@capgo/inappbrowser 8.0.0 → 8.0.2

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 (50) hide show
  1. package/CapgoInappbrowser.podspec +2 -2
  2. package/LICENSE +373 -21
  3. package/Package.swift +28 -0
  4. package/README.md +600 -74
  5. package/android/build.gradle +17 -16
  6. package/android/src/main/AndroidManifest.xml +14 -2
  7. package/android/src/main/java/ee/forgr/capacitor_inappbrowser/InAppBrowserPlugin.java +952 -204
  8. package/android/src/main/java/ee/forgr/capacitor_inappbrowser/Options.java +478 -81
  9. package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewCallbacks.java +10 -4
  10. package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewDialog.java +3021 -226
  11. package/android/src/main/res/drawable/ic_refresh.xml +9 -0
  12. package/android/src/main/res/drawable/ic_share.xml +10 -0
  13. package/android/src/main/res/layout/activity_browser.xml +10 -0
  14. package/android/src/main/res/layout/content_browser.xml +3 -2
  15. package/android/src/main/res/layout/tool_bar.xml +44 -7
  16. package/android/src/main/res/values/strings.xml +4 -0
  17. package/android/src/main/res/values/themes.xml +27 -0
  18. package/android/src/main/res/xml/file_paths.xml +14 -0
  19. package/dist/docs.json +1289 -149
  20. package/dist/esm/definitions.d.ts +614 -25
  21. package/dist/esm/definitions.js +17 -1
  22. package/dist/esm/definitions.js.map +1 -1
  23. package/dist/esm/index.d.ts +2 -2
  24. package/dist/esm/index.js +4 -4
  25. package/dist/esm/index.js.map +1 -1
  26. package/dist/esm/web.d.ts +16 -3
  27. package/dist/esm/web.js +43 -7
  28. package/dist/esm/web.js.map +1 -1
  29. package/dist/plugin.cjs.js +60 -8
  30. package/dist/plugin.cjs.js.map +1 -1
  31. package/dist/plugin.js +60 -8
  32. package/dist/plugin.js.map +1 -1
  33. package/ios/{Plugin → Sources/InAppBrowserPlugin}/Enums.swift +5 -5
  34. package/ios/Sources/InAppBrowserPlugin/InAppBrowserPlugin.swift +954 -0
  35. package/ios/Sources/InAppBrowserPlugin/WKWebViewController.swift +2003 -0
  36. package/package.json +32 -30
  37. package/ios/Plugin/Assets.xcassets/Back.imageset/Back.png +0 -0
  38. package/ios/Plugin/Assets.xcassets/Back.imageset/Back@2x.png +0 -0
  39. package/ios/Plugin/Assets.xcassets/Back.imageset/Back@3x.png +0 -0
  40. package/ios/Plugin/Assets.xcassets/Back.imageset/Contents.json +0 -26
  41. package/ios/Plugin/Assets.xcassets/Contents.json +0 -6
  42. package/ios/Plugin/Assets.xcassets/Forward.imageset/Contents.json +0 -26
  43. package/ios/Plugin/Assets.xcassets/Forward.imageset/Forward.png +0 -0
  44. package/ios/Plugin/Assets.xcassets/Forward.imageset/Forward@2x.png +0 -0
  45. package/ios/Plugin/Assets.xcassets/Forward.imageset/Forward@3x.png +0 -0
  46. package/ios/Plugin/InAppBrowserPlugin.h +0 -10
  47. package/ios/Plugin/InAppBrowserPlugin.m +0 -17
  48. package/ios/Plugin/InAppBrowserPlugin.swift +0 -203
  49. package/ios/Plugin/Info.plist +0 -24
  50. package/ios/Plugin/WKWebViewController.swift +0 -784
@@ -1,5 +1,7 @@
1
1
  package ee.forgr.capacitor_inappbrowser;
2
2
 
3
+ import android.Manifest;
4
+ import android.app.Activity;
3
5
  import android.content.ComponentName;
4
6
  import android.content.Intent;
5
7
  import android.content.pm.PackageManager;
@@ -8,235 +10,981 @@ import android.net.Uri;
8
10
  import android.os.Bundle;
9
11
  import android.text.TextUtils;
10
12
  import android.util.Log;
11
- import android.webkit.WebStorage;
13
+ import android.webkit.CookieManager;
14
+ import android.webkit.PermissionRequest;
15
+ import androidx.activity.result.ActivityResult;
16
+ import androidx.activity.result.ActivityResultLauncher;
17
+ import androidx.activity.result.contract.ActivityResultContracts;
18
+ import androidx.annotation.NonNull;
12
19
  import androidx.browser.customtabs.CustomTabsCallback;
13
20
  import androidx.browser.customtabs.CustomTabsClient;
14
21
  import androidx.browser.customtabs.CustomTabsIntent;
15
22
  import androidx.browser.customtabs.CustomTabsServiceConnection;
16
23
  import androidx.browser.customtabs.CustomTabsSession;
24
+ import com.getcapacitor.JSArray;
17
25
  import com.getcapacitor.JSObject;
26
+ import com.getcapacitor.PermissionState;
18
27
  import com.getcapacitor.Plugin;
19
28
  import com.getcapacitor.PluginCall;
20
29
  import com.getcapacitor.PluginMethod;
21
30
  import com.getcapacitor.annotation.CapacitorPlugin;
31
+ import com.getcapacitor.annotation.Permission;
32
+ import com.getcapacitor.annotation.PermissionCallback;
33
+ import java.lang.reflect.Field;
34
+ import java.util.ArrayList;
22
35
  import java.util.Iterator;
36
+ import java.util.List;
37
+ import java.util.regex.Pattern;
38
+ import java.util.regex.PatternSyntaxException;
39
+ import org.json.JSONException;
40
+ import org.json.JSONObject;
23
41
 
