@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.
- package/CapgoInappbrowser.podspec +17 -0
- package/LICENSE +21 -0
- package/README.md +690 -0
- package/android/build.gradle +64 -0
- package/android/src/main/AndroidManifest.xml +12 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/InAppBrowserPlugin.java +741 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/Options.java +340 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewCallbacks.java +15 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewDialog.java +1177 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/android/src/main/res/drawable/arrow_back_disabled.xml +9 -0
- package/android/src/main/res/drawable/arrow_back_enabled.xml +9 -0
- package/android/src/main/res/drawable/arrow_forward_disabled.xml +9 -0
- package/android/src/main/res/drawable/arrow_forward_enabled.xml +9 -0
- package/android/src/main/res/drawable/ic_clear_24px.xml +9 -0
- package/android/src/main/res/drawable/ic_refresh.xml +9 -0
- package/android/src/main/res/layout/activity_browser.xml +22 -0
- package/android/src/main/res/layout/bridge_layout_main.xml +15 -0
- package/android/src/main/res/layout/content_browser.xml +16 -0
- package/android/src/main/res/layout/tool_bar.xml +72 -0
- package/android/src/main/res/values/browser_theme.xml +3 -0
- package/android/src/main/res/values/colors.xml +5 -0
- package/android/src/main/res/values/dimens.xml +3 -0
- package/android/src/main/res/values/strings.xml +11 -0
- package/android/src/main/res/values/styles.xml +4 -0
- package/dist/docs.json +1865 -0
- package/dist/esm/definitions.d.ts +361 -0
- package/dist/esm/definitions.js +13 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +19 -0
- package/dist/esm/web.js +48 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +75 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +78 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/Assets.xcassets/Back.imageset/Back.png +0 -0
- package/ios/Plugin/Assets.xcassets/Back.imageset/Back@2x.png +0 -0
- package/ios/Plugin/Assets.xcassets/Back.imageset/Back@3x.png +0 -0
- package/ios/Plugin/Assets.xcassets/Back.imageset/Contents.json +26 -0
- package/ios/Plugin/Assets.xcassets/Contents.json +6 -0
- package/ios/Plugin/Assets.xcassets/Forward.imageset/Contents.json +26 -0
- package/ios/Plugin/Assets.xcassets/Forward.imageset/Forward.png +0 -0
- package/ios/Plugin/Assets.xcassets/Forward.imageset/Forward@2x.png +0 -0
- package/ios/Plugin/Assets.xcassets/Forward.imageset/Forward@3x.png +0 -0
- package/ios/Plugin/Enums.swift +65 -0
- package/ios/Plugin/InAppBrowserPlugin.h +10 -0
- package/ios/Plugin/InAppBrowserPlugin.m +21 -0
- package/ios/Plugin/InAppBrowserPlugin.swift +434 -0
- package/ios/Plugin/Info.plist +24 -0
- package/ios/Plugin/WKWebViewController.swift +1021 -0
- 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
|
+
}
|