@capgo/inappbrowser 6.4.3 → 6.6.1
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/README.md +128 -30
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/InAppBrowserPlugin.java +91 -10
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/Options.java +9 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewDialog.java +132 -4
- package/dist/docs.json +666 -8
- package/dist/esm/definitions.d.ts +20 -2
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +2 -0
- package/dist/esm/web.js +8 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +8 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +8 -0
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/InAppBrowserPlugin.m +2 -0
- package/ios/Plugin/InAppBrowserPlugin.swift +49 -25
- package/ios/Plugin/WKWebViewController.swift +76 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -70,6 +70,8 @@ Add the following to your `Info.plist` file:
|
|
|
70
70
|
|
|
71
71
|
* [`open(...)`](#open)
|
|
72
72
|
* [`clearCookies(...)`](#clearcookies)
|
|
73
|
+
* [`clearAllCookies()`](#clearallcookies)
|
|
74
|
+
* [`clearCache()`](#clearcache)
|
|
73
75
|
* [`getCookies(...)`](#getcookies)
|
|
74
76
|
* [`close()`](#close)
|
|
75
77
|
* [`openWebView(...)`](#openwebview)
|
|
@@ -131,6 +133,36 @@ Clear cookies of url
|
|
|
131
133
|
--------------------
|
|
132
134
|
|
|
133
135
|
|
|
136
|
+
### clearAllCookies()
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
clearAllCookies() => Promise<any>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Clear all cookies
|
|
143
|
+
|
|
144
|
+
**Returns:** <code>Promise<any></code>
|
|
145
|
+
|
|
146
|
+
**Since:** 6.5.0
|
|
147
|
+
|
|
148
|
+
--------------------
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
### clearCache()
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
clearCache() => Promise<any>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Clear cache
|
|
158
|
+
|
|
159
|
+
**Returns:** <code>Promise<any></code>
|
|
160
|
+
|
|
161
|
+
**Since:** 6.5.0
|
|
162
|
+
|
|
163
|
+
--------------------
|
|
164
|
+
|
|
165
|
+
|
|
134
166
|
### getCookies(...)
|
|
135
167
|
|
|
136
168
|
```typescript
|
|
@@ -335,7 +367,7 @@ Will be triggered when page is loaded
|
|
|
335
367
|
addListener(eventName: "pageLoadError", listenerFunc: () => void) => Promise<PluginListenerHandle>
|
|
336
368
|
```
|
|
337
369
|
|
|
338
|
-
Will be triggered when page
|
|
370
|
+
Will be triggered when page load error
|
|
339
371
|
|
|
340
372
|
| Param | Type |
|
|
341
373
|
| ------------------ | ---------------------------- |
|
|
@@ -402,10 +434,9 @@ Reload the current web page.
|
|
|
402
434
|
|
|
403
435
|
#### ClearCookieOptions
|
|
404
436
|
|
|
405
|
-
| Prop
|
|
406
|
-
|
|
|
407
|
-
| **`url`**
|
|
408
|
-
| **`cache`** | <code>boolean</code> |
|
|
437
|
+
| Prop | Type |
|
|
438
|
+
| --------- | ------------------- |
|
|
439
|
+
| **`url`** | <code>string</code> |
|
|
409
440
|
|
|
410
441
|
|
|
411
442
|
#### HttpCookie
|
|
@@ -427,31 +458,32 @@ Reload the current web page.
|
|
|
427
458
|
|
|
428
459
|
#### OpenWebViewOptions
|
|
429
460
|
|
|
430
|
-
| Prop | Type | Description
|
|
431
|
-
| -------------------------------------- | --------------------------------------------------------------- |
|
|
432
|
-
| **`url`** | <code>string</code> | Target URL to load.
|
|
433
|
-
| **`headers`** | <code><a href="#headers">Headers</a></code> | <a href="#headers">Headers</a> to send with the request.
|
|
434
|
-
| **`credentials`** | <code><a href="#credentials">Credentials</a></code> | <a href="#credentials">Credentials</a> to send with the request and all subsequent requests for the same host.
|
|
435
|
-
| **`shareDisclaimer`** | <code><a href="#disclaimeroptions">DisclaimerOptions</a></code> | share options
|
|
436
|
-
| **`toolbarType`** | <code><a href="#toolbartype">ToolBarType</a></code> | Toolbar type
|
|
437
|
-
| **`shareSubject`** | <code>string</code> | Share subject
|
|
438
|
-
| **`title`** | <code>string</code> | Title of the browser
|
|
439
|
-
| **`backgroundColor`** | <code><a href="#backgroundcolor">BackgroundColor</a></code> | Background color of the browser, only on IOS
|
|
440
|
-
| **`activeNativeNavigationForWebview`** | <code>boolean</code> | If true, active the native navigation within the webview, Android only
|
|
441
|
-
| **`disableGoBackOnNativeApplication`** | <code>boolean</code> | Disable the possibility to go back on native application, usefull to force user to stay on the webview, Android only
|
|
442
|
-
| **`isPresentAfterPageLoad`** | <code>boolean</code> | Open url in a new window fullscreen isPresentAfterPageLoad: if true, the browser will be presented after the page is loaded, if false, the browser will be presented immediately.
|
|
443
|
-
| **`isInspectable`** | <code>boolean</code> | Whether the website in the webview is inspectable or not, ios only
|
|
444
|
-
| **`isAnimated`** | <code>boolean</code> | Whether the webview opening is animated or not, ios only
|
|
445
|
-
| **`showReloadButton`** | <code>boolean</code> | Shows a reload button that reloads the web page
|
|
446
|
-
| **`closeModal`** | <code>boolean</code> | CloseModal: if true a confirm will be displayed when user clicks on close button, if false the browser will be closed immediately.
|
|
447
|
-
| **`closeModalTitle`** | <code>string</code> | CloseModalTitle: title of the confirm when user clicks on close button, only on IOS
|
|
448
|
-
| **`closeModalDescription`** | <code>string</code> | CloseModalDescription: description of the confirm when user clicks on close button, only on IOS
|
|
449
|
-
| **`closeModalOk`** | <code>string</code> | CloseModalOk: text of the confirm button when user clicks on close button, only on IOS
|
|
450
|
-
| **`closeModalCancel`** | <code>string</code> | CloseModalCancel: text of the cancel button when user clicks on close button, only on IOS
|
|
451
|
-
| **`visibleTitle`** | <code>boolean</code> | visibleTitle: if true the website title would be shown else shown empty
|
|
452
|
-
| **`toolbarColor`** | <code>string</code> | toolbarColor: color of the toolbar in hex format
|
|
453
|
-
| **`showArrow`** | <code>boolean</code> | showArrow: if true an arrow would be shown instead of cross for closing the window
|
|
454
|
-
| **`ignoreUntrustedSSLError`** | <code>boolean</code> | ignoreUntrustedSSLError: if true, the webview will ignore untrusted SSL errors allowing the user to view the website.
|
|
461
|
+
| Prop | Type | Description | Default | Since |
|
|
462
|
+
| -------------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | ------ |
|
|
463
|
+
| **`url`** | <code>string</code> | Target URL to load. | | 0.1.0 |
|
|
464
|
+
| **`headers`** | <code><a href="#headers">Headers</a></code> | <a href="#headers">Headers</a> to send with the request. | | 0.1.0 |
|
|
465
|
+
| **`credentials`** | <code><a href="#credentials">Credentials</a></code> | <a href="#credentials">Credentials</a> to send with the request and all subsequent requests for the same host. | | 6.1.0 |
|
|
466
|
+
| **`shareDisclaimer`** | <code><a href="#disclaimeroptions">DisclaimerOptions</a></code> | share options | | 0.1.0 |
|
|
467
|
+
| **`toolbarType`** | <code><a href="#toolbartype">ToolBarType</a></code> | Toolbar type | <code>ToolBarType.DEFAULT</code> | 0.1.0 |
|
|
468
|
+
| **`shareSubject`** | <code>string</code> | Share subject | | 0.1.0 |
|
|
469
|
+
| **`title`** | <code>string</code> | Title of the browser | <code>'New Window'</code> | 0.1.0 |
|
|
470
|
+
| **`backgroundColor`** | <code><a href="#backgroundcolor">BackgroundColor</a></code> | Background color of the browser, only on IOS | <code>BackgroundColor.BLACK</code> | 0.1.0 |
|
|
471
|
+
| **`activeNativeNavigationForWebview`** | <code>boolean</code> | If true, active the native navigation within the webview, Android only | <code>false</code> | |
|
|
472
|
+
| **`disableGoBackOnNativeApplication`** | <code>boolean</code> | Disable the possibility to go back on native application, usefull to force user to stay on the webview, Android only | <code>false</code> | |
|
|
473
|
+
| **`isPresentAfterPageLoad`** | <code>boolean</code> | Open url in a new window fullscreen isPresentAfterPageLoad: if true, the browser will be presented after the page is loaded, if false, the browser will be presented immediately. | <code>false</code> | 0.1.0 |
|
|
474
|
+
| **`isInspectable`** | <code>boolean</code> | Whether the website in the webview is inspectable or not, ios only | <code>false</code> | |
|
|
475
|
+
| **`isAnimated`** | <code>boolean</code> | Whether the webview opening is animated or not, ios only | <code>true</code> | |
|
|
476
|
+
| **`showReloadButton`** | <code>boolean</code> | Shows a reload button that reloads the web page | <code>false</code> | 1.0.15 |
|
|
477
|
+
| **`closeModal`** | <code>boolean</code> | CloseModal: if true a confirm will be displayed when user clicks on close button, if false the browser will be closed immediately. | <code>false</code> | 1.1.0 |
|
|
478
|
+
| **`closeModalTitle`** | <code>string</code> | CloseModalTitle: title of the confirm when user clicks on close button, only on IOS | <code>'Close'</code> | 1.1.0 |
|
|
479
|
+
| **`closeModalDescription`** | <code>string</code> | CloseModalDescription: description of the confirm when user clicks on close button, only on IOS | <code>'Are you sure you want to close this window?'</code> | 1.1.0 |
|
|
480
|
+
| **`closeModalOk`** | <code>string</code> | CloseModalOk: text of the confirm button when user clicks on close button, only on IOS | <code>'Close'</code> | 1.1.0 |
|
|
481
|
+
| **`closeModalCancel`** | <code>string</code> | CloseModalCancel: text of the cancel button when user clicks on close button, only on IOS | <code>'Cancel'</code> | 1.1.0 |
|
|
482
|
+
| **`visibleTitle`** | <code>boolean</code> | visibleTitle: if true the website title would be shown else shown empty | <code>true</code> | 1.2.5 |
|
|
483
|
+
| **`toolbarColor`** | <code>string</code> | toolbarColor: color of the toolbar in hex format | <code>'#ffffff''</code> | 1.2.5 |
|
|
484
|
+
| **`showArrow`** | <code>boolean</code> | showArrow: if true an arrow would be shown instead of cross for closing the window | <code>false</code> | 1.2.5 |
|
|
485
|
+
| **`ignoreUntrustedSSLError`** | <code>boolean</code> | ignoreUntrustedSSLError: if true, the webview will ignore untrusted SSL errors allowing the user to view the website. | <code>false</code> | 6.1.0 |
|
|
486
|
+
| **`preShowScript`** | <code><a href="#string">String</a></code> | preShowScript: if isPresentAfterPageLoad is true and this variable is set the plugin will inject a script before showing the browser. This script will be run in an async context. The plugin will wait for the script to finish (max 10 seconds) | | 6.6.0 |
|
|
455
487
|
|
|
456
488
|
|
|
457
489
|
#### DisclaimerOptions
|
|
@@ -464,6 +496,72 @@ Reload the current web page.
|
|
|
464
496
|
| **`cancelBtn`** | <code>string</code> |
|
|
465
497
|
|
|
466
498
|
|
|
499
|
+
#### String
|
|
500
|
+
|
|
501
|
+
Allows manipulation and formatting of text strings and determination and location of substrings within strings.
|
|
502
|
+
|
|
503
|
+
| Prop | Type | Description |
|
|
504
|
+
| ------------ | ------------------- | ------------------------------------------------------------ |
|
|
505
|
+
| **`length`** | <code>number</code> | Returns the length of a <a href="#string">String</a> object. |
|
|
506
|
+
|
|
507
|
+
| Method | Signature | Description |
|
|
508
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
509
|
+
| **toString** | () => string | Returns a string representation of a string. |
|
|
510
|
+
| **charAt** | (pos: number) => string | Returns the character at the specified index. |
|
|
511
|
+
| **charCodeAt** | (index: number) => number | Returns the Unicode value of the character at the specified location. |
|
|
512
|
+
| **concat** | (...strings: string[]) => string | Returns a string that contains the concatenation of two or more strings. |
|
|
513
|
+
| **indexOf** | (searchString: string, position?: number \| undefined) => number | Returns the position of the first occurrence of a substring. |
|
|
514
|
+
| **lastIndexOf** | (searchString: string, position?: number \| undefined) => number | Returns the last occurrence of a substring in the string. |
|
|
515
|
+
| **localeCompare** | (that: string) => number | Determines whether two strings are equivalent in the current locale. |
|
|
516
|
+
| **match** | (regexp: string \| <a href="#regexp">RegExp</a>) => <a href="#regexpmatcharray">RegExpMatchArray</a> \| null | Matches a string with a regular expression, and returns an array containing the results of that search. |
|
|
517
|
+
| **replace** | (searchValue: string \| <a href="#regexp">RegExp</a>, replaceValue: string) => string | Replaces text in a string, using a regular expression or search string. |
|
|
518
|
+
| **replace** | (searchValue: string \| <a href="#regexp">RegExp</a>, replacer: (substring: string, ...args: any[]) => string) => string | Replaces text in a string, using a regular expression or search string. |
|
|
519
|
+
| **search** | (regexp: string \| <a href="#regexp">RegExp</a>) => number | Finds the first substring match in a regular expression search. |
|
|
520
|
+
| **slice** | (start?: number \| undefined, end?: number \| undefined) => string | Returns a section of a string. |
|
|
521
|
+
| **split** | (separator: string \| <a href="#regexp">RegExp</a>, limit?: number \| undefined) => string[] | Split a string into substrings using the specified separator and return them as an array. |
|
|
522
|
+
| **substring** | (start: number, end?: number \| undefined) => string | Returns the substring at the specified location within a <a href="#string">String</a> object. |
|
|
523
|
+
| **toLowerCase** | () => string | Converts all the alphabetic characters in a string to lowercase. |
|
|
524
|
+
| **toLocaleLowerCase** | (locales?: string \| string[] \| undefined) => string | Converts all alphabetic characters to lowercase, taking into account the host environment's current locale. |
|
|
525
|
+
| **toUpperCase** | () => string | Converts all the alphabetic characters in a string to uppercase. |
|
|
526
|
+
| **toLocaleUpperCase** | (locales?: string \| string[] \| undefined) => string | Returns a string where all alphabetic characters have been converted to uppercase, taking into account the host environment's current locale. |
|
|
527
|
+
| **trim** | () => string | Removes the leading and trailing white space and line terminator characters from a string. |
|
|
528
|
+
| **substr** | (from: number, length?: number \| undefined) => string | Gets a substring beginning at the specified location and having the specified length. |
|
|
529
|
+
| **valueOf** | () => string | Returns the primitive value of the specified object. |
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
#### RegExpMatchArray
|
|
533
|
+
|
|
534
|
+
| Prop | Type |
|
|
535
|
+
| ----------- | ------------------- |
|
|
536
|
+
| **`index`** | <code>number</code> |
|
|
537
|
+
| **`input`** | <code>string</code> |
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
#### RegExp
|
|
541
|
+
|
|
542
|
+
| Prop | Type | Description |
|
|
543
|
+
| ---------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
544
|
+
| **`source`** | <code>string</code> | Returns a copy of the text of the regular expression pattern. Read-only. The regExp argument is a Regular expression object. It can be a variable name or a literal. |
|
|
545
|
+
| **`global`** | <code>boolean</code> | Returns a Boolean value indicating the state of the global flag (g) used with a regular expression. Default is false. Read-only. |
|
|
546
|
+
| **`ignoreCase`** | <code>boolean</code> | Returns a Boolean value indicating the state of the ignoreCase flag (i) used with a regular expression. Default is false. Read-only. |
|
|
547
|
+
| **`multiline`** | <code>boolean</code> | Returns a Boolean value indicating the state of the multiline flag (m) used with a regular expression. Default is false. Read-only. |
|
|
548
|
+
| **`lastIndex`** | <code>number</code> | |
|
|
549
|
+
|
|
550
|
+
| Method | Signature | Description |
|
|
551
|
+
| ----------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
|
552
|
+
| **exec** | (string: string) => <a href="#regexpexecarray">RegExpExecArray</a> \| null | Executes a search on a string using a regular expression pattern, and returns an array containing the results of that search. |
|
|
553
|
+
| **test** | (string: string) => boolean | Returns a Boolean value that indicates whether or not a pattern exists in a searched string. |
|
|
554
|
+
| **compile** | () => this | |
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
#### RegExpExecArray
|
|
558
|
+
|
|
559
|
+
| Prop | Type |
|
|
560
|
+
| ----------- | ------------------- |
|
|
561
|
+
| **`index`** | <code>number</code> |
|
|
562
|
+
| **`input`** | <code>string</code> |
|
|
563
|
+
|
|
564
|
+
|
|
467
565
|
#### PluginListenerHandle
|
|
468
566
|
|
|
469
567
|
| Prop | Type |
|
|
@@ -9,9 +9,14 @@ import android.content.pm.ResolveInfo;
|
|
|
9
9
|
import android.net.Uri;
|
|
10
10
|
import android.os.Bundle;
|
|
11
11
|
import android.text.TextUtils;
|
|
12
|
+
import android.util.ArrayMap;
|
|
12
13
|
import android.util.Log;
|
|
14
|
+
import android.view.View;
|
|
15
|
+
import android.view.View;
|
|
13
16
|
import android.webkit.CookieManager;
|
|
14
17
|
import android.webkit.PermissionRequest;
|
|
18
|
+
import android.webkit.WebResourceRequest;
|
|
19
|
+
import android.webkit.WebResourceResponse;
|
|
15
20
|
import androidx.browser.customtabs.CustomTabsCallback;
|
|
16
21
|
import androidx.browser.customtabs.CustomTabsClient;
|
|
17
22
|
import androidx.browser.customtabs.CustomTabsIntent;
|
|
@@ -25,7 +30,13 @@ import com.getcapacitor.PluginMethod;
|
|
|
25
30
|
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
26
31
|
import com.getcapacitor.annotation.Permission;
|
|
27
32
|
import com.getcapacitor.annotation.PermissionCallback;
|
|
33
|
+
import java.util.ArrayList;
|
|
28
34
|
import java.util.Iterator;
|
|
35
|
+
import java.util.List;
|
|
36
|
+
import java.util.Objects;
|
|
37
|
+
import java.util.Optional;
|
|
38
|
+
import java.util.UUID;
|
|
39
|
+
import java.util.concurrent.Semaphore;
|
|
29
40
|
import org.json.JSONException;
|
|
30
41
|
import org.json.JSONObject;
|
|
31
42
|
|
|
@@ -137,7 +148,16 @@ public class InAppBrowserPlugin
|
|
|
137
148
|
|
|
138
149
|
if (resultCode == Activity.RESULT_OK) {
|
|
139
150
|
if (data != null) {
|
|
140
|
-
|
|
151
|
+
String dataString = data.getDataString();
|
|
152
|
+
if (data.getClipData() != null) { // If multiple file selected
|
|
153
|
+
int count = data.getClipData().getItemCount();
|
|
154
|
+
results = new Uri[count];
|
|
155
|
+
for (int i = 0; i < count; i++) {
|
|
156
|
+
results[i] = data.getClipData().getItemAt(i).getUri();
|
|
157
|
+
}
|
|
158
|
+
} else if (dataString != null) { //if single file selected
|
|
159
|
+
results = new Uri[] { Uri.parse(dataString) };
|
|
160
|
+
}
|
|
141
161
|
}
|
|
142
162
|
}
|
|
143
163
|
|
|
@@ -284,23 +304,83 @@ public class InAppBrowserPlugin
|
|
|
284
304
|
call.resolve();
|
|
285
305
|
}
|
|
286
306
|
|
|
307
|
+
@PluginMethod
|
|
308
|
+
public void clearCache(PluginCall call) {
|
|
309
|
+
CookieManager cookieManager = CookieManager.getInstance();
|
|
310
|
+
cookieManager.removeAllCookies(null);
|
|
311
|
+
cookieManager.flush();
|
|
312
|
+
call.resolve();
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
@PluginMethod
|
|
316
|
+
public void clearAllCookies(PluginCall call) {
|
|
317
|
+
CookieManager cookieManager = CookieManager.getInstance();
|
|
318
|
+
cookieManager.removeAllCookies(null);
|
|
319
|
+
cookieManager.flush();
|
|
320
|
+
call.resolve();
|
|
321
|
+
}
|
|
322
|
+
|
|
287
323
|
@PluginMethod
|
|
288
324
|
public void clearCookies(PluginCall call) {
|
|
289
325
|
String url = call.getString("url", currentUrl);
|
|
290
|
-
Boolean clearCache = call.getBoolean("cache", false);
|
|
291
326
|
if (url == null || TextUtils.isEmpty(url)) {
|
|
292
327
|
call.reject("Invalid URL");
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
Uri uri = Uri.parse(url);
|
|
332
|
+
String host = uri.getHost();
|
|
333
|
+
if (host == null || TextUtils.isEmpty(host)) {
|
|
334
|
+
call.reject("Invalid URL (Host is null)");
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
CookieManager cookieManager = CookieManager.getInstance();
|
|
339
|
+
String cookieString = cookieManager.getCookie(url);
|
|
340
|
+
ArrayList<String> cookiesToRemove = new ArrayList<>();
|
|
341
|
+
|
|
342
|
+
cookiesToRemove.clear();
|
|
343
|
+
|
|
344
|
+
if (cookieString != null) {
|
|
345
|
+
String[] cookies = cookieString.split("; ");
|
|
346
|
+
|
|
347
|
+
String domain = uri.getHost();
|
|
348
|
+
|
|
349
|
+
for (String cookie : cookies) {
|
|
350
|
+
String[] parts = cookie.split("=");
|
|
351
|
+
if (parts.length > 0) {
|
|
352
|
+
cookiesToRemove.add(parts[0].trim());
|
|
353
|
+
CookieManager.getInstance()
|
|
354
|
+
.setCookie(url, String.format("%s=del;", parts[0].trim()));
|
|
300
355
|
}
|
|
301
356
|
}
|
|
302
|
-
call.resolve();
|
|
303
357
|
}
|
|
358
|
+
|
|
359
|
+
StringBuilder scriptToRun = new StringBuilder();
|
|
360
|
+
for (String cookieToRemove : cookiesToRemove) {
|
|
361
|
+
scriptToRun.append(
|
|
362
|
+
String.format(
|
|
363
|
+
"window.cookieStore.delete('%s', {name: '%s', domain: '%s'});",
|
|
364
|
+
cookieToRemove,
|
|
365
|
+
cookieToRemove,
|
|
366
|
+
url
|
|
367
|
+
)
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
Log.i("DelCookies", String.format("Script to run:\n%s", scriptToRun));
|
|
372
|
+
|
|
373
|
+
this.getActivity()
|
|
374
|
+
.runOnUiThread(
|
|
375
|
+
new Runnable() {
|
|
376
|
+
@Override
|
|
377
|
+
public void run() {
|
|
378
|
+
webViewDialog.executeScript(scriptToRun.toString());
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
call.resolve();
|
|
304
384
|
}
|
|
305
385
|
|
|
306
386
|
@PluginMethod
|
|
@@ -350,6 +430,7 @@ public class InAppBrowserPlugin
|
|
|
350
430
|
Boolean.TRUE.equals(call.getBoolean("ignoreUntrustedSSLError", false))
|
|
351
431
|
);
|
|
352
432
|
options.setShareDisclaimer(call.getObject("shareDisclaimer", null));
|
|
433
|
+
options.setPreShowScript(call.getString("preShowScript", null));
|
|
353
434
|
options.setShareSubject(call.getString("shareSubject", null));
|
|
354
435
|
options.setToolbarType(call.getString("toolbarType", ""));
|
|
355
436
|
options.setActiveNativeNavigationForWebview(
|
|
@@ -26,6 +26,7 @@ public class Options {
|
|
|
26
26
|
private String ToolbarColor;
|
|
27
27
|
private boolean ShowArrow;
|
|
28
28
|
private boolean ignoreUntrustedSSLError;
|
|
29
|
+
private String preShowScript;
|
|
29
30
|
|
|
30
31
|
public PluginCall getPluginCall() {
|
|
31
32
|
return pluginCall;
|
|
@@ -208,4 +209,12 @@ public class Options {
|
|
|
208
209
|
public void setIgnoreUntrustedSSLError(boolean _ignoreUntrustedSSLError) {
|
|
209
210
|
this.ignoreUntrustedSSLError = _ignoreUntrustedSSLError;
|
|
210
211
|
}
|
|
212
|
+
|
|
213
|
+
public String getPreShowScript() {
|
|
214
|
+
return preShowScript;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
public void setPreShowScript(String preLoadScript) {
|
|
218
|
+
this.preShowScript = preLoadScript;
|
|
219
|
+
}
|
|
211
220
|
}
|
|
@@ -14,6 +14,7 @@ import android.net.Uri;
|
|
|
14
14
|
import android.net.http.SslError;
|
|
15
15
|
import android.text.TextUtils;
|
|
16
16
|
import android.util.Log;
|
|
17
|
+
import android.view.KeyEvent;
|
|
17
18
|
import android.view.View;
|
|
18
19
|
import android.view.Window;
|
|
19
20
|
import android.view.WindowManager;
|
|
@@ -25,12 +26,14 @@ import android.webkit.ValueCallback;
|
|
|
25
26
|
import android.webkit.WebChromeClient;
|
|
26
27
|
import android.webkit.WebResourceError;
|
|
27
28
|
import android.webkit.WebResourceRequest;
|
|
29
|
+
import android.webkit.WebResourceResponse;
|
|
28
30
|
import android.webkit.WebView;
|
|
29
31
|
import android.webkit.WebViewClient;
|
|
30
32
|
import android.widget.ImageButton;
|
|
31
33
|
import android.widget.TextView;
|
|
32
34
|
import android.widget.Toast;
|
|
33
35
|
import android.widget.Toolbar;
|
|
36
|
+
import androidx.annotation.Nullable;
|
|
34
37
|
import com.getcapacitor.JSObject;
|
|
35
38
|
import java.net.URI;
|
|
36
39
|
import java.net.URISyntaxException;
|
|
@@ -38,6 +41,10 @@ import java.util.HashMap;
|
|
|
38
41
|
import java.util.Iterator;
|
|
39
42
|
import java.util.Map;
|
|
40
43
|
import java.util.Objects;
|
|
44
|
+
import java.util.concurrent.ExecutorService;
|
|
45
|
+
import java.util.concurrent.Executors;
|
|
46
|
+
import java.util.concurrent.Semaphore;
|
|
47
|
+
import java.util.concurrent.TimeUnit;
|
|
41
48
|
import org.json.JSONArray;
|
|
42
49
|
import org.json.JSONObject;
|
|
43
50
|
|
|
@@ -50,10 +57,14 @@ public class WebViewDialog extends Dialog {
|
|
|
50
57
|
public Activity activity;
|
|
51
58
|
private boolean isInitialized = false;
|
|
52
59
|
|
|
60
|
+
Semaphore preShowSemaphore = null;
|
|
61
|
+
String preshowError = null;
|
|
62
|
+
|
|
53
63
|
public PermissionRequest currentPermissionRequest;
|
|
54
64
|
public static final int FILE_CHOOSER_REQUEST_CODE = 1000;
|
|
55
65
|
public ValueCallback<Uri> mUploadMessage;
|
|
56
66
|
public ValueCallback<Uri[]> mFilePathCallback;
|
|
67
|
+
ExecutorService executorService = Executors.newFixedThreadPool(1);
|
|
57
68
|
|
|
58
69
|
public interface PermissionHandler {
|
|
59
70
|
void handleCameraPermissionRequest(PermissionRequest request);
|
|
@@ -85,6 +96,26 @@ public class WebViewDialog extends Dialog {
|
|
|
85
96
|
}
|
|
86
97
|
}
|
|
87
98
|
|
|
99
|
+
public class PreShowScriptInterface {
|
|
100
|
+
|
|
101
|
+
@JavascriptInterface
|
|
102
|
+
public void error(String error) {
|
|
103
|
+
// Handle message from JavaScript
|
|
104
|
+
if (preShowSemaphore != null) {
|
|
105
|
+
preshowError = error;
|
|
106
|
+
preShowSemaphore.release();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@JavascriptInterface
|
|
111
|
+
public void success() {
|
|
112
|
+
// Handle message from JavaScript
|
|
113
|
+
if (preShowSemaphore != null) {
|
|
114
|
+
preShowSemaphore.release();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
88
119
|
public void presentWebView() {
|
|
89
120
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
90
121
|
setCancelable(true);
|
|
@@ -105,6 +136,10 @@ public class WebViewDialog extends Dialog {
|
|
|
105
136
|
new JavaScriptInterface(),
|
|
106
137
|
"AndroidInterface"
|
|
107
138
|
);
|
|
139
|
+
_webView.addJavascriptInterface(
|
|
140
|
+
new PreShowScriptInterface(),
|
|
141
|
+
"PreShowScriptInterface"
|
|
142
|
+
);
|
|
108
143
|
_webView.getSettings().setJavaScriptEnabled(true);
|
|
109
144
|
_webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
|
|
110
145
|
_webView.getSettings().setDatabaseEnabled(true);
|
|
@@ -117,6 +152,7 @@ public class WebViewDialog extends Dialog {
|
|
|
117
152
|
_webView.getSettings().setUseWideViewPort(true);
|
|
118
153
|
_webView.getSettings().setAllowFileAccessFromFileURLs(true);
|
|
119
154
|
_webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
|
|
155
|
+
_webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
|
|
120
156
|
|
|
121
157
|
_webView.setWebViewClient(new WebViewClient());
|
|
122
158
|
|
|
@@ -131,7 +167,8 @@ public class WebViewDialog extends Dialog {
|
|
|
131
167
|
) {
|
|
132
168
|
openFileChooser(
|
|
133
169
|
filePathCallback,
|
|
134
|
-
fileChooserParams.getAcceptTypes()[0]
|
|
170
|
+
fileChooserParams.getAcceptTypes()[0],
|
|
171
|
+
fileChooserParams.getMode() == FileChooserParams.MODE_OPEN_MULTIPLE
|
|
135
172
|
);
|
|
136
173
|
return true;
|
|
137
174
|
}
|
|
@@ -247,14 +284,71 @@ public class WebViewDialog extends Dialog {
|
|
|
247
284
|
_webView.evaluateJavascript(script, null);
|
|
248
285
|
}
|
|
249
286
|
|
|
287
|
+
private void injectPreShowScript() {
|
|
288
|
+
// String script =
|
|
289
|
+
// "import('https://unpkg.com/darkreader@4.9.89/darkreader.js').then(() => {DarkReader.enable({ brightness: 100, contrast: 90, sepia: 10 });window.PreLoadScriptInterface.finished()})";
|
|
290
|
+
|
|
291
|
+
if (preShowSemaphore != null) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
String script =
|
|
296
|
+
"async function preShowFunction() {\n" +
|
|
297
|
+
_options.getPreShowScript() +
|
|
298
|
+
'\n' +
|
|
299
|
+
"};\n" +
|
|
300
|
+
"preShowFunction().then(() => window.PreShowScriptInterface.success()).catch(err => { console.error('Preshow error', err); window.PreShowScriptInterface.error(JSON.stringify(err, Object.getOwnPropertyNames(err))) })";
|
|
301
|
+
|
|
302
|
+
Log.i(
|
|
303
|
+
"InjectPreShowScript",
|
|
304
|
+
String.format("PreShowScript script:\n%s", script)
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
preShowSemaphore = new Semaphore(0);
|
|
308
|
+
activity.runOnUiThread(
|
|
309
|
+
new Runnable() {
|
|
310
|
+
@Override
|
|
311
|
+
public void run() {
|
|
312
|
+
_webView.evaluateJavascript(script, null);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
try {
|
|
318
|
+
if (!preShowSemaphore.tryAcquire(10, TimeUnit.SECONDS)) {
|
|
319
|
+
Log.e(
|
|
320
|
+
"InjectPreShowScript",
|
|
321
|
+
"PreShowScript running for over 10 seconds. The plugin will not wait any longer!"
|
|
322
|
+
);
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
if (preshowError != null && !preshowError.isEmpty()) {
|
|
326
|
+
Log.e(
|
|
327
|
+
"InjectPreShowScript",
|
|
328
|
+
"Error within the user-provided preShowFunction: " + preshowError
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
} catch (InterruptedException e) {
|
|
332
|
+
Log.e(
|
|
333
|
+
"InjectPreShowScript",
|
|
334
|
+
"Error when calling InjectPreShowScript: " + e.getMessage()
|
|
335
|
+
);
|
|
336
|
+
} finally {
|
|
337
|
+
preShowSemaphore = null;
|
|
338
|
+
preshowError = null;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
250
342
|
private void openFileChooser(
|
|
251
343
|
ValueCallback<Uri[]> filePathCallback,
|
|
252
|
-
String acceptType
|
|
344
|
+
String acceptType,
|
|
345
|
+
boolean isMultiple
|
|
253
346
|
) {
|
|
254
347
|
mFilePathCallback = filePathCallback;
|
|
255
348
|
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
|
256
349
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
|
257
350
|
intent.setType(acceptType); // Default to */*
|
|
351
|
+
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, isMultiple);
|
|
258
352
|
activity.startActivityForResult(
|
|
259
353
|
Intent.createChooser(intent, "Select File"),
|
|
260
354
|
FILE_CHOOSER_REQUEST_CODE
|
|
@@ -545,9 +639,43 @@ public class WebViewDialog extends Dialog {
|
|
|
545
639
|
isInitialized = true;
|
|
546
640
|
_webView.clearHistory();
|
|
547
641
|
if (_options.isPresentAfterPageLoad()) {
|
|
548
|
-
|
|
549
|
-
|
|
642
|
+
boolean usePreShowScript =
|
|
643
|
+
_options.getPreShowScript() != null &&
|
|
644
|
+
!_options.getPreShowScript().isEmpty();
|
|
645
|
+
if (!usePreShowScript) {
|
|
646
|
+
show();
|
|
647
|
+
_options.getPluginCall().resolve();
|
|
648
|
+
} else {
|
|
649
|
+
executorService.execute(
|
|
650
|
+
new Runnable() {
|
|
651
|
+
@Override
|
|
652
|
+
public void run() {
|
|
653
|
+
if (
|
|
654
|
+
_options.getPreShowScript() != null &&
|
|
655
|
+
!_options.getPreShowScript().isEmpty()
|
|
656
|
+
) {
|
|
657
|
+
injectPreShowScript();
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
activity.runOnUiThread(
|
|
661
|
+
new Runnable() {
|
|
662
|
+
@Override
|
|
663
|
+
public void run() {
|
|
664
|
+
show();
|
|
665
|
+
_options.getPluginCall().resolve();
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
);
|
|
672
|
+
}
|
|
550
673
|
}
|
|
674
|
+
} else if (
|
|
675
|
+
_options.getPreShowScript() != null &&
|
|
676
|
+
!_options.getPreShowScript().isEmpty()
|
|
677
|
+
) {
|
|
678
|
+
injectPreShowScript();
|
|
551
679
|
}
|
|
552
680
|
|
|
553
681
|
ImageButton backButton = _toolbar.findViewById(R.id.backButton);
|