24
- @CapacitorPlugin(name = "InAppBrowser")
25
- public class InAppBrowserPlugin extends Plugin {
42
+ @CapacitorPlugin(
43
+ name = "InAppBrowser",
44
+ permissions = {
45
+ @Permission(alias = "camera", strings = { Manifest.permission.CAMERA }),
46
+ @Permission(alias = "microphone", strings = { Manifest.permission.RECORD_AUDIO }),
47
+ @Permission(alias = "storage", strings = { Manifest.permission.READ_EXTERNAL_STORAGE })
48
+ },
49
+ requestCodes = { WebViewDialog.FILE_CHOOSER_REQUEST_CODE }
50
+ )
51
+ public class InAppBrowserPlugin extends Plugin implements WebViewDialog.PermissionHandler {
26
52
 
27
- public static final String CUSTOM_TAB_PACKAGE_NAME = "com.android.chrome"; // Change when in stable
28
- private CustomTabsClient customTabsClient;
29
- private CustomTabsSession currentSession;
30
- private WebViewDialog webViewDialog = null;
53
+ private final String pluginVersion = "8.0.2";
54
+
55
+ public static final String CUSTOM_TAB_PACKAGE_NAME = "com.android.chrome"; // Change when in stable
56
+ private CustomTabsClient customTabsClient;
57
+ private CustomTabsSession currentSession;
58
+ private WebViewDialog webViewDialog = null;
59
+ private String currentUrl = "";
60
+
61
+ private PermissionRequest currentPermissionRequest;
62
+
63
+ private ActivityResultLauncher<Intent> fileChooserLauncher;
31
64
 
32
- CustomTabsServiceConnection connection = new CustomTabsServiceConnection() {
33
65
  @Override
34
- public void onCustomTabsServiceConnected(
35
- ComponentName name,
36
- CustomTabsClient client
37
- ) {
38
- customTabsClient = client;
39
- client.warmup(0);
66
+ public void load() {
67
+ super.load();
68
+ fileChooserLauncher = getActivity().registerForActivityResult(
69
+ new ActivityResultContracts.StartActivityForResult(),
70
+ this::handleFileChooserResult
71
+ );
40
72
  }
41
73
 
42
- @Override
43
- public void onServiceDisconnected(ComponentName name) {}
44
- };
45
-
46
- @PluginMethod
47
- public void setUrl(PluginCall call) {
48
- String url = call.getString("url");
49
- if (url == null || TextUtils.isEmpty(url)) {
50
- call.reject("Invalid URL");
51
- }
52
- this.getActivity()
53
- .runOnUiThread(
54
- new Runnable() {
55
- @Override
56
- public void run() {
57
- webViewDialog.setUrl(url);
58
- }
59
- }
60
- );
61
- call.resolve();
62
- }
63
-
64
- @PluginMethod
65
- public void open(PluginCall call) {
66
- String url = call.getString("url");
67
-
68
- // get the deeplink prevention, if provided
69
- Boolean preventDeeplink = call.getBoolean("preventDeeplink", null);
70
-
71
- if (url == null || TextUtils.isEmpty(url)) {
72
- call.reject("Invalid URL");
73
- }
74
- CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(
75
- getCustomTabsSession()
76
- );
77
- CustomTabsIntent tabsIntent = builder.build();
78
- tabsIntent.intent.putExtra(
79
- Intent.EXTRA_REFERRER,
80
- Uri.parse(
81
- Intent.URI_ANDROID_APP_SCHEME + "//" + getContext().getPackageName()
82
- )
83
- );
84
- tabsIntent.intent.putExtra(
85
- android.provider.Browser.EXTRA_HEADERS,
86
- this.getHeaders(call)
87
- );
88
-
89
- if (preventDeeplink != null) {
90
- String browserPackageName = "";
91
- Intent browserIntent = new Intent(
92
- Intent.ACTION_VIEW,
93
- Uri.parse("http://")
94
- );
95
- ResolveInfo resolveInfo = getContext()
96
- .getPackageManager()
97
- .resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
98
-
99
- if (resolveInfo != null) {
100
- browserPackageName = resolveInfo.activityInfo.packageName;
101
-
102
- if (!browserPackageName.isEmpty()) {
103
- tabsIntent.intent.setPackage(browserPackageName);
104
- }
105
- }
106
- }
107
-
108
- tabsIntent.launchUrl(getContext(), Uri.parse(url));
109
-
110
- call.resolve();
111
- }
112
-
113
- @PluginMethod
114
- public void clearCookies(PluginCall call) {
115
- WebStorage.getInstance().deleteAllData();
116
- call.resolve();
117
- }
118
-
119
- @PluginMethod
120
- public void openWebView(PluginCall call) {
121
- String url = call.getString("url");
122
- if (url == null || TextUtils.isEmpty(url)) {
123
- call.reject("Invalid URL");
124
- }
125
- final Options options = new Options();
126
- options.setUrl(url);
127
- options.setHeaders(call.getObject("headers"));
128
- options.setTitle(call.getString("title", "New Window"));
129
- options.setShareDisclaimer(call.getObject("shareDisclaimer", null));
130
- options.setShareSubject(call.getString("shareSubject", null));
131
- options.setToolbarType(call.getString("toolbarType", ""));
132
- options.setPresentAfterPageLoad(
133
- call.getBoolean("isPresentAfterPageLoad", false)
134
- );
135
- options.setPluginCall(call);
136
- options.setCallbacks(
137
- new WebViewCallbacks() {
138
- @Override
139
- public void urlChangeEvent(String url) {
140
- notifyListeners("urlChangeEvent", new JSObject().put("url", url));
74
+ private void handleFileChooserResult(ActivityResult result) {
75
+ if (webViewDialog != null && webViewDialog.mFilePathCallback != null) {
76
+ Uri[] results = null;
77
+ Intent data = result.getData();
78
+
79
+ if (result.getResultCode() == Activity.RESULT_OK) {
80
+ // Handle camera capture result
81
+ if (webViewDialog.tempCameraUri != null && (data == null || data.getData() == null)) {
82
+ results = new Uri[] { webViewDialog.tempCameraUri };
83
+ }
84
+ // Handle regular file picker result
85
+ else if (data != null) {
86
+ if (data.getClipData() != null) {
87
+ // Handle multiple files
88
+ int count = data.getClipData().getItemCount();
89
+ results = new Uri[count];
90
+ for (int i = 0; i < count; i++) {
91
+ results[i] = data.getClipData().getItemAt(i).getUri();
92
+ }
93
+ } else if (data.getData() != null) {
94
+ // Handle single file
95
+ results = new Uri[] { data.getData() };
96
+ }
97
+ }
98
+ }
99
+
100
+ // Send the result to WebView and clean up
101
+ webViewDialog.mFilePathCallback.onReceiveValue(results);
102
+ webViewDialog.mFilePathCallback = null;
103
+ webViewDialog.tempCameraUri = null;
141
104
  }
105
+ }
142
106
 
143
- @Override
144
- public void closeEvent(String url) {
145
- notifyListeners("closeEvent", new JSObject().put("url", url));
107
+ public void handleMicrophonePermissionRequest(PermissionRequest request) {
108
+ this.currentPermissionRequest = request;
109
+ if (getPermissionState("microphone") != PermissionState.GRANTED) {
110
+ requestPermissionForAlias("microphone", null, "microphonePermissionCallback");
111
+ } else {
112
+ grantMicrophonePermission();
113
+ }
114
+ }
115
+
116
+ private void grantMicrophonePermission() {
117
+ if (currentPermissionRequest != null) {
118
+ currentPermissionRequest.grant(new String[] { PermissionRequest.RESOURCE_AUDIO_CAPTURE });
119
+ currentPermissionRequest = null;
120
+ }
121
+ }
122
+
123
+ @PermissionCallback
124
+ private void microphonePermissionCallback(PluginCall call) {
125
+ if (getPermissionState("microphone") == PermissionState.GRANTED) {
126
+ grantCameraAndMicrophonePermission();
127
+ } else {
128
+ if (currentPermissionRequest != null) {
129
+ currentPermissionRequest.deny();
130
+ currentPermissionRequest = null;
131
+ }
132
+ if (call != null) {
133
+ call.reject("Microphone permission is required");
134
+ }
135
+ }
136
+ }
137
+
138
+ private void grantCameraAndMicrophonePermission() {
139
+ if (currentPermissionRequest != null) {
140
+ currentPermissionRequest.grant(
141
+ new String[] { PermissionRequest.RESOURCE_VIDEO_CAPTURE, PermissionRequest.RESOURCE_AUDIO_CAPTURE }
142
+ );
143
+ currentPermissionRequest = null;
144
+ }
145
+ }
146
+
147
+ public void handleCameraPermissionRequest(PermissionRequest request) {
148
+ this.currentPermissionRequest = request;
149
+ if (getPermissionState("camera") != PermissionState.GRANTED) {
150
+ requestPermissionForAlias("camera", null, "cameraPermissionCallback");
151
+ } else if (getPermissionState("microphone") != PermissionState.GRANTED) {
152
+ requestPermissionForAlias("microphone", null, "microphonePermissionCallback");
153
+ } else {
154
+ grantCameraAndMicrophonePermission();
155
+ }
156
+ }
157
+
158
+ @PermissionCallback
159
+ private void cameraPermissionCallback(PluginCall call) {
160
+ if (getPermissionState("camera") == PermissionState.GRANTED) {
161
+ if (getPermissionState("microphone") != PermissionState.GRANTED) {
162
+ requestPermissionForAlias("microphone", null, "microphonePermissionCallback");
163
+ } else {
164
+ grantCameraAndMicrophonePermission();
165
+ }
166
+ } else {
167
+ if (currentPermissionRequest != null) {
168
+ currentPermissionRequest.deny();
169
+ currentPermissionRequest = null;
170
+ }
171
+
172
+ // Reject only if there's a call - could be null for WebViewDialog flow
173
+ if (call != null) {
174
+ call.reject("Camera permission is required");
175
+ }
176
+ }
177
+ }
178
+
179
+ @PermissionCallback
180
+ private void cameraPermissionCallback() {
181
+ if (getPermissionState("camera") == PermissionState.GRANTED) {
182
+ grantCameraPermission();
183
+ } else {
184
+ if (currentPermissionRequest != null) {
185
+ currentPermissionRequest.deny();
186
+ currentPermissionRequest = null;
187
+ }
146
188
  }
189
+ }
147
190
 
191
+ private void grantCameraPermission() {
192
+ if (currentPermissionRequest != null) {
193
+ currentPermissionRequest.grant(new String[] { PermissionRequest.RESOURCE_VIDEO_CAPTURE });
194
+ currentPermissionRequest = null;
195
+ }
196
+ }
197
+
198
+ CustomTabsServiceConnection connection = new CustomTabsServiceConnection() {
148
199
  @Override
149
- public void pageLoaded() {
150
- notifyListeners("browserPageLoaded", new JSObject());
200
+ public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) {
201
+ customTabsClient = client;
151
202
  }
152
203
 
153
204
  @Override
154
- public void pageLoadError() {
155
- notifyListeners("pageLoadError", new JSObject());
156
- }
157
- }
158
- );
159
- getActivity()
160
- .runOnUiThread(
161
- new Runnable() {
162
- @Override
163
- public void run() {
164
- webViewDialog =
165
- new WebViewDialog(
166
- getContext(),
167
- android.R.style.Theme_NoTitleBar,
168
- options
169
- );
170
- webViewDialog.presentWebView();
171
- }
172
- }
173
- );
174
- }
175
-
176
- @PluginMethod
177
- public void close(PluginCall call) {
178
- if (webViewDialog != null) {
179
- webViewDialog.dismiss();
180
- webViewDialog = null;
181
- } else {
182
- Intent intent = new Intent(
183
- getContext(),
184
- getBridge().getActivity().getClass()
185
- );
186
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
187
- getContext().startActivity(intent);
188
- }
189
- call.resolve();
190
- }
191
-
192
- private Bundle getHeaders(PluginCall pluginCall) {
193
- JSObject headersProvided = pluginCall.getObject("headers");
194
- Bundle headers = new Bundle();
195
- if (headersProvided != null) {
196
- Iterator<String> keys = headersProvided.keys();
197
- while (keys.hasNext()) {
198
- String key = keys.next();
199
- headers.putString(key, headersProvided.getString(key));
200
- }
201
- }
202
- return headers;
203
- }
204
-
205
- protected void handleOnResume() {
206
- boolean ok = CustomTabsClient.bindCustomTabsService(
207
- getContext(),
208
- CUSTOM_TAB_PACKAGE_NAME,
209
- connection
210
- );
211
- if (!ok) {
212
- Log.e(getLogTag(), "Error binding to custom tabs service");
213
- }
214
- }
215
-
216
- protected void handleOnPause() {
217
- getContext().unbindService(connection);
218
- }
219
-
220
- public CustomTabsSession getCustomTabsSession() {
221
- if (customTabsClient == null) {
222
- return null;
223
- }
224
-
225
- if (currentSession == null) {
226
- currentSession =
227
- customTabsClient.newSession(
228
- new CustomTabsCallback() {
229
- @Override
230
- public void onNavigationEvent(int navigationEvent, Bundle extras) {
231
- switch (navigationEvent) {
232
- case NAVIGATION_FINISHED:
233
- notifyListeners("browserPageLoaded", new JSObject());
234
- break;
235
- }
236
- }
237
- }
205
+ public void onServiceDisconnected(ComponentName name) {
206
+ customTabsClient = null;
207
+ }
208
+ };
209
+
210
+ @PluginMethod
211
+ public void requestCameraPermission(PluginCall call) {
212
+ if (getPermissionState("camera") != PermissionState.GRANTED) {
213
+ requestPermissionForAlias("camera", call, "cameraPermissionCallback");
214
+ } else {
215
+ call.resolve();
216
+ }
217
+ }
218
+
219
+ @PluginMethod
220
+ public void setUrl(PluginCall call) {
221
+ String url = call.getString("url");
222
+ if (url == null || TextUtils.isEmpty(url)) {
223
+ call.reject("Invalid URL");
224
+ return;
225
+ }
226
+
227
+ if (webViewDialog == null) {
228
+ call.reject("WebView is not initialized");
229
+ return;
230
+ }
231
+
232
+ currentUrl = url;
233
+ this.getActivity().runOnUiThread(
234
+ new Runnable() {
235
+ @Override
236
+ public void run() {
237
+ try {
238
+ if (webViewDialog != null) {
239
+ webViewDialog.setUrl(url);
240
+ call.resolve();
241
+ } else {
242
+ call.reject("WebView is not initialized");
243
+ }
244
+ } catch (Exception e) {
245
+ Log.e("InAppBrowser", "Error setting URL: " + e.getMessage());
246
+ call.reject("Failed to set URL: " + e.getMessage());
247
+ }
248
+ }
249
+ }
250
+ );
251
+ }
252
+
253
+ @PluginMethod
254
+ public void open(PluginCall call) {
255
+ String url = call.getString("url");
256
+ if (url == null) {
257
+ call.reject("URL is required");
258
+ return;
259
+ }
260
+
261
+ // get the deeplink prevention, if provided
262
+ Boolean preventDeeplink = call.getBoolean("preventDeeplink", false);
263
+ Boolean isPresentAfterPageLoad = call.getBoolean("isPresentAfterPageLoad", false);
264
+
265
+ if (url == null || TextUtils.isEmpty(url)) {
266
+ call.reject("Invalid URL");
267
+ }
268
+ currentUrl = url;
269
+ CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(getCustomTabsSession());
270
+ CustomTabsIntent tabsIntent = builder.build();
271
+ tabsIntent.intent.putExtra(Intent.EXTRA_REFERRER, Uri.parse(Intent.URI_ANDROID_APP_SCHEME + "//" + getContext().getPackageName()));
272
+ tabsIntent.intent.putExtra(android.provider.Browser.EXTRA_HEADERS, this.getHeaders(call));
273
+
274
+ if (preventDeeplink != false) {
275
+ String browserPackageName = "";
276
+ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://"));
277
+ ResolveInfo resolveInfo = getContext().getPackageManager().resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
278
+
279
+ if (resolveInfo != null) {
280
+ browserPackageName = resolveInfo.activityInfo.packageName;
281
+
282
+ if (!browserPackageName.isEmpty()) {
283
+ tabsIntent.intent.setPackage(browserPackageName);
284
+ }
285
+ }
286
+ }
287
+
288
+ if (isPresentAfterPageLoad) {
289
+ tabsIntent.intent.putExtra("isPresentAfterPageLoad", true);
290
+ }
291
+
292
+ tabsIntent.launchUrl(getContext(), Uri.parse(url));
293
+
294
+ call.resolve();
295
+ }
296
+
297
+ @PluginMethod
298
+ public void clearCache(PluginCall call) {
299
+ CookieManager cookieManager = CookieManager.getInstance();
300
+ cookieManager.removeAllCookies(null);
301
+ cookieManager.flush();
302
+ call.resolve();
303
+ }
304
+
305
+ @PluginMethod
306
+ public void clearAllCookies(PluginCall call) {
307
+ CookieManager cookieManager = CookieManager.getInstance();
308
+ cookieManager.removeAllCookies(null);
309
+ cookieManager.flush();
310
+ call.resolve();
311
+ }
312
+
313
+ @PluginMethod
314
+ public void clearCookies(PluginCall call) {
315
+ String url = call.getString("url", currentUrl);
316
+ if (url == null || TextUtils.isEmpty(url)) {
317
+ call.reject("Invalid URL");
318
+ return;
319
+ }
320
+
321
+ Uri uri = Uri.parse(url);
322
+ String host = uri.getHost();
323
+ if (host == null || TextUtils.isEmpty(host)) {
324
+ call.reject("Invalid URL (Host is null)");
325
+ return;
326
+ }
327
+
328
+ CookieManager cookieManager = CookieManager.getInstance();
329
+ String cookieString = cookieManager.getCookie(url);
330
+ ArrayList<String> cookiesToRemove = new ArrayList<>();
331
+
332
+ if (cookieString != null) {
333
+ String[] cookies = cookieString.split("; ");
334
+
335
+ String domain = uri.getHost();
336
+
337
+ for (String cookie : cookies) {
338
+ String[] parts = cookie.split("=");
339
+ if (parts.length > 0) {
340
+ cookiesToRemove.add(parts[0].trim());
341
+ CookieManager.getInstance().setCookie(url, String.format("%s=del;", parts[0].trim()));
342
+ }
343
+ }
344
+ }
345
+
346
+ StringBuilder scriptToRun = new StringBuilder();
347
+ for (String cookieToRemove : cookiesToRemove) {
348
+ scriptToRun.append(
349
+ String.format("window.cookieStore.delete('%s', {name: '%s', domain: '%s'});", cookieToRemove, cookieToRemove, url)
350
+ );
351
+ }
352
+
353
+ Log.i("DelCookies", String.format("Script to run:\n%s", scriptToRun));
354
+
355
+ this.getActivity().runOnUiThread(
356
+ new Runnable() {
357
+ @Override
358
+ public void run() {
359
+ try {
360
+ if (webViewDialog != null) {
361
+ webViewDialog.executeScript(scriptToRun.toString());
362
+ call.resolve();
363
+ } else {
364
+ call.reject("WebView is not initialized");
365
+ }
366
+ } catch (Exception e) {
367
+ Log.e("InAppBrowser", "Error clearing cookies: " + e.getMessage());
368
+ call.reject("Failed to clear cookies: " + e.getMessage());
369
+ }
370
+ }
371
+ }
372
+ );
373
+ }
374
+
375
+ @PluginMethod
376
+ public void getCookies(PluginCall call) {
377
+ String url = call.getString("url");
378
+ if (url == null || TextUtils.isEmpty(url)) {
379
+ call.reject("Invalid URL");
380
+ return;
381
+ }
382
+ CookieManager cookieManager = CookieManager.getInstance();
383
+ String cookieString = cookieManager.getCookie(url);
384
+ JSObject result = new JSObject();
385
+ if (cookieString != null) {
386
+ String[] cookiePairs = cookieString.split("; ");
387
+ for (String cookie : cookiePairs) {
388
+ String[] parts = cookie.split("=", 2);
389
+ if (parts.length == 2) {
390
+ result.put(parts[0], parts[1]);
391
+ }
392
+ }
393
+ }
394
+ call.resolve(result);
395
+ }
396
+
397
+ @PluginMethod
398
+ public void openWebView(PluginCall call) {
399
+ String url = call.getString("url");
400
+ if (url == null || TextUtils.isEmpty(url)) {
401
+ call.reject("Invalid URL");
402
+ }
403
+ currentUrl = url;
404
+ final Options options = new Options();
405
+ options.setUrl(url);
406
+ options.setHeaders(call.getObject("headers"));
407
+ options.setCredentials(call.getObject("credentials"));
408
+ options.setShowReloadButton(Boolean.TRUE.equals(call.getBoolean("showReloadButton", false)));
409
+ options.setVisibleTitle(Boolean.TRUE.equals(call.getBoolean("visibleTitle", true)));
410
+ if (Boolean.TRUE.equals(options.getVisibleTitle())) {
411
+ options.setTitle(call.getString("title", "New Window"));
412
+ } else {
413
+ options.setTitle(call.getString("title", ""));
414
+ }
415
+ options.setToolbarColor(call.getString("toolbarColor", "#ffffff"));
416
+ options.setBackgroundColor(call.getString("backgroundColor", "white"));
417
+ options.setToolbarTextColor(call.getString("toolbarTextColor"));
418
+ options.setArrow(Boolean.TRUE.equals(call.getBoolean("showArrow", false)));
419
+ options.setIgnoreUntrustedSSLError(Boolean.TRUE.equals(call.getBoolean("ignoreUntrustedSSLError", false)));
420
+
421
+ // Set text zoom if specified in options (default is 100)
422
+ Integer textZoom = call.getInt("textZoom");
423
+ if (textZoom != null) {
424
+ options.setTextZoom(textZoom);
425
+ }
426
+
427
+ String proxyRequestsStr = call.getString("proxyRequests");
428
+ if (proxyRequestsStr != null) {
429
+ try {
430
+ options.setProxyRequestsPattern(Pattern.compile(proxyRequestsStr));
431
+ } catch (PatternSyntaxException e) {
432
+ Log.e("WebViewDialog", String.format("Pattern '%s' is not a valid pattern", proxyRequestsStr));
433
+ }
434
+ }
435
+
436
+ try {
437
+ // Try to set buttonNearDone if present, with better error handling
438
+ JSObject buttonNearDoneObj = call.getObject("buttonNearDone");
439
+ if (buttonNearDoneObj != null) {
440
+ try {
441
+ // Provide better debugging for buttonNearDone
442
+ JSObject androidObj = buttonNearDoneObj.getJSObject("android");
443
+ if (androidObj != null) {
444
+ String iconType = androidObj.getString("iconType", "asset");
445
+ String icon = androidObj.getString("icon", "");
446
+ Log.d("InAppBrowser", "ButtonNearDone config - iconType: " + iconType + ", icon: " + icon);
447
+
448
+ // For vector type, verify if resource exists
449
+ if ("vector".equals(iconType)) {
450
+ int resourceId = getContext().getResources().getIdentifier(icon, "drawable", getContext().getPackageName());
451
+ if (resourceId == 0) {
452
+ Log.e("InAppBrowser", "Vector resource not found: " + icon);
453
+ // List available drawable resources to help debugging
454
+ try {
455
+ final StringBuilder availableResources = getStringBuilder();
456
+ Log.d("InAppBrowser", availableResources.toString());
457
+ } catch (Exception e) {
458
+ Log.e("InAppBrowser", "Error listing resources: " + e.getMessage());
459
+ }
460
+ } else {
461
+ Log.d("InAppBrowser", "Vector resource found with ID: " + resourceId);
462
+ }
463
+ }
464
+ }
465
+
466
+ // Try to create the ButtonNearDone object
467
+ Options.ButtonNearDone buttonNearDone = Options.ButtonNearDone.generateFromPluginCall(call, getContext().getAssets());
468
+ options.setButtonNearDone(buttonNearDone);
469
+ } catch (Exception e) {
470
+ Log.e("InAppBrowser", "Error setting buttonNearDone: " + e.getMessage(), e);
471
+ }
472
+ }
473
+ } catch (Exception e) {
474
+ Log.e("InAppBrowser", "Error processing buttonNearDone: " + e.getMessage(), e);
475
+ }
476
+
477
+ options.setShareDisclaimer(call.getObject("shareDisclaimer", null));
478
+ options.setPreShowScript(call.getString("preShowScript", null));
479
+ options.setShareSubject(call.getString("shareSubject", null));
480
+ options.setToolbarType(call.getString("toolbarType", ""));
481
+ options.setPreventDeeplink(Boolean.TRUE.equals(call.getBoolean("preventDeeplink", false)));
482
+
483
+ // Validate preShowScript requires isPresentAfterPageLoad
484
+ if (call.getData().has("preShowScript") && !Boolean.TRUE.equals(call.getBoolean("isPresentAfterPageLoad", false))) {
485
+ call.reject("preShowScript requires isPresentAfterPageLoad to be true");
486
+ return;
487
+ }
488
+
489
+ // Validate closeModal options
490
+ if (Boolean.TRUE.equals(call.getBoolean("closeModal", false))) {
491
+ options.setCloseModal(true);
492
+ options.setCloseModalTitle(call.getString("closeModalTitle", "Close"));
493
+ options.setCloseModalDescription(call.getString("closeModalDescription", "Are you sure ?"));
494
+ options.setCloseModalOk(call.getString("closeModalOk", "Ok"));
495
+ options.setCloseModalCancel(call.getString("closeModalCancel", "Cancel"));
496
+ } else {
497
+ // Reject if closeModal is false but closeModal options are provided
498
+ if (
499
+ call.getData().has("closeModalTitle") ||
500
+ call.getData().has("closeModalDescription") ||
501
+ call.getData().has("closeModalOk") ||
502
+ call.getData().has("closeModalCancel")
503
+ ) {
504
+ call.reject("closeModal options require closeModal to be true");
505
+ return;
506
+ }
507
+ options.setCloseModal(false);
508
+ }
509
+
510
+ // Validate shareDisclaimer requires shareSubject
511
+ if (call.getData().has("shareDisclaimer") && !call.getData().has("shareSubject")) {
512
+ call.reject("shareDisclaimer requires shareSubject to be provided");
513
+ return;
514
+ }
515
+
516
+ // Validate buttonNearDone compatibility with toolbar type
517
+ if (call.getData().has("buttonNearDone")) {
518
+ String toolbarType = options.getToolbarType();
519
+ if (
520
+ TextUtils.equals(toolbarType, "activity") ||
521
+ TextUtils.equals(toolbarType, "navigation") ||
522
+ TextUtils.equals(toolbarType, "blank")
523
+ ) {
524
+ call.reject("buttonNearDone is not compatible with toolbarType: " + toolbarType);
525
+ return;
526
+ }
527
+ }
528
+
529
+ options.setActiveNativeNavigationForWebview(Boolean.TRUE.equals(call.getBoolean("activeNativeNavigationForWebview", false)));
530
+ options.setDisableGoBackOnNativeApplication(Boolean.TRUE.equals(call.getBoolean("disableGoBackOnNativeApplication", false)));
531
+ options.setPresentAfterPageLoad(Boolean.TRUE.equals(call.getBoolean("isPresentAfterPageLoad", false)));
532
+ options.setPluginCall(call);
533
+
534
+ // Set Material Design picker option
535
+ options.setMaterialPicker(Boolean.TRUE.equals(call.getBoolean("materialPicker", false)));
536
+
537
+ // Set enabledSafeBottomMargin option
538
+ options.setEnabledSafeMargin(Boolean.TRUE.equals(call.getBoolean("enabledSafeBottomMargin", false)));
539
+
540
+ // Use system top inset for WebView margin when explicitly enabled
541
+ options.setUseTopInset(Boolean.TRUE.equals(call.getBoolean("useTopInset", false)));
542
+
543
+ // options.getToolbarItemTypes().add(ToolbarItemType.RELOAD); TODO: fix this
544
+ options.setCallbacks(
545
+ new WebViewCallbacks() {
546
+ @Override
547
+ public void urlChangeEvent(String url) {
548
+ notifyListeners("urlChangeEvent", new JSObject().put("url", url));
549
+ }
550
+
551
+ @Override
552
+ public void closeEvent(String url) {
553
+ notifyListeners("closeEvent", new JSObject().put("url", url));
554
+ }
555
+
556
+ @Override
557
+ public void pageLoaded() {
558
+ notifyListeners("browserPageLoaded", new JSObject());
559
+ }
560
+
561
+ @Override
562
+ public void pageLoadError() {
563
+ notifyListeners("pageLoadError", new JSObject());
564
+ }
565
+
566
+ @Override
567
+ public void buttonNearDoneClicked() {
568
+ notifyListeners("buttonNearDoneClick", new JSObject());
569
+ }
570
+
571
+ @Override
572
+ public void confirmBtnClicked(String url) {
573
+ notifyListeners("confirmBtnClicked", new JSObject().put("url", url));
574
+ }
575
+
576
+ @Override
577
+ public void javascriptCallback(String message) {
578
+ // Handle the message received from JavaScript
579
+ Log.d("WebViewDialog", "Received message from JavaScript: " + message);
580
+ // Process the message as needed
581
+ try {
582
+ // Parse the received message as a JSON object
583
+ JSONObject jsonMessage = new JSONObject(message);
584
+
585
+ // Create a new JSObject to send to the Capacitor plugin
586
+ JSObject jsObject = new JSObject();
587
+
588
+ // Iterate through the keys in the JSON object and add them to the JSObject
589
+ Iterator<String> keys = jsonMessage.keys();
590
+ while (keys.hasNext()) {
591
+ String key = keys.next();
592
+ jsObject.put(key, jsonMessage.get(key));
593
+ }
594
+
595
+ // Notify listeners with the parsed message
596
+ notifyListeners("messageFromWebview", jsObject);
597
+ } catch (JSONException e) {
598
+ Log.e("WebViewDialog", "Error parsing JSON message: " + e.getMessage());
599
+
600
+ // If JSON parsing fails, send the raw message as a string
601
+ JSObject jsObject = new JSObject();
602
+ jsObject.put("rawMessage", message);
603
+ notifyListeners("messageFromWebview", jsObject);
604
+ }
605
+ }
606
+ }
607
+ );
608
+
609
+ JSArray jsAuthorizedLinks = call.getArray("authorizedAppLinks");
610
+ if (jsAuthorizedLinks != null && jsAuthorizedLinks.length() > 0) {
611
+ List<String> authorizedLinks = new ArrayList<>();
612
+ for (int i = 0; i < jsAuthorizedLinks.length(); i++) {
613
+ try {
614
+ String link = jsAuthorizedLinks.getString(i);
615
+ if (link != null && !link.trim().isEmpty()) {
616
+ authorizedLinks.add(link);
617
+ }
618
+ } catch (Exception e) {
619
+ Log.w("InAppBrowserPlugin", "Error reading authorized app link at index " + i, e);
620
+ }
621
+ }
622
+ Log.d("InAppBrowserPlugin", "Parsed authorized app links: " + authorizedLinks);
623
+ options.setAuthorizedAppLinks(authorizedLinks);
624
+ } else {
625
+ Log.d("InAppBrowserPlugin", "No authorized app links provided.");
626
+ }
627
+
628
+ JSArray blockedHostsRaw = call.getArray("blockedHosts");
629
+ if (blockedHostsRaw != null && blockedHostsRaw.length() > 0) {
630
+ List<String> blockedHosts = new ArrayList<>();
631
+ for (int i = 0; i < blockedHostsRaw.length(); i++) {
632
+ try {
633
+ String host = blockedHostsRaw.getString(i);
634
+ if (host != null && !host.trim().isEmpty()) {
635
+ blockedHosts.add(host);
636
+ }
637
+ } catch (Exception e) {
638
+ Log.w("InAppBrowserPlugin", "Error reading blocked host at index " + i, e);
639
+ }
640
+ }
641
+ Log.d("InAppBrowserPlugin", "Parsed blocked hosts: " + blockedHosts);
642
+ options.setBlockedHosts(blockedHosts);
643
+ } else {
644
+ Log.d("InAppBrowserPlugin", "No blocked hosts provided.");
645
+ }
646
+
647
+ // Set Google Pay support option
648
+ options.setEnableGooglePaySupport(Boolean.TRUE.equals(call.getBoolean("enableGooglePaySupport", false)));
649
+
650
+ // Set dimensions if provided
651
+ Integer width = call.getInt("width");
652
+ Integer height = call.getInt("height");
653
+ Integer x = call.getInt("x");
654
+ Integer y = call.getInt("y");
655
+
656
+ // Validate dimension parameters
657
+ if (width != null && height == null) {
658
+ call.reject("Height must be specified when width is provided");
659
+ return;
660
+ }
661
+
662
+ if (width != null) {
663
+ options.setWidth(width);
664
+ }
665
+ if (height != null) {
666
+ options.setHeight(height);
667
+ }
668
+ if (x != null) {
669
+ options.setX(x);
670
+ }
671
+ if (y != null) {
672
+ options.setY(y);
673
+ }
674
+
675
+ this.getActivity().runOnUiThread(
676
+ new Runnable() {
677
+ @Override
678
+ public void run() {
679
+ webViewDialog = new WebViewDialog(
680
+ getContext(),
681
+ android.R.style.Theme_NoTitleBar,
682
+ options,
683
+ InAppBrowserPlugin.this,
684
+ getBridge().getWebView()
685
+ );
686
+ webViewDialog.activity = InAppBrowserPlugin.this.getActivity();
687
+ webViewDialog.presentWebView();
688
+ call.resolve();
689
+ }
690
+ }
691
+ );
692
+ }
693
+
694
+ @NonNull
695
+ private static StringBuilder getStringBuilder() {
696
+ Field[] drawables = R.drawable.class.getFields();
697
+ StringBuilder availableResources = new StringBuilder("Available resources: ");
698
+ for (int i = 0; i < Math.min(10, drawables.length); i++) {
699
+ availableResources.append(drawables[i].getName()).append(", ");
700
+ }
701
+ if (drawables.length > 10) {
702
+ availableResources.append("... (").append(drawables.length - 10).append(" more)");
703
+ }
704
+ return availableResources;
705
+ }
706
+
707
+ @PluginMethod
708
+ public void postMessage(PluginCall call) {
709
+ if (webViewDialog == null) {
710
+ call.reject("WebView is not initialized");
711
+ return;
712
+ }
713
+ JSObject eventData = call.getObject("detail");
714
+ // Log event data
715
+ if (eventData == null) {
716
+ call.reject("No event data provided");
717
+ return;
718
+ }
719
+
720
+ Log.d("InAppBrowserPlugin", "Event data: " + eventData.toString());
721
+ this.getActivity().runOnUiThread(
722
+ new Runnable() {
723
+ @Override
724
+ public void run() {
725
+ if (webViewDialog != null) {
726
+ webViewDialog.postMessageToJS(eventData);
727
+ call.resolve();
728
+ } else {
729
+ call.reject("WebView is not initialized");
730
+ }
731
+ }
732
+ }
733
+ );
734
+ }
735
+
736
+ @PluginMethod
737
+ public void executeScript(PluginCall call) {
738
+ String script = call.getString("code");
739
+ if (script == null || script.trim().isEmpty()) {
740
+ call.reject("Script is required");
741
+ return;
742
+ }
743
+
744
+ if (webViewDialog == null) {
745
+ call.reject("WebView is not initialized");
746
+ return;
747
+ }
748
+
749
+ this.getActivity().runOnUiThread(
750
+ new Runnable() {
751
+ @Override
752
+ public void run() {
753
+ try {
754
+ if (webViewDialog != null) {
755
+ webViewDialog.executeScript(script);
756
+ call.resolve();
757
+ } else {
758
+ call.reject("WebView is not initialized");
759
+ }
760
+ } catch (Exception e) {
761
+ Log.e("InAppBrowser", "Error executing script: " + e.getMessage());
762
+ call.reject("Failed to execute script: " + e.getMessage());
763
+ }
764
+ }
765
+ }
766
+ );
767
+ }
768
+
769
+ @PluginMethod
770
+ public void goBack(PluginCall call) {
771
+ this.getActivity().runOnUiThread(
772
+ new Runnable() {
773
+ @Override
774
+ public void run() {
775
+ if (webViewDialog != null) {
776
+ boolean canGoBack = webViewDialog.goBack();
777
+ JSObject result = new JSObject();
778
+ result.put("canGoBack", canGoBack);
779
+ call.resolve(result);
780
+ } else {
781
+ JSObject result = new JSObject();
782
+ result.put("canGoBack", false);
783
+ call.resolve(result);
784
+ }
785
+ }
786
+ }
787
+ );
788
+ }
789
+
790
+ @PluginMethod
791
+ public void reload(PluginCall call) {
792
+ this.getActivity().runOnUiThread(
793
+ new Runnable() {
794
+ @Override
795
+ public void run() {
796
+ if (webViewDialog != null) {
797
+ webViewDialog.reload();
798
+ call.resolve();
799
+ } else {
800
+ call.reject("WebView is not initialized");
801
+ }
802
+ }
803
+ }
804
+ );
805
+ }
806
+
807
+ @PluginMethod
808
+ public void lsuakdchgbbaHandleProxiedRequest(PluginCall call) {
809
+ if (webViewDialog != null) {
810
+ Boolean ok = call.getBoolean("ok", false);
811
+ String id = call.getString("id");
812
+ if (id == null) {
813
+ Log.e("InAppBrowserProxy", "CRITICAL ERROR, proxy id = null");
814
+ return;
815
+ }
816
+ if (Boolean.FALSE.equals(ok)) {
817
+ String result = call.getString("result", "");
818
+ webViewDialog.handleProxyResultError(result, id);
819
+ } else {
820
+ JSONObject object = call.getObject("result");
821
+ webViewDialog.handleProxyResultOk(object, id);
822
+ }
823
+ }
824
+ call.resolve();
825
+ }
826
+
827
+ @PluginMethod
828
+ public void close(PluginCall call) {
829
+ if (webViewDialog == null) {
830
+ // Fallback: try to bring main activity to foreground
831
+ try {
832
+ Intent intent = new Intent(getContext(), getBridge().getActivity().getClass());
833
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
834
+ getContext().startActivity(intent);
835
+ call.resolve();
836
+ } catch (Exception e) {
837
+ Log.e("InAppBrowser", "Error bringing main activity to foreground: " + e.getMessage());
838
+ call.reject("WebView is not initialized and failed to restore main activity");
839
+ }
840
+ return;
841
+ }
842
+
843
+ this.getActivity().runOnUiThread(
844
+ new Runnable() {
845
+ @Override
846
+ public void run() {
847
+ try {
848
+ if (webViewDialog != null) {
849
+ String currentUrl = "";
850
+ try {
851
+ currentUrl = webViewDialog.getUrl();
852
+ if (currentUrl == null) {
853
+ currentUrl = "";
854
+ }
855
+ } catch (Exception e) {
856
+ Log.e("InAppBrowser", "Error getting URL before close: " + e.getMessage());
857
+ currentUrl = "";
858
+ }
859
+
860
+ // Notify listeners about the close event
861
+ notifyListeners("closeEvent", new JSObject().put("url", currentUrl));
862
+
863
+ webViewDialog.dismiss();
864
+ webViewDialog = null;
865
+ call.resolve();
866
+ } else {
867
+ // Secondary fallback inside UI thread
868
+ try {
869
+ Intent intent = new Intent(getContext(), getBridge().getActivity().getClass());
870
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
871
+ getContext().startActivity(intent);
872
+ call.resolve();
873
+ } catch (Exception e) {
874
+ Log.e("InAppBrowser", "Error in secondary fallback: " + e.getMessage());
875
+ call.reject("WebView is not initialized");
876
+ }
877
+ }
878
+ } catch (Exception e) {
879
+ Log.e("InAppBrowser", "Error closing WebView: " + e.getMessage());
880
+ call.reject("Failed to close WebView: " + e.getMessage());
881
+ }
882
+ }
883
+ }
884
+ );
885
+ }
886
+
887
+ private Bundle getHeaders(PluginCall pluginCall) {
888
+ JSObject headersProvided = pluginCall.getObject("headers");
889
+ Bundle headers = new Bundle();
890
+ if (headersProvided != null) {
891
+ Iterator<String> keys = headersProvided.keys();
892
+ while (keys.hasNext()) {
893
+ String key = keys.next();
894
+ headers.putString(key, headersProvided.getString(key));
895
+ }
896
+ }
897
+ return headers;
898
+ }
899
+
900
+ protected void handleOnResume() {
901
+ boolean ok = CustomTabsClient.bindCustomTabsService(getContext(), CUSTOM_TAB_PACKAGE_NAME, connection);
902
+ if (!ok) {
903
+ Log.e(getLogTag(), "Error binding to custom tabs service");
904
+ }
905
+ }
906
+
907
+ protected void handleOnPause() {
908
+ getContext().unbindService(connection);
909
+ }
910
+
911
+ public CustomTabsSession getCustomTabsSession() {
912
+ if (customTabsClient == null) {
913
+ return null;
914
+ }
915
+
916
+ if (currentSession == null) {
917
+ currentSession = customTabsClient.newSession(
918
+ new CustomTabsCallback() {
919
+ @Override
920
+ public void onNavigationEvent(int navigationEvent, Bundle extras) {
921
+ // Only fire browserPageLoaded for Custom Tabs, not for WebView
922
+ if (navigationEvent == NAVIGATION_FINISHED && webViewDialog == null) {
923
+ notifyListeners("browserPageLoaded", new JSObject());
924
+ }
925
+ }
926
+ }
927
+ );
928
+ }
929
+ return currentSession;
930
+ }
931
+
932
+ @Override
933
+ protected void handleOnDestroy() {
934
+ if (webViewDialog != null) {
935
+ try {
936
+ webViewDialog.dismiss();
937
+ } catch (Exception e) {
938
+ // Ignore, dialog may already be dismissed
939
+ }
940
+ webViewDialog = null;
941
+ }
942
+ currentPermissionRequest = null;
943
+ customTabsClient = null;
944
+ currentSession = null;
945
+ super.handleOnDestroy();
946
+ }
947
+
948
+ @PluginMethod
949
+ public void getPluginVersion(final PluginCall call) {
950
+ try {
951
+ final JSObject ret = new JSObject();
952
+ ret.put("version", this.pluginVersion);
953
+ call.resolve(ret);
954
+ } catch (final Exception e) {
955
+ call.reject("Could not get plugin version", e);
956
+ }
957
+ }
958
+
959
+ @PluginMethod
960
+ public void updateDimensions(PluginCall call) {
961
+ if (webViewDialog == null) {
962
+ call.reject("WebView is not initialized");
963
+ return;
964
+ }
965
+
966
+ Integer width = call.getInt("width");
967
+ Integer height = call.getInt("height");
968
+ Integer x = call.getInt("x");
969
+ Integer y = call.getInt("y");
970
+
971
+ this.getActivity().runOnUiThread(
972
+ new Runnable() {
973
+ @Override
974
+ public void run() {
975
+ try {
976
+ if (webViewDialog != null) {
977
+ webViewDialog.updateDimensions(width, height, x, y);
978
+ call.resolve();
979
+ } else {
980
+ call.reject("WebView is not initialized");
981
+ }
982
+ } catch (Exception e) {
983
+ Log.e("InAppBrowser", "Error updating dimensions: " + e.getMessage());
984
+ call.reject("Failed to update dimensions: " + e.getMessage());
985
+ }
986
+ }
987
+ }
238
988
  );
239
989
  }
240
- return currentSession;
241
- }
242
990
  }