@capgo/inappbrowser 6.6.7 → 6.8.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 CHANGED
@@ -84,6 +84,7 @@ Add the following to your `Info.plist` file:
84
84
  * [`postMessage(...)`](#postmessage)
85
85
  * [`setUrl(...)`](#seturl)
86
86
  * [`addListener('urlChangeEvent', ...)`](#addlistenerurlchangeevent-)
87
+ * [`addListener('buttonNearDoneClick', ...)`](#addlistenerbuttonneardoneclick-)
87
88
  * [`addListener('closeEvent', ...)`](#addlistenercloseevent-)
88
89
  * [`addListener('confirmBtnClicked', ...)`](#addlistenerconfirmbtnclicked-)
89
90
  * [`addListener('messageFromWebview', ...)`](#addlistenermessagefromwebview-)
@@ -286,6 +287,22 @@ Listen for url change, only for openWebView
286
287
  --------------------
287
288
 
288
289
 
290
+ ### addListener('buttonNearDoneClick', ...)
291
+
292
+ ```typescript
293
+ addListener(eventName: "buttonNearDoneClick", listenerFunc: ButtonNearListener) => Promise<PluginListenerHandle>
294
+ ```
295
+
296
+ | Param | Type |
297
+ | ------------------ | ----------------------------------------------------------------- |
298
+ | **`eventName`** | <code>'buttonNearDoneClick'</code> |
299
+ | **`listenerFunc`** | <code><a href="#buttonnearlistener">ButtonNearListener</a></code> |
300
+
301
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
302
+
303
+ --------------------
304
+
305
+
289
306
  ### addListener('closeEvent', ...)
290
307
 
291
308
  ```typescript
@@ -463,32 +480,33 @@ Reload the current web page.
463
480
 
464
481
  #### OpenWebViewOptions
465
482
 
466
- | Prop | Type | Description | Default | Since |
467
- | -------------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | ------ |
468
- | **`url`** | <code>string</code> | Target URL to load. | | 0.1.0 |
469
- | **`headers`** | <code><a href="#headers">Headers</a></code> | <a href="#headers">Headers</a> to send with the request. | | 0.1.0 |
470
- | **`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 |
471
- | **`shareDisclaimer`** | <code><a href="#disclaimeroptions">DisclaimerOptions</a></code> | share options | | 0.1.0 |
472
- | **`toolbarType`** | <code><a href="#toolbartype">ToolBarType</a></code> | Toolbar type | <code>ToolBarType.DEFAULT</code> | 0.1.0 |
473
- | **`shareSubject`** | <code>string</code> | Share subject | | 0.1.0 |
474
- | **`title`** | <code>string</code> | Title of the browser | <code>'New Window'</code> | 0.1.0 |
475
- | **`backgroundColor`** | <code><a href="#backgroundcolor">BackgroundColor</a></code> | Background color of the browser, only on IOS | <code>BackgroundColor.BLACK</code> | 0.1.0 |
476
- | **`activeNativeNavigationForWebview`** | <code>boolean</code> | If true, active the native navigation within the webview, Android only | <code>false</code> | |
477
- | **`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> | |
478
- | **`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 |
479
- | **`isInspectable`** | <code>boolean</code> | Whether the website in the webview is inspectable or not, ios only | <code>false</code> | |
480
- | **`isAnimated`** | <code>boolean</code> | Whether the webview opening is animated or not, ios only | <code>true</code> | |
481
- | **`showReloadButton`** | <code>boolean</code> | Shows a reload button that reloads the web page | <code>false</code> | 1.0.15 |
482
- | **`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 |
483
- | **`closeModalTitle`** | <code>string</code> | CloseModalTitle: title of the confirm when user clicks on close button, only on IOS | <code>'Close'</code> | 1.1.0 |
484
- | **`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 |
485
- | **`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 |
486
- | **`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 |
487
- | **`visibleTitle`** | <code>boolean</code> | visibleTitle: if true the website title would be shown else shown empty | <code>true</code> | 1.2.5 |
488
- | **`toolbarColor`** | <code>string</code> | toolbarColor: color of the toolbar in hex format | <code>'#ffffff''</code> | 1.2.5 |
489
- | **`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 |
490
- | **`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 |
491
- | **`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 |
483
+ | Prop | Type | Description | Default | Since |
484
+ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | ------ |
485
+ | **`url`** | <code>string</code> | Target URL to load. | | 0.1.0 |
486
+ | **`headers`** | <code><a href="#headers">Headers</a></code> | <a href="#headers">Headers</a> to send with the request. | | 0.1.0 |
487
+ | **`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 |
488
+ | **`shareDisclaimer`** | <code><a href="#disclaimeroptions">DisclaimerOptions</a></code> | share options | | 0.1.0 |
489
+ | **`toolbarType`** | <code><a href="#toolbartype">ToolBarType</a></code> | Toolbar type | <code>ToolBarType.DEFAULT</code> | 0.1.0 |
490
+ | **`shareSubject`** | <code>string</code> | Share subject | | 0.1.0 |
491
+ | **`title`** | <code>string</code> | Title of the browser | <code>'New Window'</code> | 0.1.0 |
492
+ | **`backgroundColor`** | <code><a href="#backgroundcolor">BackgroundColor</a></code> | Background color of the browser, only on IOS | <code>BackgroundColor.BLACK</code> | 0.1.0 |
493
+ | **`activeNativeNavigationForWebview`** | <code>boolean</code> | If true, active the native navigation within the webview, Android only | <code>false</code> | |
494
+ | **`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> | |
495
+ | **`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 |
496
+ | **`isInspectable`** | <code>boolean</code> | Whether the website in the webview is inspectable or not, ios only | <code>false</code> | |
497
+ | **`isAnimated`** | <code>boolean</code> | Whether the webview opening is animated or not, ios only | <code>true</code> | |
498
+ | **`showReloadButton`** | <code>boolean</code> | Shows a reload button that reloads the web page | <code>false</code> | 1.0.15 |
499
+ | **`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 |
500
+ | **`closeModalTitle`** | <code>string</code> | CloseModalTitle: title of the confirm when user clicks on close button, only on IOS | <code>'Close'</code> | 1.1.0 |
501
+ | **`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 |
502
+ | **`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 |
503
+ | **`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 |
504
+ | **`visibleTitle`** | <code>boolean</code> | visibleTitle: if true the website title would be shown else shown empty | <code>true</code> | 1.2.5 |
505
+ | **`toolbarColor`** | <code>string</code> | toolbarColor: color of the toolbar in hex format | <code>'#ffffff''</code> | 1.2.5 |
506
+ | **`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 |
507
+ | **`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 |
508
+ | **`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 |
509
+ | **`buttonNearDone`** | <code>{ ios: { iconType: 'sf-symbol' \| 'asset'; icon: <a href="#string">String</a>; }; android: { iconType: 'asset'; icon: <a href="#string">String</a>; width?: number; height?: number; }; }</code> | buttonNearDone allows for a creation of a custom button. Please see [buttonNearDone.md](/buttonNearDone.md) for more info. | | 6.7.0 |
492
510
 
493
511
 
494
512
  #### DisclaimerOptions
@@ -634,6 +652,11 @@ Construct a type with a set of properties K of type T
634
652
  <code>(state: <a href="#urlevent">UrlEvent</a>): void</code>
635
653
 
636
654
 
655
+ #### ButtonNearListener
656
+
657
+ <code>(state: {}): void</code>
658
+
659
+
637
660
  #### ConfirmBtnListener
638
661
 
639
662
  <code>(state: <a href="#btnevent">BtnEvent</a>): void</code>
@@ -52,6 +52,7 @@ repositories {
52
52
  dependencies {
53
53
  implementation fileTree(dir: 'libs', include: ['*.jar'])
54
54
  implementation project(':capacitor-android')
55
+ implementation 'com.caverock:androidsvg:1.4'
55
56
  implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
56
57
  testImplementation "junit:junit:$junitVersion"
57
58
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
@@ -425,6 +425,29 @@ public class InAppBrowserPlugin
425
425
  options.setIgnoreUntrustedSSLError(
426
426
  Boolean.TRUE.equals(call.getBoolean("ignoreUntrustedSSLError", false))
427
427
  );
428
+
429
+ try {
430
+ Options.ButtonNearDone buttonNearDone =
431
+ Options.ButtonNearDone.generateFromPluginCall(
432
+ call,
433
+ getActivity().getAssets()
434
+ );
435
+ options.setButtonNearDone(buttonNearDone);
436
+ } catch (IllegalArgumentException illegalArgumentException) {
437
+ call.reject(
438
+ String.format(
439
+ "ButtonNearDone rejected: %s",
440
+ illegalArgumentException.getMessage()
441
+ )
442
+ );
443
+ } catch (RuntimeException e) {
444
+ Log.e(
445
+ "WebViewDialog",
446
+ String.format("ButtonNearDone runtime error: %s", e)
447
+ );
448
+ call.reject(String.format("ButtonNearDone RuntimeException: %s", e));
449
+ }
450
+
428
451
  options.setShareDisclaimer(call.getObject("shareDisclaimer", null));
429
452
  options.setPreShowScript(call.getString("preShowScript", null));
430
453
  options.setShareSubject(call.getString("shareSubject", null));
@@ -477,6 +500,11 @@ public class InAppBrowserPlugin
477
500
  notifyListeners("pageLoadError", new JSObject());
478
501
  }
479
502
 
503
+ @Override
504
+ public void buttonNearDoneClicked() {
505
+ notifyListeners("buttonNearDoneClick", new JSObject());
506
+ }
507
+
480
508
  @Override
481
509
  public void javascriptCallback(String message) {
482
510
  // Handle the message received from JavaScript
@@ -1,15 +1,117 @@
1
1
  package ee.forgr.capacitor_inappbrowser;
2
2
 
3
+ import android.content.res.AssetManager;
4
+ import androidx.annotation.Nullable;
3
5
  import com.getcapacitor.JSObject;
4
6
  import com.getcapacitor.PluginCall;
7
+ import java.io.IOException;
8
+ import java.io.InputStream;
9
+ import java.util.Objects;
5
10
 
6
11
  public class Options {
7
12
 
13
+ public static class ButtonNearDone {
14
+
15
+ public enum AllIconTypes {
16
+ ASSET,
17
+ }
18
+
19
+ private AllIconTypes iconType;
20
+ private String icon;
21
+ private int height;
22
+ private int width;
23
+
24
+ private ButtonNearDone(
25
+ AllIconTypes iconType,
26
+ String icon,
27
+ int height,
28
+ int width
29
+ ) {
30
+ this.iconType = iconType;
31
+ this.icon = icon;
32
+ this.height = height;
33
+ this.width = width;
34
+ }
35
+
36
+ @Nullable
37
+ public static ButtonNearDone generateFromPluginCall(
38
+ PluginCall call,
39
+ AssetManager assetManager
40
+ ) throws IllegalArgumentException, RuntimeException {
41
+ JSObject buttonNearDone = call.getObject("buttonNearDone");
42
+ if (buttonNearDone == null) {
43
+ // Return null when "buttonNearDone" isn't configured, else throw an error
44
+ return null;
45
+ }
46
+
47
+ JSObject android = buttonNearDone.getJSObject("android");
48
+ if (android == null) {
49
+ throw new IllegalArgumentException("buttonNearDone.android is null");
50
+ }
51
+
52
+ String iconType = android.getString("iconType", "asset");
53
+ if (!Objects.equals(iconType, "asset")) {
54
+ throw new IllegalArgumentException(
55
+ "buttonNearDone.android.iconType is not equal to \"asset\""
56
+ );
57
+ }
58
+
59
+ String icon = android.getString("icon");
60
+ if (icon == null) {
61
+ throw new IllegalArgumentException(
62
+ "buttonNearDone.android.icon is null"
63
+ );
64
+ }
65
+
66
+ InputStream fileInputString = null;
67
+
68
+ try {
69
+ // Try to open the file
70
+ fileInputString = assetManager.open(icon);
71
+ // do nothing
72
+ } catch (IOException e) {
73
+ throw new IllegalArgumentException(
74
+ "buttonNearDone.android.icon cannot be found in the assetManager"
75
+ );
76
+ } finally {
77
+ // Close the input stream if it was opened
78
+ if (fileInputString != null) {
79
+ try {
80
+ fileInputString.close();
81
+ } catch (IOException e) {
82
+ throw new RuntimeException(e);
83
+ }
84
+ }
85
+ }
86
+ Integer width = android.getInteger("width", 48);
87
+
88
+ Integer height = android.getInteger("height", 48);
89
+ return new ButtonNearDone(AllIconTypes.ASSET, icon, height, width);
90
+ }
91
+
92
+ public AllIconTypes getIconType() {
93
+ return iconType;
94
+ }
95
+
96
+ public String getIcon() {
97
+ return icon;
98
+ }
99
+
100
+ public int getHeight() {
101
+ return height;
102
+ }
103
+
104
+ public int getWidth() {
105
+ return width;
106
+ }
107
+ }
108
+
8
109
  private String title;
9
110
  private boolean CloseModal;
10
111
  private String CloseModalTitle;
11
112
  private String CloseModalDescription;
12
113
  private String CloseModalCancel;
114
+ private ButtonNearDone buttonNearDone;
13
115
  private String CloseModalOk;
14
116
  private String url;
15
117
  private JSObject headers;
@@ -68,6 +170,14 @@ public class Options {
68
170
  this.CloseModalDescription = CloseModalDescription;
69
171
  }
70
172
 
173
+ public void setButtonNearDone(ButtonNearDone buttonNearDone) {
174
+ this.buttonNearDone = buttonNearDone;
175
+ }
176
+
177
+ public ButtonNearDone getButtonNearDone() {
178
+ return this.buttonNearDone;
179
+ }
180
+
71
181
  public String getCloseModalCancel() {
72
182
  return CloseModalCancel;
73
183
  }
@@ -10,4 +10,6 @@ public interface WebViewCallbacks {
10
10
  public void pageLoadError();
11
11
 
12
12
  public void javascriptCallback(String message);
13
+
14
+ public void buttonNearDoneClicked();
13
15
  }
@@ -8,13 +8,18 @@ import android.content.ActivityNotFoundException;
8
8
  import android.content.Context;
9
9
  import android.content.DialogInterface;
10
10
  import android.content.Intent;
11
+ import android.content.res.AssetManager;
11
12
  import android.graphics.Bitmap;
12
13
  import android.graphics.Color;
14
+ import android.graphics.Picture;
15
+ import android.graphics.drawable.PictureDrawable;
13
16
  import android.net.Uri;
14
17
  import android.net.http.SslError;
15
18
  import android.text.TextUtils;
16
19
  import android.util.Log;
20
+ import android.view.KeyEvent;
17
21
  import android.view.View;
22
+ import android.view.ViewGroup.LayoutParams;
18
23
  import android.view.Window;
19
24
  import android.view.WindowManager;
20
25
  import android.webkit.HttpAuthHandler;
@@ -31,7 +36,12 @@ import android.widget.ImageButton;
31
36
  import android.widget.TextView;
32
37
  import android.widget.Toast;
33
38
  import android.widget.Toolbar;
39
+ import androidx.annotation.Nullable;
40
+ import com.caverock.androidsvg.SVG;
41
+ import com.caverock.androidsvg.SVGParseException;
34
42
  import com.getcapacitor.JSObject;
43
+ import java.io.IOException;
44
+ import java.io.InputStream;
35
45
  import java.net.URI;
36
46
  import java.net.URISyntaxException;
37
47
  import java.util.Arrays;
@@ -498,14 +508,65 @@ public class WebViewDialog extends Dialog {
498
508
  if (TextUtils.equals(_options.getToolbarType(), "activity")) {
499
509
  _toolbar.findViewById(R.id.forwardButton).setVisibility(View.GONE);
500
510
  _toolbar.findViewById(R.id.backButton).setVisibility(View.GONE);
511
+ ImageButton buttonNearDoneView = _toolbar.findViewById(
512
+ R.id.buttonNearDone
513
+ );
514
+ buttonNearDoneView.setVisibility(View.GONE);
501
515
  //TODO: Add share button functionality
502
516
  } else if (TextUtils.equals(_options.getToolbarType(), "navigation")) {
517
+ ImageButton buttonNearDoneView = _toolbar.findViewById(
518
+ R.id.buttonNearDone
519
+ );
520
+ buttonNearDoneView.setVisibility(View.GONE);
503
521
  //TODO: Remove share button when implemented
504
522
  } else if (TextUtils.equals(_options.getToolbarType(), "blank")) {
505
523
  _toolbar.setVisibility(View.GONE);
506
524
  } else {
507
525
  _toolbar.findViewById(R.id.forwardButton).setVisibility(View.GONE);
508
526
  _toolbar.findViewById(R.id.backButton).setVisibility(View.GONE);
527
+
528
+ Options.ButtonNearDone buttonNearDone = _options.getButtonNearDone();
529
+ if (buttonNearDone != null) {
530
+ AssetManager assetManager = _context.getAssets();
531
+
532
+ // Open the SVG file from assets
533
+ InputStream inputStream = null;
534
+ try {
535
+ ImageButton buttonNearDoneView = _toolbar.findViewById(
536
+ R.id.buttonNearDone
537
+ );
538
+ buttonNearDoneView.setVisibility(View.VISIBLE);
539
+
540
+ inputStream = assetManager.open(buttonNearDone.getIcon());
541
+
542
+ SVG svg = SVG.getFromInputStream(inputStream);
543
+ Picture picture = svg.renderToPicture(
544
+ buttonNearDone.getWidth(),
545
+ buttonNearDone.getHeight()
546
+ );
547
+ PictureDrawable pictureDrawable = new PictureDrawable(picture);
548
+
549
+ buttonNearDoneView.setImageDrawable(pictureDrawable);
550
+ buttonNearDoneView.setOnClickListener(view ->
551
+ _options.getCallbacks().buttonNearDoneClicked()
552
+ );
553
+ } catch (IOException | SVGParseException e) {
554
+ throw new RuntimeException(e);
555
+ } finally {
556
+ if (inputStream != null) {
557
+ try {
558
+ inputStream.close();
559
+ } catch (IOException e) {
560
+ throw new RuntimeException(e);
561
+ }
562
+ }
563
+ }
564
+ } else {
565
+ ImageButton buttonNearDoneView = _toolbar.findViewById(
566
+ R.id.buttonNearDone
567
+ );
568
+ buttonNearDoneView.setVisibility(View.GONE);
569
+ }
509
570
  }
510
571
  }
511
572
 
@@ -522,12 +583,20 @@ public class WebViewDialog extends Dialog {
522
583
 
523
584
  if (!url.startsWith("https://") && !url.startsWith("http://")) {
524
585
  try {
525
- Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
586
+ Intent intent;
587
+ if (url.startsWith("intent://")) {
588
+ intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
589
+ } else {
590
+ intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
591
+ }
592
+
526
593
  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
527
594
  context.startActivity(intent);
528
595
  return true;
529
596
  } catch (ActivityNotFoundException e) {
530
597
  // Do nothing
598
+ } catch (URISyntaxException e) {
599
+ // Do nothing
531
600
  }
532
601
  }
533
602
  return false;
@@ -674,7 +743,14 @@ public class WebViewDialog extends Dialog {
674
743
  _options.getPreShowScript() != null &&
675
744
  !_options.getPreShowScript().isEmpty()
676
745
  ) {
677
- injectPreShowScript();
746
+ executorService.execute(
747
+ new Runnable() {
748
+ @Override
749
+ public void run() {
750
+ injectPreShowScript();
751
+ }
752
+ }
753
+ );
678
754
  }
679
755
 
680
756
  ImageButton backButton = _toolbar.findViewById(R.id.backButton);
@@ -1,6 +1,7 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <android.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
3
3
  xmlns:app="http://schemas.android.com/apk/res-auto"
4
+ xmlns:tools="http://schemas.android.com/tools"
4
5
  android:layout_width="match_parent"
5
6
  android:layout_height="wrap_content"
6
7
  android:background="#eeeeef"
@@ -15,6 +16,18 @@
15
16
  android:layout_gravity="start"
16
17
  android:background="#eeeeef"
17
18
  android:contentDescription="@string/close_button" />
19
+
20
+ <ImageButton
21
+ android:id="@+id/buttonNearDone"
22
+ android:layout_width="wrap_content"
23
+ android:layout_height="wrap_content"
24
+ android:layout_gravity="start"
25
+ android:background="@android:color/transparent"
26
+ android:contentDescription="@string/button_near_done"
27
+ android:src="@drawable/ic_clear_24px"
28
+ android:translationX="64px"
29
+ tools:visibility="gone"
30
+ />
18
31
  <ImageButton
19
32
  android:id="@+id/reloadButton"
20
33
  android:layout_width="wrap_content"
@@ -3,6 +3,7 @@
3
3
  <string name="title_activity_browser">BrowserActivity</string>
4
4
  <string name="title_activity_basic">BasicActivity</string>
5
5
  <string name="close_button">Close Button</string>
6
+ <string name="button_near_done">Button near "done"</string>
6
7
  <string name="reload_button">Reload Button</string>
7
8
  <string name="back_button">Back Button</string>
8
9
  <string name="title">Title</string>
package/dist/docs.json CHANGED
@@ -221,6 +221,30 @@
221
221
  ],
222
222
  "slug": "addlistenerurlchangeevent-"
223
223
  },
224
+ {
225
+ "name": "addListener",
226
+ "signature": "(eventName: \"buttonNearDoneClick\", listenerFunc: ButtonNearListener) => Promise<PluginListenerHandle>",
227
+ "parameters": [
228
+ {
229
+ "name": "eventName",
230
+ "docs": "",
231
+ "type": "'buttonNearDoneClick'"
232
+ },
233
+ {
234
+ "name": "listenerFunc",
235
+ "docs": "",
236
+ "type": "ButtonNearListener"
237
+ }
238
+ ],
239
+ "returns": "Promise<PluginListenerHandle>",
240
+ "tags": [],
241
+ "docs": "",
242
+ "complexTypes": [
243
+ "PluginListenerHandle",
244
+ "ButtonNearListener"
245
+ ],
246
+ "slug": "addlistenerbuttonneardoneclick-"
247
+ },
224
248
  {
225
249
  "name": "addListener",
226
250
  "signature": "(eventName: \"closeEvent\", listenerFunc: UrlChangeListener) => Promise<PluginListenerHandle>",
@@ -913,6 +937,20 @@
913
937
  "String"
914
938
  ],
915
939
  "type": "String"
940
+ },
941
+ {
942
+ "name": "buttonNearDone",
943
+ "tags": [
944
+ {
945
+ "text": "6.7.0",
946
+ "name": "since"
947
+ }
948
+ ],
949
+ "docs": "buttonNearDone allows for a creation of a custom button. Please see [buttonNearDone.md](/buttonNearDone.md) for more info.",
950
+ "complexTypes": [
951
+ "String"
952
+ ],
953
+ "type": "{ ios: { iconType: 'sf-symbol' | 'asset'; icon: String; }; android: { iconType: 'asset'; icon: String; width?: number | undefined; height?: number | undefined; }; } | undefined"
916
954
  }
917
955
  ]
918
956
  },
@@ -1784,6 +1822,17 @@
1784
1822
  }
1785
1823
  ]
1786
1824
  },
1825
+ {
1826
+ "name": "ButtonNearListener",
1827
+ "slug": "buttonnearlistener",
1828
+ "docs": "",
1829
+ "types": [
1830
+ {
1831
+ "text": "(state: {}): void",
1832
+ "complexTypes": []
1833
+ }
1834
+ ]
1835
+ },
1787
1836
  {
1788
1837
  "name": "ConfirmBtnListener",
1789
1838
  "slug": "confirmbtnlistener",
@@ -17,6 +17,7 @@ export interface BtnEvent {
17
17
  }
18
18
  export type UrlChangeListener = (state: UrlEvent) => void;
19
19
  export type ConfirmBtnListener = (state: BtnEvent) => void;
20
+ export type ButtonNearListener = (state: {}) => void;
20
21
  export declare enum BackgroundColor {
21
22
  WHITE = "white",
22
23
  BLACK = "black"
@@ -223,6 +224,23 @@ export interface OpenWebViewOptions {
223
224
  * @since 6.6.0
224
225
  */
225
226
  preShowScript?: String;
227
+ /**
228
+ * buttonNearDone allows for a creation of a custom button. Please see [buttonNearDone.md](/buttonNearDone.md) for more info.
229
+ *
230
+ * @since 6.7.0
231
+ */
232
+ buttonNearDone?: {
233
+ ios: {
234
+ iconType: "sf-symbol" | "asset";
235
+ icon: String;
236
+ };
237
+ android: {
238
+ iconType: "asset";
239
+ icon: String;
240
+ width?: number;
241
+ height?: number;
242
+ };
243
+ };
226
244
  }
227
245
  export interface InAppBrowserPlugin {
228
246
  /**
@@ -291,6 +309,7 @@ export interface InAppBrowserPlugin {
291
309
  * @since 0.0.1
292
310
  */
293
311
  addListener(eventName: "urlChangeEvent", listenerFunc: UrlChangeListener): Promise<PluginListenerHandle>;
312
+ addListener(eventName: "buttonNearDoneClick", listenerFunc: ButtonNearListener): Promise<PluginListenerHandle>;
294
313
  /**
295
314
  * Listen for close click only for openWebView
296
315
  *
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAsBA,MAAM,CAAN,IAAY,eAGX;AAHD,WAAY,eAAe;IACzB,kCAAe,CAAA;IACf,kCAAe,CAAA;AACjB,CAAC,EAHW,eAAe,KAAf,eAAe,QAG1B;AACD,MAAM,CAAN,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,oCAAqB,CAAA;IACrB,wCAAyB,CAAA;IACzB,8BAAe,CAAA;IACf,2BAAY,CAAA;AACd,CAAC,EALW,WAAW,KAAX,WAAW,QAKtB","sourcesContent":["import type { PluginListenerHandle } from \"@capacitor/core\";\n\nexport interface UrlEvent {\n /**\n * Emit when the url changes\n *\n * @since 0.0.1\n */\n url: string;\n}\nexport interface BtnEvent {\n /**\n * Emit when a button is clicked.\n *\n * @since 0.0.1\n */\n url: string;\n}\n\nexport type UrlChangeListener = (state: UrlEvent) => void;\nexport type ConfirmBtnListener = (state: BtnEvent) => void;\n\nexport enum BackgroundColor {\n WHITE = \"white\",\n BLACK = \"black\",\n}\nexport enum ToolBarType {\n ACTIVITY = \"activity\",\n NAVIGATION = \"navigation\",\n BLANK = \"blank\",\n DEFAULT = \"\",\n}\n\nexport interface Headers {\n [key: string]: string;\n}\n\nexport interface GetCookieOptions {\n url: string;\n includeHttpOnly?: boolean;\n}\n\nexport interface ClearCookieOptions {\n url: string;\n}\n\nexport interface Credentials {\n username: string;\n password: string;\n}\n\nexport interface OpenOptions {\n /**\n * Target URL to load.\n * @since 0.1.0\n */\n url: string;\n /**\n * Headers to send with the request.\n * @since 0.1.0\n */\n headers?: Headers;\n /**\n * Credentials to send with the request and all subsequent requests for the same host.\n * @since 6.1.0\n */\n credentials?: Credentials;\n /**\n * if true, the browser will be presented after the page is loaded, if false, the browser will be presented immediately.\n * @since 0.1.0\n */\n isPresentAfterPageLoad?: boolean;\n preventDeeplink?: boolean;\n}\n\nexport interface DisclaimerOptions {\n title: string;\n message: string;\n confirmBtn: string;\n cancelBtn: string;\n}\n\nexport interface OpenWebViewOptions {\n /**\n * Target URL to load.\n * @since 0.1.0\n */\n url: string;\n /**\n * Headers to send with the request.\n * @since 0.1.0\n */\n headers?: Headers;\n /**\n * Credentials to send with the request and all subsequent requests for the same host.\n * @since 6.1.0\n */\n credentials?: Credentials;\n /**\n * share options\n * @since 0.1.0\n */\n shareDisclaimer?: DisclaimerOptions;\n /**\n * Toolbar type\n * @since 0.1.0\n * @default ToolBarType.DEFAULT\n */\n toolbarType?: ToolBarType;\n /**\n * Share subject\n * @since 0.1.0\n */\n shareSubject?: string;\n /**\n * Title of the browser\n * @since 0.1.0\n * @default 'New Window'\n */\n title?: string;\n /**\n * Background color of the browser, only on IOS\n * @since 0.1.0\n * @default BackgroundColor.BLACK\n */\n backgroundColor?: BackgroundColor;\n /**\n * If true, active the native navigation within the webview, Android only\n *\n * @default false\n */\n activeNativeNavigationForWebview?: boolean;\n /**\n * Disable the possibility to go back on native application,\n * usefull to force user to stay on the webview, Android only\n *\n * @default false\n */\n disableGoBackOnNativeApplication?: boolean;\n /**\n * Open url in a new window fullscreen\n *\n * isPresentAfterPageLoad: if true, the browser will be presented after the page is loaded, if false, the browser will be presented immediately.\n * @since 0.1.0\n * @default false\n */\n isPresentAfterPageLoad?: boolean;\n /**\n * Whether the website in the webview is inspectable or not, ios only\n *\n * @default false\n */\n isInspectable?: boolean;\n /**\n * Whether the webview opening is animated or not, ios only\n *\n * @default true\n */\n isAnimated?: boolean;\n /**\n * Shows a reload button that reloads the web page\n * @since 1.0.15\n * @default false\n */\n showReloadButton?: boolean;\n /**\n * CloseModal: if true a confirm will be displayed when user clicks on close button, if false the browser will be closed immediately.\n *\n * @since 1.1.0\n * @default false\n */\n closeModal?: boolean;\n /**\n * CloseModalTitle: title of the confirm when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Close'\n */\n closeModalTitle?: string;\n /**\n * CloseModalDescription: description of the confirm when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Are you sure you want to close this window?'\n */\n closeModalDescription?: string;\n /**\n * CloseModalOk: text of the confirm button when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Close'\n */\n closeModalOk?: string;\n /**\n * CloseModalCancel: text of the cancel button when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Cancel'\n */\n closeModalCancel?: string;\n /**\n * visibleTitle: if true the website title would be shown else shown empty\n *\n * @since 1.2.5\n * @default true\n */\n visibleTitle?: boolean;\n /**\n * toolbarColor: color of the toolbar in hex format\n *\n * @since 1.2.5\n * @default '#ffffff''\n */\n toolbarColor?: string;\n /**\n * showArrow: if true an arrow would be shown instead of cross for closing the window\n *\n * @since 1.2.5\n * @default false\n */\n showArrow?: boolean;\n /**\n * ignoreUntrustedSSLError: if true, the webview will ignore untrusted SSL errors allowing the user to view the website.\n *\n * @since 6.1.0\n * @default false\n */\n ignoreUntrustedSSLError?: boolean;\n /**\n * preShowScript: if isPresentAfterPageLoad is true and this variable is set the plugin will inject a script before showing the browser.\n * This script will be run in an async context. The plugin will wait for the script to finish (max 10 seconds)\n *\n * @since 6.6.0\n */\n preShowScript?: String;\n}\n\nexport interface InAppBrowserPlugin {\n /**\n * Open url in a new window fullscreen\n *\n * @since 0.1.0\n */\n open(options: OpenOptions): Promise<any>;\n\n /**\n * Clear cookies of url\n *\n * @since 0.5.0\n */\n clearCookies(options: ClearCookieOptions): Promise<any>;\n /**\n * Clear all cookies\n *\n * @since 6.5.0\n */\n clearAllCookies(): Promise<any>;\n\n /**\n * Clear cache\n *\n * @since 6.5.0\n */\n clearCache(): Promise<any>;\n\n /**\n * Get cookies for a specific URL.\n * @param options The options, including the URL to get cookies for.\n * @returns A promise that resolves with the cookies.\n */\n getCookies(options: GetCookieOptions): Promise<Record<string, string>>;\n /**\n * Close the webview.\n */\n close(): Promise<any>;\n /**\n * Open url in a new webview with toolbars\n *\n * @since 0.1.0\n */\n openWebView(options: OpenWebViewOptions): Promise<any>;\n /**\n * Injects JavaScript code into the InAppBrowser window.\n */\n executeScript({ code }: { code: string }): Promise<void>;\n /**\n * Sends an event to the webview. you can listen to this event with addListener(\"messageFromWebview\", listenerFunc: (event: Record<string, any>) => void)\n * detail is the data you want to send to the webview, it's a requirement of Capacitor we cannot send direct objects\n * Your object has to be serializable to JSON, so no functions or other non-JSON-serializable types are allowed.\n */\n postMessage(options: { detail: Record<string, any> }): Promise<void>;\n /**\n * Sets the URL of the webview.\n */\n setUrl(options: { url: string }): Promise<any>;\n /**\n * Listen for url change, only for openWebView\n *\n * @since 0.0.1\n */\n addListener(\n eventName: \"urlChangeEvent\",\n listenerFunc: UrlChangeListener,\n ): Promise<PluginListenerHandle>;\n\n /**\n * Listen for close click only for openWebView\n *\n * @since 0.4.0\n */\n addListener(\n eventName: \"closeEvent\",\n listenerFunc: UrlChangeListener,\n ): Promise<PluginListenerHandle>;\n /**\n * Will be triggered when user clicks on confirm button when disclaimer is required, works only on iOS\n *\n * @since 0.0.1\n */\n addListener(\n eventName: \"confirmBtnClicked\",\n listenerFunc: ConfirmBtnListener,\n ): Promise<PluginListenerHandle>;\n /**\n * Will be triggered when event is sent from webview, to send an event to the webview use window.mobileApp.postMessage({ \"detail\": { \"message\": \"myMessage\" } })\n * detail is the data you want to send to the webview, it's a requirement of Capacitor we cannot send direct objects\n * Your object has to be serializable to JSON, so no functions or other non-JSON-serializable types are allowed.\n *\n * This method is inject at runtime in the webview\n */\n addListener(\n eventName: \"messageFromWebview\",\n listenerFunc: (event: { detail: Record<string, any> }) => void,\n ): Promise<PluginListenerHandle>;\n\n /**\n * Will be triggered when page is loaded\n */\n addListener(\n eventName: \"browserPageLoaded\",\n listenerFunc: () => void,\n ): Promise<PluginListenerHandle>;\n\n /**\n * Will be triggered when page load error\n */\n addListener(\n eventName: \"pageLoadError\",\n listenerFunc: () => void,\n ): Promise<PluginListenerHandle>;\n /**\n * Remove all listeners for this plugin.\n *\n * @since 1.0.0\n */\n removeAllListeners(): Promise<void>;\n\n /**\n * Reload the current web page.\n *\n * @since 1.0.0\n */\n reload(): Promise<any>; // Add this line\n}\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAuBA,MAAM,CAAN,IAAY,eAGX;AAHD,WAAY,eAAe;IACzB,kCAAe,CAAA;IACf,kCAAe,CAAA;AACjB,CAAC,EAHW,eAAe,KAAf,eAAe,QAG1B;AACD,MAAM,CAAN,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,oCAAqB,CAAA;IACrB,wCAAyB,CAAA;IACzB,8BAAe,CAAA;IACf,2BAAY,CAAA;AACd,CAAC,EALW,WAAW,KAAX,WAAW,QAKtB","sourcesContent":["import type { PluginListenerHandle } from \"@capacitor/core\";\n\nexport interface UrlEvent {\n /**\n * Emit when the url changes\n *\n * @since 0.0.1\n */\n url: string;\n}\nexport interface BtnEvent {\n /**\n * Emit when a button is clicked.\n *\n * @since 0.0.1\n */\n url: string;\n}\n\nexport type UrlChangeListener = (state: UrlEvent) => void;\nexport type ConfirmBtnListener = (state: BtnEvent) => void;\nexport type ButtonNearListener = (state: {}) => void;\n\nexport enum BackgroundColor {\n WHITE = \"white\",\n BLACK = \"black\",\n}\nexport enum ToolBarType {\n ACTIVITY = \"activity\",\n NAVIGATION = \"navigation\",\n BLANK = \"blank\",\n DEFAULT = \"\",\n}\n\nexport interface Headers {\n [key: string]: string;\n}\n\nexport interface GetCookieOptions {\n url: string;\n includeHttpOnly?: boolean;\n}\n\nexport interface ClearCookieOptions {\n url: string;\n}\n\nexport interface Credentials {\n username: string;\n password: string;\n}\n\nexport interface OpenOptions {\n /**\n * Target URL to load.\n * @since 0.1.0\n */\n url: string;\n /**\n * Headers to send with the request.\n * @since 0.1.0\n */\n headers?: Headers;\n /**\n * Credentials to send with the request and all subsequent requests for the same host.\n * @since 6.1.0\n */\n credentials?: Credentials;\n /**\n * if true, the browser will be presented after the page is loaded, if false, the browser will be presented immediately.\n * @since 0.1.0\n */\n isPresentAfterPageLoad?: boolean;\n preventDeeplink?: boolean;\n}\n\nexport interface DisclaimerOptions {\n title: string;\n message: string;\n confirmBtn: string;\n cancelBtn: string;\n}\n\nexport interface OpenWebViewOptions {\n /**\n * Target URL to load.\n * @since 0.1.0\n */\n url: string;\n /**\n * Headers to send with the request.\n * @since 0.1.0\n */\n headers?: Headers;\n /**\n * Credentials to send with the request and all subsequent requests for the same host.\n * @since 6.1.0\n */\n credentials?: Credentials;\n /**\n * share options\n * @since 0.1.0\n */\n shareDisclaimer?: DisclaimerOptions;\n /**\n * Toolbar type\n * @since 0.1.0\n * @default ToolBarType.DEFAULT\n */\n toolbarType?: ToolBarType;\n /**\n * Share subject\n * @since 0.1.0\n */\n shareSubject?: string;\n /**\n * Title of the browser\n * @since 0.1.0\n * @default 'New Window'\n */\n title?: string;\n /**\n * Background color of the browser, only on IOS\n * @since 0.1.0\n * @default BackgroundColor.BLACK\n */\n backgroundColor?: BackgroundColor;\n /**\n * If true, active the native navigation within the webview, Android only\n *\n * @default false\n */\n activeNativeNavigationForWebview?: boolean;\n /**\n * Disable the possibility to go back on native application,\n * usefull to force user to stay on the webview, Android only\n *\n * @default false\n */\n disableGoBackOnNativeApplication?: boolean;\n /**\n * Open url in a new window fullscreen\n *\n * isPresentAfterPageLoad: if true, the browser will be presented after the page is loaded, if false, the browser will be presented immediately.\n * @since 0.1.0\n * @default false\n */\n isPresentAfterPageLoad?: boolean;\n /**\n * Whether the website in the webview is inspectable or not, ios only\n *\n * @default false\n */\n isInspectable?: boolean;\n /**\n * Whether the webview opening is animated or not, ios only\n *\n * @default true\n */\n isAnimated?: boolean;\n /**\n * Shows a reload button that reloads the web page\n * @since 1.0.15\n * @default false\n */\n showReloadButton?: boolean;\n /**\n * CloseModal: if true a confirm will be displayed when user clicks on close button, if false the browser will be closed immediately.\n *\n * @since 1.1.0\n * @default false\n */\n closeModal?: boolean;\n /**\n * CloseModalTitle: title of the confirm when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Close'\n */\n closeModalTitle?: string;\n /**\n * CloseModalDescription: description of the confirm when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Are you sure you want to close this window?'\n */\n closeModalDescription?: string;\n /**\n * CloseModalOk: text of the confirm button when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Close'\n */\n closeModalOk?: string;\n /**\n * CloseModalCancel: text of the cancel button when user clicks on close button, only on IOS\n *\n * @since 1.1.0\n * @default 'Cancel'\n */\n closeModalCancel?: string;\n /**\n * visibleTitle: if true the website title would be shown else shown empty\n *\n * @since 1.2.5\n * @default true\n */\n visibleTitle?: boolean;\n /**\n * toolbarColor: color of the toolbar in hex format\n *\n * @since 1.2.5\n * @default '#ffffff''\n */\n toolbarColor?: string;\n /**\n * showArrow: if true an arrow would be shown instead of cross for closing the window\n *\n * @since 1.2.5\n * @default false\n */\n showArrow?: boolean;\n /**\n * ignoreUntrustedSSLError: if true, the webview will ignore untrusted SSL errors allowing the user to view the website.\n *\n * @since 6.1.0\n * @default false\n */\n ignoreUntrustedSSLError?: boolean;\n /**\n * preShowScript: if isPresentAfterPageLoad is true and this variable is set the plugin will inject a script before showing the browser.\n * This script will be run in an async context. The plugin will wait for the script to finish (max 10 seconds)\n *\n * @since 6.6.0\n */\n preShowScript?: String;\n /**\n * buttonNearDone allows for a creation of a custom button. Please see [buttonNearDone.md](/buttonNearDone.md) for more info.\n *\n * @since 6.7.0\n */\n buttonNearDone?: {\n ios: {\n iconType: \"sf-symbol\" | \"asset\";\n icon: String;\n };\n android: {\n iconType: \"asset\";\n icon: String;\n width?: number;\n height?: number;\n };\n };\n}\n\nexport interface InAppBrowserPlugin {\n /**\n * Open url in a new window fullscreen\n *\n * @since 0.1.0\n */\n open(options: OpenOptions): Promise<any>;\n\n /**\n * Clear cookies of url\n *\n * @since 0.5.0\n */\n clearCookies(options: ClearCookieOptions): Promise<any>;\n /**\n * Clear all cookies\n *\n * @since 6.5.0\n */\n clearAllCookies(): Promise<any>;\n\n /**\n * Clear cache\n *\n * @since 6.5.0\n */\n clearCache(): Promise<any>;\n\n /**\n * Get cookies for a specific URL.\n * @param options The options, including the URL to get cookies for.\n * @returns A promise that resolves with the cookies.\n */\n getCookies(options: GetCookieOptions): Promise<Record<string, string>>;\n /**\n * Close the webview.\n */\n close(): Promise<any>;\n /**\n * Open url in a new webview with toolbars\n *\n * @since 0.1.0\n */\n openWebView(options: OpenWebViewOptions): Promise<any>;\n /**\n * Injects JavaScript code into the InAppBrowser window.\n */\n executeScript({ code }: { code: string }): Promise<void>;\n /**\n * Sends an event to the webview. you can listen to this event with addListener(\"messageFromWebview\", listenerFunc: (event: Record<string, any>) => void)\n * detail is the data you want to send to the webview, it's a requirement of Capacitor we cannot send direct objects\n * Your object has to be serializable to JSON, so no functions or other non-JSON-serializable types are allowed.\n */\n postMessage(options: { detail: Record<string, any> }): Promise<void>;\n /**\n * Sets the URL of the webview.\n */\n setUrl(options: { url: string }): Promise<any>;\n /**\n * Listen for url change, only for openWebView\n *\n * @since 0.0.1\n */\n addListener(\n eventName: \"urlChangeEvent\",\n listenerFunc: UrlChangeListener,\n ): Promise<PluginListenerHandle>;\n\n addListener(\n eventName: \"buttonNearDoneClick\",\n listenerFunc: ButtonNearListener,\n ): Promise<PluginListenerHandle>;\n\n /**\n * Listen for close click only for openWebView\n *\n * @since 0.4.0\n */\n addListener(\n eventName: \"closeEvent\",\n listenerFunc: UrlChangeListener,\n ): Promise<PluginListenerHandle>;\n /**\n * Will be triggered when user clicks on confirm button when disclaimer is required, works only on iOS\n *\n * @since 0.0.1\n */\n addListener(\n eventName: \"confirmBtnClicked\",\n listenerFunc: ConfirmBtnListener,\n ): Promise<PluginListenerHandle>;\n /**\n * Will be triggered when event is sent from webview, to send an event to the webview use window.mobileApp.postMessage({ \"detail\": { \"message\": \"myMessage\" } })\n * detail is the data you want to send to the webview, it's a requirement of Capacitor we cannot send direct objects\n * Your object has to be serializable to JSON, so no functions or other non-JSON-serializable types are allowed.\n *\n * This method is inject at runtime in the webview\n */\n addListener(\n eventName: \"messageFromWebview\",\n listenerFunc: (event: { detail: Record<string, any> }) => void,\n ): Promise<PluginListenerHandle>;\n\n /**\n * Will be triggered when page is loaded\n */\n addListener(\n eventName: \"browserPageLoaded\",\n listenerFunc: () => void,\n ): Promise<PluginListenerHandle>;\n\n /**\n * Will be triggered when page load error\n */\n addListener(\n eventName: \"pageLoadError\",\n listenerFunc: () => void,\n ): Promise<PluginListenerHandle>;\n /**\n * Remove all listeners for this plugin.\n *\n * @since 1.0.0\n */\n removeAllListeners(): Promise<void>;\n\n /**\n * Reload the current web page.\n *\n * @since 1.0.0\n */\n reload(): Promise<any>; // Add this line\n}\n"]}
@@ -138,6 +138,39 @@ public class InAppBrowserPlugin: CAPPlugin {
138
138
  return
139
139
  }
140
140
 
141
+ var buttonNearDoneIcon: UIImage?
142
+ if let buttonNearDoneSettings = call.getObject("buttonNearDone") {
143
+ guard let iosSettingsRaw = buttonNearDoneSettings["ios"] else {
144
+ call.reject("IOS settings not found")
145
+ return
146
+ }
147
+ if !(iosSettingsRaw is JSObject) {
148
+ call.reject("IOS settings are not an object")
149
+ return
150
+ }
151
+ let iosSettings = iosSettingsRaw as! JSObject
152
+
153
+ guard let iconType = iosSettings["iconType"] as? String else {
154
+ call.reject("buttonNearDone.iconType is empty")
155
+ return
156
+ }
157
+ if iconType != "sf-symbol" && iconType != "asset" {
158
+ call.reject("IconType is neither 'sf-symbol' nor 'asset'")
159
+ return
160
+ }
161
+ guard let icon = iosSettings["icon"] as? String else {
162
+ call.reject("buttonNearDone.icon is empty")
163
+ return
164
+ }
165
+
166
+ if iconType == "sf-symbol" {
167
+ buttonNearDoneIcon = UIImage(systemName: icon)
168
+ } else {
169
+ // UIImage(resource: ImageResource(name: "public/monkey.svg", bundle: Bundle.main))
170
+ buttonNearDoneIcon = UIImage(named: icon, in: Bundle.main, with: nil)
171
+ }
172
+ }
173
+
141
174
  let headers = call.getObject("headers", [:]).mapValues { String(describing: $0 as Any) }
142
175
  let closeModal = call.getBool("closeModal", false)
143
176
  let closeModalTitle = call.getString("closeModalTitle", "Close")
@@ -145,6 +178,7 @@ public class InAppBrowserPlugin: CAPPlugin {
145
178
  let closeModalOk = call.getString("closeModalOk", "OK")
146
179
  let closeModalCancel = call.getString("closeModalCancel", "Cancel")
147
180
  let isInspectable = call.getBool("isInspectable", false)
181
+ let preventDeeplink = call.getBool("preventDeeplink", false)
148
182
  let isAnimated = call.getBool("isAnimated", true)
149
183
 
150
184
  var disclaimerContent = call.getObject("shareDisclaimer")
@@ -164,11 +198,12 @@ public class InAppBrowserPlugin: CAPPlugin {
164
198
  let url = URL(string: urlString)
165
199
 
166
200
  if self.isPresentAfterPageLoad {
167
- self.webViewController = WKWebViewController.init(url: url!, headers: headers, isInspectable: isInspectable, credentials: credentials)
201
+ self.webViewController = WKWebViewController.init(url: url!, headers: headers, isInspectable: isInspectable, credentials: credentials, preventDeeplink: preventDeeplink)
168
202
  } else {
169
203
  self.webViewController = WKWebViewController.init()
170
204
  self.webViewController?.setHeaders(headers: headers)
171
205
  self.webViewController?.setCredentials(credentials: credentials)
206
+ self.webViewController?.setPreventDeeplink(preventDeeplink: preventDeeplink)
172
207
  }
173
208
 
174
209
  self.webViewController?.source = .remote(url!)
@@ -176,6 +211,9 @@ public class InAppBrowserPlugin: CAPPlugin {
176
211
  self.webViewController?.leftNavigationBarItemTypes = self.getToolbarItems(toolbarType: toolbarType)
177
212
  self.webViewController?.toolbarItemTypes = []
178
213
  self.webViewController?.doneBarButtonItemPosition = .right
214
+
215
+ self.webViewController?.buttonNearDoneIcon = buttonNearDoneIcon
216
+
179
217
  if call.getBool("showArrow", false) {
180
218
  self.webViewController?.stopBarButtonItemImage = UIImage(named: "Forward@3x", in: Bundle(for: InAppBrowserPlugin.self), compatibleWith: nil)
181
219
  }
@@ -290,6 +328,7 @@ public class InAppBrowserPlugin: CAPPlugin {
290
328
  }
291
329
 
292
330
  let isInspectable = call.getBool("isInspectable", false)
331
+ let preventDeeplink = call.getBool("preventDeeplink", false)
293
332
 
294
333
  self.currentPluginCall = call
295
334
 
@@ -313,11 +352,12 @@ public class InAppBrowserPlugin: CAPPlugin {
313
352
  let url = URL(string: urlString)
314
353
 
315
354
  if self.isPresentAfterPageLoad {
316
- self.webViewController = WKWebViewController.init(url: url!, headers: headers, isInspectable: isInspectable, credentials: credentials)
355
+ self.webViewController = WKWebViewController.init(url: url!, headers: headers, isInspectable: isInspectable, credentials: credentials, preventDeeplink: preventDeeplink)
317
356
  } else {
318
357
  self.webViewController = WKWebViewController.init()
319
358
  self.webViewController?.setHeaders(headers: headers)
320
359
  self.webViewController?.setCredentials(credentials: credentials)
360
+ self.webViewController?.setPreventDeeplink(preventDeeplink: preventDeeplink)
321
361
  }
322
362
 
323
363
  self.webViewController?.source = .remote(url!)
@@ -67,11 +67,12 @@ open class WKWebViewController: UIViewController, WKScriptMessageHandler {
67
67
  self.initWebview()
68
68
  }
69
69
 
70
- public init(url: URL, headers: [String: String], isInspectable: Bool, credentials: WKWebViewCredentials? = nil) {
70
+ public init(url: URL, headers: [String: String], isInspectable: Bool, credentials: WKWebViewCredentials? = nil, preventDeeplink: Bool) {
71
71
  super.init(nibName: nil, bundle: nil)
72
72
  self.source = .remote(url)
73
73
  self.credentials = credentials
74
74
  self.setHeaders(headers: headers)
75
+ self.setPreventDeeplink(preventDeeplink: preventDeeplink)
75
76
  self.initWebview(isInspectable: isInspectable)
76
77
  }
77
78
 
@@ -99,6 +100,7 @@ open class WKWebViewController: UIViewController, WKScriptMessageHandler {
99
100
  open var closeModalCancel = ""
100
101
  open var ignoreUntrustedSSLError = false
101
102
  var viewWasPresented = false
103
+ var preventDeeplink: Bool = false
102
104
 
103
105
  internal var preShowSemaphore: DispatchSemaphore?
104
106
  internal var preShowError: String?
@@ -115,6 +117,10 @@ open class WKWebViewController: UIViewController, WKScriptMessageHandler {
115
117
  }
116
118
  }
117
119
 
120
+ func setPreventDeeplink(preventDeeplink: Bool) {
121
+ self.preventDeeplink = preventDeeplink
122
+ }
123
+
118
124
  internal var customUserAgent: String? {
119
125
  didSet {
120
126
  guard let agent = userAgent else {
@@ -155,6 +161,8 @@ open class WKWebViewController: UIViewController, WKScriptMessageHandler {
155
161
  open var stopBarButtonItemImage: UIImage?
156
162
  open var activityBarButtonItemImage: UIImage?
157
163
 
164
+ open var buttonNearDoneIcon: UIImage?
165
+
158
166
  fileprivate var webView: WKWebView?
159
167
  fileprivate var progressView: UIProgressView?
160
168
 
@@ -274,7 +282,9 @@ open class WKWebViewController: UIViewController, WKScriptMessageHandler {
274
282
  };
275
283
  }
276
284
  """
277
- webView?.evaluateJavaScript(script, completionHandler: nil)
285
+ DispatchQueue.main.async {
286
+ self.webView?.evaluateJavaScript(script, completionHandler: nil)
287
+ }
278
288
  }
279
289
 
280
290
  open func initWebview(isInspectable: Bool = true) {
@@ -398,25 +408,28 @@ open class WKWebViewController: UIViewController, WKScriptMessageHandler {
398
408
  override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
399
409
  switch keyPath {
400
410
  case estimatedProgressKeyPath?:
401
- guard let estimatedProgress = self.webView?.estimatedProgress else {
402
- return
403
- }
404
- self.progressView?.alpha = 1
405
- self.progressView?.setProgress(Float(estimatedProgress), animated: true)
406
-
407
- if estimatedProgress >= 1.0 {
408
- UIView.animate(withDuration: 0.3, delay: 0.3, options: .curveEaseOut, animations: {
409
- self.progressView?.alpha = 0
410
- }, completion: {
411
- _ in
412
- self.progressView?.setProgress(0, animated: false)
413
- })
411
+ DispatchQueue.main.async {
412
+ guard let estimatedProgress = self.webView?.estimatedProgress else {
413
+ return
414
+ }
415
+ self.progressView?.alpha = 1
416
+ self.progressView?.setProgress(Float(estimatedProgress), animated: true)
417
+
418
+ if estimatedProgress >= 1.0 {
419
+ UIView.animate(withDuration: 0.3, delay: 0.3, options: .curveEaseOut, animations: {
420
+ self.progressView?.alpha = 0
421
+ }, completion: {
422
+ _ in
423
+ self.progressView?.setProgress(0, animated: false)
424
+ })
425
+ }
414
426
  }
415
427
  case titleKeyPath?:
416
428
  if self.hasDynamicTitle {
417
429
  self.navigationItem.title = webView?.url?.host
418
430
  }
419
431
  case "URL":
432
+
420
433
  self.capBrowserPlugin?.notifyListeners("urlChangeEvent", data: ["url": webView?.url?.absoluteString ?? ""])
421
434
  self.injectJavaScriptInterface()
422
435
  default:
@@ -440,7 +453,9 @@ public extension WKWebViewController {
440
453
  }
441
454
 
442
455
  func load(remote: URL) {
443
- webView?.load(createRequest(url: remote))
456
+ DispatchQueue.main.async {
457
+ self.webView?.load(self.createRequest(url: remote))
458
+ }
444
459
  }
445
460
 
446
461
  func load(file: URL, access: URL) {
@@ -583,13 +598,17 @@ fileprivate extension WKWebViewController {
583
598
  return UIBarButtonItem()
584
599
  }
585
600
 
586
- navigationItem.rightBarButtonItems = rightNavigaionBarItemTypes.map {
601
+ var rightBarButtons = rightNavigaionBarItemTypes.map {
587
602
  barButtonItemType in
588
603
  if let barButtonItem = barButtonItem(barButtonItemType) {
589
604
  return barButtonItem
590
605
  }
591
606
  return UIBarButtonItem()
592
607
  }
608
+ if rightBarButtons.count == 1 && buttonNearDoneIcon != nil && rightBarButtons[0] == doneBarButtonItem {
609
+ rightBarButtons.append(UIBarButtonItem(image: buttonNearDoneIcon, style: .plain, target: self, action: #selector(buttonNearDoneDidClick)))
610
+ }
611
+ navigationItem.rightBarButtonItems = rightBarButtons
593
612
 
594
613
  if toolbarItemTypes.count > 0 {
595
614
  for index in 0..<toolbarItemTypes.count - 1 {
@@ -597,13 +616,14 @@ fileprivate extension WKWebViewController {
597
616
  }
598
617
  }
599
618
 
600
- setToolbarItems(toolbarItemTypes.map {
619
+ let gen = toolbarItemTypes.map {
601
620
  barButtonItemType -> UIBarButtonItem in
602
621
  if let barButtonItem = barButtonItem(barButtonItemType) {
603
622
  return barButtonItem
604
623
  }
605
624
  return UIBarButtonItem()
606
- }, animated: true)
625
+ }
626
+ setToolbarItems(gen, animated: true)
607
627
  }
608
628
 
609
629
  func updateBarButtonItems() {
@@ -722,6 +742,10 @@ fileprivate extension WKWebViewController {
722
742
  webView?.goForward()
723
743
  }
724
744
 
745
+ @objc func buttonNearDoneDidClick(sender: AnyObject) {
746
+ self.capBrowserPlugin?.notifyListeners("buttonNearDoneClick", data: [:])
747
+ }
748
+
725
749
  @objc func reloadDidClick(sender: AnyObject) {
726
750
  webView?.stopLoading()
727
751
  if webView?.url != nil {
@@ -771,6 +795,7 @@ fileprivate extension WKWebViewController {
771
795
  self.present(alert, animated: true, completion: nil)
772
796
  } else {
773
797
  let activityViewController = UIActivityViewController(activityItems: items, applicationActivities: nil)
798
+ #imageLiteral(resourceName: "simulator_screenshot_B8B44B8D-EB30-425C-9BF4-1F37697A8459.png")
774
799
  activityViewController.setValue(self.shareSubject ?? self.title, forKey: "subject")
775
800
  activityViewController.popoverPresentationController?.barButtonItem = (sender as! UIBarButtonItem)
776
801
  self.present(activityViewController, animated: true, completion: nil)
@@ -946,6 +971,10 @@ extension WKWebViewController: WKNavigationDelegate {
946
971
  public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
947
972
  var actionPolicy: WKNavigationActionPolicy = .allow
948
973
 
974
+ if self.preventDeeplink {
975
+ actionPolicy = .preventDeeplinkActionPolicy
976
+ }
977
+
949
978
  defer {
950
979
  decisionHandler(actionPolicy)
951
980
  }
@@ -981,3 +1010,7 @@ class BlockBarButtonItem: UIBarButtonItem {
981
1010
 
982
1011
  var block: ((WKWebViewController) -> Void)?
983
1012
  }
1013
+
1014
+ extension WKNavigationActionPolicy {
1015
+ static let preventDeeplinkActionPolicy = WKNavigationActionPolicy(rawValue: WKNavigationActionPolicy.allow.rawValue + 2)!
1016
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/inappbrowser",
3
- "version": "6.6.7",
3
+ "version": "6.8.1",
4
4
  "description": "Capacitor plugin in app browser",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",