@capgo/capacitor-inappbrowser 8.16.6 → 8.17.0
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 +9 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/CapgoInAppBrowserPlugin.java +9 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/CloseButtonPositionSupport.java +35 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/Options.java +10 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/OrientationLayoutSupport.java +6 -2
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/SystemUiChromeSupport.java +11 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewDialog.java +102 -87
- package/dist/docs.json +36 -0
- package/dist/esm/definitions.d.ts +22 -0
- package/dist/esm/definitions.js +11 -0
- package/dist/esm/definitions.js.map +1 -1
- package/dist/plugin.cjs.js +11 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +11 -0
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/InAppBrowserPlugin/CloseButtonPositionSupport.swift +15 -0
- package/ios/Sources/InAppBrowserPlugin/InAppBrowserPlugin.swift +12 -1
- package/ios/Sources/InAppBrowserPlugin/WKWebViewController.swift +76 -76
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1606,6 +1606,7 @@ See the README section "openSecureWindow (OAuth)" for full setup examples.
|
|
|
1606
1606
|
| **`isAnimated`** | <code>boolean</code> | Whether the webview opening is animated or not, ios only | <code>true</code> | |
|
|
1607
1607
|
| **`showReloadButton`** | <code>boolean</code> | Shows a reload button that reloads the web page | <code>false</code> | 1.0.15 |
|
|
1608
1608
|
| **`closeAction`** | <code><a href="#closeaction">CloseAction</a></code> | closeAction controls what happens when the native toolbar close button is pressed. This does not change the behavior of close(), JavaScript window.mobileApp.close(), or native back navigation. | <code>CloseAction.CLOSE</code> | 8.7.7 |
|
|
1609
|
+
| **`closeButtonPosition`** | <code><a href="#closebuttonposition">CloseButtonPosition</a></code> | Where the native toolbar close button is placed. When omitted, each platform keeps its convention: Android places the close button at the start, iOS at the end (or at the start when `showArrow` is true). Setting this option overrides that placement on both platforms. | | 8.17.0 |
|
|
1609
1610
|
| **`screenshotOnHide`** | <code>boolean</code> | Captures the visible webview and includes it as `screenshot` in `hideEvent` before the toolbar close button hides the webview. Only applies when `closeAction` is <a href="#closeaction">`CloseAction.HIDE`</a>. On iOS, capture uses `WKWebView.takeSnapshot`. When testing through Apple's iPhone Mirroring app with the physical device locked, the snapshot can succeed with the correct dimensions but a fully transparent PNG. Capture works as expected on a normal unlocked device. This appears to be an Apple mirroring limitation rather than a plugin bug. | <code>false</code> | 8.7.10 |
|
|
1610
1611
|
| **`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 |
|
|
1611
1612
|
| **`closeModalTitle`** | <code>string</code> | CloseModalTitle: title of the confirm when user clicks on close button | <code>"Close"</code> | 1.1.0 |
|
|
@@ -2015,6 +2016,14 @@ Native handling mode used after a managed download finishes.
|
|
|
2015
2016
|
| **`HIDE`** | <code>'hide'</code> | The toolbar close button hides the webview so it can be shown again. |
|
|
2016
2017
|
|
|
2017
2018
|
|
|
2019
|
+
#### CloseButtonPosition
|
|
2020
|
+
|
|
2021
|
+
| Members | Value | Description |
|
|
2022
|
+
| ----------- | -------------------- | -------------------------------------------------------------- |
|
|
2023
|
+
| **`START`** | <code>'start'</code> | Leading edge of the toolbar (left in left-to-right layouts). |
|
|
2024
|
+
| **`END`** | <code>'end'</code> | Trailing edge of the toolbar (right in left-to-right layouts). |
|
|
2025
|
+
|
|
2026
|
+
|
|
2018
2027
|
#### InvisibilityMode
|
|
2019
2028
|
|
|
2020
2029
|
| Members | Value | Description |
|
|
@@ -1072,6 +1072,15 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
1072
1072
|
return;
|
|
1073
1073
|
}
|
|
1074
1074
|
options.setCloseAction(closeAction);
|
|
1075
|
+
String closeButtonPosition = call.getString("closeButtonPosition");
|
|
1076
|
+
if (closeButtonPosition != null) {
|
|
1077
|
+
closeButtonPosition = closeButtonPosition.toLowerCase(Locale.ROOT);
|
|
1078
|
+
if (CloseButtonPositionSupport.gravityFor(closeButtonPosition) == null) {
|
|
1079
|
+
call.reject("closeButtonPosition must be 'start' or 'end'");
|
|
1080
|
+
return;
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
options.setCloseButtonPosition(closeButtonPosition);
|
|
1075
1084
|
options.setTitleFontFamily(call.getString("titleFontFamily"));
|
|
1076
1085
|
JSObject titleIconObj = call.getObject("titleIcon");
|
|
1077
1086
|
if (titleIconObj != null) {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
package ee.forgr.capacitor_inappbrowser;
|
|
2
|
+
|
|
3
|
+
import android.view.Gravity;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Maps the {@code closeButtonPosition} option onto toolbar layout values.
|
|
7
|
+
*/
|
|
8
|
+
final class CloseButtonPositionSupport {
|
|
9
|
+
|
|
10
|
+
/** End padding that visually matches the start side's toolbar content inset. */
|
|
11
|
+
static final int END_PADDING_DP = 20;
|
|
12
|
+
|
|
13
|
+
private CloseButtonPositionSupport() {}
|
|
14
|
+
|
|
15
|
+
/** Toolbar gravity for the option value, or {@code null} to keep the layout default. */
|
|
16
|
+
static Integer gravityFor(String closeButtonPosition) {
|
|
17
|
+
if ("start".equals(closeButtonPosition)) {
|
|
18
|
+
return Gravity.START;
|
|
19
|
+
}
|
|
20
|
+
if ("end".equals(closeButtonPosition)) {
|
|
21
|
+
return Gravity.END;
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Keeps the layout's edge nudge pointing outwards for the resolved gravity.
|
|
28
|
+
* Resolves start/end against the layout direction so RTL mirrors correctly.
|
|
29
|
+
*/
|
|
30
|
+
static float mirroredTranslationX(int gravity, int layoutDirection, float translationX) {
|
|
31
|
+
int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
|
|
32
|
+
float outwards = Math.abs(translationX);
|
|
33
|
+
return absoluteGravity == Gravity.RIGHT ? outwards : -outwards;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -146,6 +146,7 @@ public class Options {
|
|
|
146
146
|
private String CloseModalCancel;
|
|
147
147
|
private ButtonNearDone buttonNearDone;
|
|
148
148
|
private String closeAction = "close";
|
|
149
|
+
private String closeButtonPosition;
|
|
149
150
|
private String titleFontFamily;
|
|
150
151
|
private ButtonNearDone titleIcon;
|
|
151
152
|
private String CloseModalOk;
|
|
@@ -466,6 +467,14 @@ public class Options {
|
|
|
466
467
|
this.closeAction = closeAction;
|
|
467
468
|
}
|
|
468
469
|
|
|
470
|
+
public String getCloseButtonPosition() {
|
|
471
|
+
return closeButtonPosition;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
public void setCloseButtonPosition(String closeButtonPosition) {
|
|
475
|
+
this.closeButtonPosition = closeButtonPosition;
|
|
476
|
+
}
|
|
477
|
+
|
|
469
478
|
public String getTitleFontFamily() {
|
|
470
479
|
return titleFontFamily;
|
|
471
480
|
}
|
|
@@ -834,6 +843,7 @@ public class Options {
|
|
|
834
843
|
copy.setCloseModalURLPattern(closeModalURLPattern);
|
|
835
844
|
copy.setButtonNearDone(buttonNearDone);
|
|
836
845
|
copy.setCloseAction(closeAction);
|
|
846
|
+
copy.setCloseButtonPosition(closeButtonPosition);
|
|
837
847
|
copy.setTitleFontFamily(titleFontFamily);
|
|
838
848
|
copy.setTitleIcon(titleIcon);
|
|
839
849
|
copy.setUrl("about:blank");
|
|
@@ -16,11 +16,13 @@ final class OrientationLayoutSupport {
|
|
|
16
16
|
Integer previousScreenHeightDp,
|
|
17
17
|
Integer previousSmallestScreenWidthDp,
|
|
18
18
|
Integer previousDensityDpi,
|
|
19
|
+
Integer previousUiMode,
|
|
19
20
|
int currentOrientation,
|
|
20
21
|
int currentScreenWidthDp,
|
|
21
22
|
int currentScreenHeightDp,
|
|
22
23
|
int currentSmallestScreenWidthDp,
|
|
23
|
-
int currentDensityDpi
|
|
24
|
+
int currentDensityDpi,
|
|
25
|
+
int currentUiMode
|
|
24
26
|
) {
|
|
25
27
|
if (previousOrientation == null) {
|
|
26
28
|
return true;
|
|
@@ -35,7 +37,9 @@ final class OrientationLayoutSupport {
|
|
|
35
37
|
previousSmallestScreenWidthDp == null ||
|
|
36
38
|
previousSmallestScreenWidthDp != currentSmallestScreenWidthDp ||
|
|
37
39
|
previousDensityDpi == null ||
|
|
38
|
-
previousDensityDpi != currentDensityDpi
|
|
40
|
+
previousDensityDpi != currentDensityDpi ||
|
|
41
|
+
previousUiMode == null ||
|
|
42
|
+
previousUiMode != currentUiMode
|
|
39
43
|
);
|
|
40
44
|
}
|
|
41
45
|
}
|
|
@@ -34,6 +34,17 @@ final class SystemUiChromeSupport {
|
|
|
34
34
|
return !edgeToEdge && shouldUsePreApi30LayoutFlags(sdkInt);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Color painted behind the browser content, visible in the system bar insets. Follows the toolbar
|
|
39
|
+
* color when one is set, otherwise the system theme, so the dialog theme's default never shows.
|
|
40
|
+
*/
|
|
41
|
+
static int resolveWindowBackgroundColor(Integer toolbarColor, boolean darkTheme) {
|
|
42
|
+
if (toolbarColor != null) {
|
|
43
|
+
return toolbarColor;
|
|
44
|
+
}
|
|
45
|
+
return darkTheme ? Color.BLACK : Color.WHITE;
|
|
46
|
+
}
|
|
47
|
+
|
|
37
48
|
static void setDecorFitsSystemWindows(Window window, boolean decorFitsSystemWindows) {
|
|
38
49
|
if (window == null) {
|
|
39
50
|
return;
|
|
@@ -2214,9 +2214,9 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
2214
2214
|
boolean isDarkBackground = isDarkColor(toolbarColor);
|
|
2215
2215
|
insetsController.setAppearanceLightStatusBars(!isDarkBackground);
|
|
2216
2216
|
} catch (IllegalArgumentException e) {
|
|
2217
|
-
|
|
2218
|
-
statusBarColorView.setBackgroundColor(
|
|
2219
|
-
insetsController.setAppearanceLightStatusBars(
|
|
2217
|
+
int fallbackColor = resolveWindowBackgroundColor();
|
|
2218
|
+
statusBarColorView.setBackgroundColor(fallbackColor);
|
|
2219
|
+
insetsController.setAppearanceLightStatusBars(!isDarkThemeEnabled());
|
|
2220
2220
|
}
|
|
2221
2221
|
} else {
|
|
2222
2222
|
// Follow system dark mode if no toolbar color provided
|
|
@@ -3450,6 +3450,7 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
3450
3450
|
Integer previousScreenHeightDp = lastConfiguration != null ? lastConfiguration.screenHeightDp : null;
|
|
3451
3451
|
Integer previousSmallestScreenWidthDp = lastConfiguration != null ? lastConfiguration.smallestScreenWidthDp : null;
|
|
3452
3452
|
Integer previousDensityDpi = lastConfiguration != null ? lastConfiguration.densityDpi : null;
|
|
3453
|
+
Integer previousUiMode = lastConfiguration != null ? lastConfiguration.uiMode : null;
|
|
3453
3454
|
|
|
3454
3455
|
int currentOrientation = newConfig != null ? newConfig.orientation : (previousOrientation != null ? previousOrientation : 0);
|
|
3455
3456
|
int currentScreenWidthDp =
|
|
@@ -3461,6 +3462,7 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
3461
3462
|
? newConfig.smallestScreenWidthDp
|
|
3462
3463
|
: (previousSmallestScreenWidthDp != null ? previousSmallestScreenWidthDp : 0);
|
|
3463
3464
|
int currentDensityDpi = newConfig != null ? newConfig.densityDpi : (previousDensityDpi != null ? previousDensityDpi : 0);
|
|
3465
|
+
int currentUiMode = newConfig != null ? newConfig.uiMode : (previousUiMode != null ? previousUiMode : 0);
|
|
3464
3466
|
|
|
3465
3467
|
boolean shouldRefresh = OrientationLayoutSupport.shouldRefreshBrowserLayout(
|
|
3466
3468
|
previousOrientation,
|
|
@@ -3468,11 +3470,13 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
3468
3470
|
previousScreenHeightDp,
|
|
3469
3471
|
previousSmallestScreenWidthDp,
|
|
3470
3472
|
previousDensityDpi,
|
|
3473
|
+
previousUiMode,
|
|
3471
3474
|
currentOrientation,
|
|
3472
3475
|
currentScreenWidthDp,
|
|
3473
3476
|
currentScreenHeightDp,
|
|
3474
3477
|
currentSmallestScreenWidthDp,
|
|
3475
|
-
currentDensityDpi
|
|
3478
|
+
currentDensityDpi,
|
|
3479
|
+
currentUiMode
|
|
3476
3480
|
);
|
|
3477
3481
|
|
|
3478
3482
|
if (newConfig != null) {
|
|
@@ -3513,6 +3517,7 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
3513
3517
|
}
|
|
3514
3518
|
|
|
3515
3519
|
ensureContentBrowserMatchParentHeight();
|
|
3520
|
+
applyWindowBackgroundColor();
|
|
3516
3521
|
|
|
3517
3522
|
boolean isBlankToolbar = _options != null && TextUtils.equals(_options.getToolbarType(), "blank");
|
|
3518
3523
|
if (isBlankToolbar) {
|
|
@@ -3599,18 +3604,7 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
3599
3604
|
appBarLayout.setStateListAnimator(null);
|
|
3600
3605
|
appBarLayout.setOutlineProvider(null);
|
|
3601
3606
|
|
|
3602
|
-
int
|
|
3603
|
-
if (_options.getToolbarColor() != null && !_options.getToolbarColor().isEmpty()) {
|
|
3604
|
-
try {
|
|
3605
|
-
backgroundColor = Color.parseColor(_options.getToolbarColor());
|
|
3606
|
-
} catch (IllegalArgumentException e) {
|
|
3607
|
-
Log.e("InAppBrowser", "Invalid toolbar color, using black: " + e.getMessage());
|
|
3608
|
-
}
|
|
3609
|
-
} else {
|
|
3610
|
-
backgroundColor = isDarkThemeEnabled() ? Color.BLACK : Color.WHITE;
|
|
3611
|
-
}
|
|
3612
|
-
|
|
3613
|
-
final int finalBgColor = backgroundColor;
|
|
3607
|
+
final int finalBgColor = resolveWindowBackgroundColor();
|
|
3614
3608
|
_webView.post(() -> {
|
|
3615
3609
|
if (_webView == null) {
|
|
3616
3610
|
return;
|
|
@@ -3630,6 +3624,12 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
3630
3624
|
|
|
3631
3625
|
applyAppBarTopInset(appBarLayout, appBarHandlesTopInset(toolbarView) ? statusBarHeight : 0);
|
|
3632
3626
|
appBarLayout.setBackgroundColor(finalBgColor);
|
|
3627
|
+
|
|
3628
|
+
Window window = getWindow();
|
|
3629
|
+
if (window != null) {
|
|
3630
|
+
WindowInsetsControllerCompat insetsController = new WindowInsetsControllerCompat(window, window.getDecorView());
|
|
3631
|
+
insetsController.setAppearanceLightStatusBars(!isDarkColor(finalBgColor));
|
|
3632
|
+
}
|
|
3633
3633
|
});
|
|
3634
3634
|
}
|
|
3635
3635
|
|
|
@@ -3874,6 +3874,29 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
3874
3874
|
}
|
|
3875
3875
|
}
|
|
3876
3876
|
|
|
3877
|
+
private int resolveWindowBackgroundColor() {
|
|
3878
|
+
Integer toolbarColor = null;
|
|
3879
|
+
if (_options.getToolbarColor() != null && !_options.getToolbarColor().isEmpty()) {
|
|
3880
|
+
try {
|
|
3881
|
+
toolbarColor = Color.parseColor(_options.getToolbarColor());
|
|
3882
|
+
} catch (IllegalArgumentException e) {
|
|
3883
|
+
Log.e("InAppBrowser", "Invalid toolbar color, using theme default: " + e.getMessage());
|
|
3884
|
+
}
|
|
3885
|
+
}
|
|
3886
|
+
return SystemUiChromeSupport.resolveWindowBackgroundColor(toolbarColor, isDarkThemeEnabled());
|
|
3887
|
+
}
|
|
3888
|
+
|
|
3889
|
+
private void applyWindowBackgroundColor() {
|
|
3890
|
+
// Custom dimensions keep the window transparent for touch passthrough
|
|
3891
|
+
if (_options.getWidth() != null || _options.getHeight() != null) {
|
|
3892
|
+
return;
|
|
3893
|
+
}
|
|
3894
|
+
Window window = getWindow();
|
|
3895
|
+
if (window != null) {
|
|
3896
|
+
window.getDecorView().setBackgroundColor(resolveWindowBackgroundColor());
|
|
3897
|
+
}
|
|
3898
|
+
}
|
|
3899
|
+
|
|
3877
3900
|
private int getSystemStatusBarHeight() {
|
|
3878
3901
|
int resourceId = getContext().getResources().getIdentifier("status_bar_height", "dimen", "android");
|
|
3879
3902
|
if (resourceId <= 0) {
|
|
@@ -4951,62 +4974,85 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
4951
4974
|
|
|
4952
4975
|
private void setupToolbar() {
|
|
4953
4976
|
_toolbar = findViewById(R.id.tool_bar);
|
|
4977
|
+
applyWindowBackgroundColor();
|
|
4954
4978
|
|
|
4955
4979
|
// Apply toolbar color early, for ALL toolbar types, before any view configuration
|
|
4956
4980
|
if (_options.getToolbarColor() != null && !_options.getToolbarColor().isEmpty()) {
|
|
4981
|
+
int toolbarColor;
|
|
4957
4982
|
try {
|
|
4958
|
-
|
|
4959
|
-
|
|
4983
|
+
toolbarColor = Color.parseColor(_options.getToolbarColor());
|
|
4984
|
+
} catch (IllegalArgumentException e) {
|
|
4985
|
+
Log.e("InAppBrowser", "Invalid toolbar color, using theme default: " + e.getMessage());
|
|
4986
|
+
toolbarColor = resolveWindowBackgroundColor();
|
|
4987
|
+
}
|
|
4960
4988
|
|
|
4961
|
-
|
|
4962
|
-
TextView titleText = _toolbar.findViewById(R.id.titleText);
|
|
4989
|
+
_toolbar.setBackgroundColor(toolbarColor);
|
|
4963
4990
|
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
cachedTitleIconResolved = false;
|
|
4991
|
+
// Get toolbar title and ensure it gets the right color
|
|
4992
|
+
TextView titleText = _toolbar.findViewById(R.id.titleText);
|
|
4967
4993
|
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
// No explicit toolbarTextColor, use automatic detection based on background
|
|
4994
|
+
// Determine icon and text color
|
|
4995
|
+
cachedTitleIconDrawable = null;
|
|
4996
|
+
cachedTitleIconResolved = false;
|
|
4997
|
+
|
|
4998
|
+
int iconColor;
|
|
4999
|
+
if (_options.getToolbarTextColor() != null && !_options.getToolbarTextColor().isEmpty()) {
|
|
5000
|
+
try {
|
|
5001
|
+
iconColor = Color.parseColor(_options.getToolbarTextColor());
|
|
5002
|
+
} catch (IllegalArgumentException e) {
|
|
5003
|
+
// Fallback to automatic detection if parsing fails
|
|
4979
5004
|
boolean isDarkBackground = isDarkColor(toolbarColor);
|
|
4980
5005
|
iconColor = isDarkBackground ? Color.WHITE : Color.BLACK;
|
|
4981
5006
|
}
|
|
5007
|
+
} else {
|
|
5008
|
+
// No explicit toolbarTextColor, use automatic detection based on background
|
|
5009
|
+
boolean isDarkBackground = isDarkColor(toolbarColor);
|
|
5010
|
+
iconColor = isDarkBackground ? Color.WHITE : Color.BLACK;
|
|
5011
|
+
}
|
|
4982
5012
|
|
|
4983
|
-
|
|
4984
|
-
|
|
5013
|
+
// Store for later use with navigation buttons
|
|
5014
|
+
this.iconColor = iconColor;
|
|
4985
5015
|
|
|
4986
|
-
|
|
4987
|
-
|
|
5016
|
+
// Set title text color directly
|
|
5017
|
+
titleText.setTextColor(iconColor);
|
|
4988
5018
|
|
|
4989
|
-
|
|
4990
|
-
|
|
5019
|
+
// Apply colors to all buttons
|
|
5020
|
+
applyColorToAllButtons(toolbarColor, iconColor);
|
|
4991
5021
|
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
5022
|
+
// Also ensure status bar gets the color
|
|
5023
|
+
if (getWindow() != null) {
|
|
5024
|
+
SystemUiChromeSupport.applyLegacyStatusBarColorViaView(findViewById(R.id.status_bar_color_view), toolbarColor);
|
|
4995
5025
|
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
getWindow().getDecorView()
|
|
5001
|
-
);
|
|
5002
|
-
insetsController.setAppearanceLightStatusBars(!isDarkBackground);
|
|
5003
|
-
}
|
|
5004
|
-
} catch (IllegalArgumentException e) {
|
|
5005
|
-
Log.e("InAppBrowser", "Invalid toolbar color: " + _options.getToolbarColor());
|
|
5026
|
+
// Determine proper status bar text color (light or dark icons)
|
|
5027
|
+
boolean isDarkBackground = isDarkColor(toolbarColor);
|
|
5028
|
+
WindowInsetsControllerCompat insetsController = new WindowInsetsControllerCompat(getWindow(), getWindow().getDecorView());
|
|
5029
|
+
insetsController.setAppearanceLightStatusBars(!isDarkBackground);
|
|
5006
5030
|
}
|
|
5007
5031
|
}
|
|
5008
5032
|
|
|
5009
5033
|
ImageButton closeButtonView = _toolbar.findViewById(R.id.closeButton);
|
|
5034
|
+
Integer closeButtonGravity = CloseButtonPositionSupport.gravityFor(_options.getCloseButtonPosition());
|
|
5035
|
+
if (closeButtonGravity != null && closeButtonView.getLayoutParams() instanceof Toolbar.LayoutParams closeButtonParams) {
|
|
5036
|
+
int verticalGravity = closeButtonParams.gravity & Gravity.VERTICAL_GRAVITY_MASK;
|
|
5037
|
+
closeButtonParams.gravity = verticalGravity | closeButtonGravity;
|
|
5038
|
+
closeButtonView.setLayoutParams(closeButtonParams);
|
|
5039
|
+
closeButtonView.setTranslationX(
|
|
5040
|
+
CloseButtonPositionSupport.mirroredTranslationX(
|
|
5041
|
+
closeButtonGravity,
|
|
5042
|
+
_context.getResources().getConfiguration().getLayoutDirection(),
|
|
5043
|
+
closeButtonView.getTranslationX()
|
|
5044
|
+
)
|
|
5045
|
+
);
|
|
5046
|
+
// Toolbar only insets the start edge; pad the logical end so the icon keeps clear of the screen edge
|
|
5047
|
+
if (closeButtonGravity == Gravity.END) {
|
|
5048
|
+
closeButtonView.setPaddingRelative(
|
|
5049
|
+
closeButtonView.getPaddingStart(),
|
|
5050
|
+
closeButtonView.getPaddingTop(),
|
|
5051
|
+
(int) getPixels(CloseButtonPositionSupport.END_PADDING_DP),
|
|
5052
|
+
closeButtonView.getPaddingBottom()
|
|
5053
|
+
);
|
|
5054
|
+
}
|
|
5055
|
+
}
|
|
5010
5056
|
closeButtonView.setOnClickListener(
|
|
5011
5057
|
new View.OnClickListener() {
|
|
5012
5058
|
@Override
|
|
@@ -5110,41 +5156,10 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
5110
5156
|
configureBlankToolbarLayout();
|
|
5111
5157
|
requestSafeAreaInsets();
|
|
5112
5158
|
|
|
5113
|
-
//
|
|
5159
|
+
// Without a toolbar the status bar view is the only chrome, so it follows the window color
|
|
5114
5160
|
View statusBarColorView = findViewById(R.id.status_bar_color_view);
|
|
5115
|
-
if (
|
|
5116
|
-
|
|
5117
|
-
int toolbarColor = Color.parseColor(_options.getToolbarColor());
|
|
5118
|
-
if (getWindow() != null) {
|
|
5119
|
-
getWindow().getDecorView().setBackgroundColor(toolbarColor);
|
|
5120
|
-
}
|
|
5121
|
-
// Also set status bar color view background if available
|
|
5122
|
-
if (statusBarColorView != null) {
|
|
5123
|
-
statusBarColorView.setBackgroundColor(toolbarColor);
|
|
5124
|
-
}
|
|
5125
|
-
} catch (IllegalArgumentException e) {
|
|
5126
|
-
// Fallback to system default if color parsing fails
|
|
5127
|
-
boolean isDarkTheme = isDarkThemeEnabled();
|
|
5128
|
-
int windowBackgroundColor = isDarkTheme ? Color.BLACK : Color.WHITE;
|
|
5129
|
-
if (getWindow() != null) {
|
|
5130
|
-
getWindow().getDecorView().setBackgroundColor(windowBackgroundColor);
|
|
5131
|
-
}
|
|
5132
|
-
// Also set status bar color view background if available
|
|
5133
|
-
if (statusBarColorView != null) {
|
|
5134
|
-
statusBarColorView.setBackgroundColor(windowBackgroundColor);
|
|
5135
|
-
}
|
|
5136
|
-
}
|
|
5137
|
-
} else {
|
|
5138
|
-
// Follow system dark mode
|
|
5139
|
-
boolean isDarkTheme = isDarkThemeEnabled();
|
|
5140
|
-
int windowBackgroundColor = isDarkTheme ? Color.BLACK : Color.WHITE;
|
|
5141
|
-
if (getWindow() != null) {
|
|
5142
|
-
getWindow().getDecorView().setBackgroundColor(windowBackgroundColor);
|
|
5143
|
-
}
|
|
5144
|
-
// Also set status bar color view background if available
|
|
5145
|
-
if (statusBarColorView != null) {
|
|
5146
|
-
statusBarColorView.setBackgroundColor(windowBackgroundColor);
|
|
5147
|
-
}
|
|
5161
|
+
if (statusBarColorView != null) {
|
|
5162
|
+
statusBarColorView.setBackgroundColor(resolveWindowBackgroundColor());
|
|
5148
5163
|
}
|
|
5149
5164
|
} else {
|
|
5150
5165
|
_toolbar.findViewById(R.id.forwardButton).setVisibility(View.GONE);
|
package/dist/docs.json
CHANGED
|
@@ -1954,6 +1954,24 @@
|
|
|
1954
1954
|
],
|
|
1955
1955
|
"type": "CloseAction"
|
|
1956
1956
|
},
|
|
1957
|
+
{
|
|
1958
|
+
"name": "closeButtonPosition",
|
|
1959
|
+
"tags": [
|
|
1960
|
+
{
|
|
1961
|
+
"text": "8.17.0",
|
|
1962
|
+
"name": "since"
|
|
1963
|
+
},
|
|
1964
|
+
{
|
|
1965
|
+
"text": "closeButtonPosition: CloseButtonPosition.END",
|
|
1966
|
+
"name": "example"
|
|
1967
|
+
}
|
|
1968
|
+
],
|
|
1969
|
+
"docs": "Where the native toolbar close button is placed.\n\nWhen omitted, each platform keeps its convention: Android places the close button at the\nstart, iOS at the end (or at the start when `showArrow` is true). Setting this option\noverrides that placement on both platforms.",
|
|
1970
|
+
"complexTypes": [
|
|
1971
|
+
"CloseButtonPosition"
|
|
1972
|
+
],
|
|
1973
|
+
"type": "CloseButtonPosition"
|
|
1974
|
+
},
|
|
1957
1975
|
{
|
|
1958
1976
|
"name": "screenshotOnHide",
|
|
1959
1977
|
"tags": [
|
|
@@ -3654,6 +3672,24 @@
|
|
|
3654
3672
|
}
|
|
3655
3673
|
]
|
|
3656
3674
|
},
|
|
3675
|
+
{
|
|
3676
|
+
"name": "CloseButtonPosition",
|
|
3677
|
+
"slug": "closebuttonposition",
|
|
3678
|
+
"members": [
|
|
3679
|
+
{
|
|
3680
|
+
"name": "START",
|
|
3681
|
+
"value": "'start'",
|
|
3682
|
+
"tags": [],
|
|
3683
|
+
"docs": "Leading edge of the toolbar (left in left-to-right layouts)."
|
|
3684
|
+
},
|
|
3685
|
+
{
|
|
3686
|
+
"name": "END",
|
|
3687
|
+
"value": "'end'",
|
|
3688
|
+
"tags": [],
|
|
3689
|
+
"docs": "Trailing edge of the toolbar (right in left-to-right layouts)."
|
|
3690
|
+
}
|
|
3691
|
+
]
|
|
3692
|
+
},
|
|
3657
3693
|
{
|
|
3658
3694
|
"name": "InvisibilityMode",
|
|
3659
3695
|
"slug": "invisibilitymode",
|
|
@@ -105,6 +105,16 @@ export declare enum CloseAction {
|
|
|
105
105
|
*/
|
|
106
106
|
HIDE = "hide"
|
|
107
107
|
}
|
|
108
|
+
export declare enum CloseButtonPosition {
|
|
109
|
+
/**
|
|
110
|
+
* Leading edge of the toolbar (left in left-to-right layouts).
|
|
111
|
+
*/
|
|
112
|
+
START = "start",
|
|
113
|
+
/**
|
|
114
|
+
* Trailing edge of the toolbar (right in left-to-right layouts).
|
|
115
|
+
*/
|
|
116
|
+
END = "end"
|
|
117
|
+
}
|
|
108
118
|
export interface ToolbarTitleIconOptions {
|
|
109
119
|
ios?: {
|
|
110
120
|
iconType: 'sf-symbol' | 'asset';
|
|
@@ -975,6 +985,18 @@ export interface OpenWebViewOptions {
|
|
|
975
985
|
* closeAction: CloseAction.HIDE
|
|
976
986
|
*/
|
|
977
987
|
closeAction?: CloseAction;
|
|
988
|
+
/**
|
|
989
|
+
* Where the native toolbar close button is placed.
|
|
990
|
+
*
|
|
991
|
+
* When omitted, each platform keeps its convention: Android places the close button at the
|
|
992
|
+
* start, iOS at the end (or at the start when `showArrow` is true). Setting this option
|
|
993
|
+
* overrides that placement on both platforms.
|
|
994
|
+
*
|
|
995
|
+
* @since 8.17.0
|
|
996
|
+
* @example
|
|
997
|
+
* closeButtonPosition: CloseButtonPosition.END
|
|
998
|
+
*/
|
|
999
|
+
closeButtonPosition?: CloseButtonPosition;
|
|
978
1000
|
/**
|
|
979
1001
|
* Captures the visible webview and includes it as `screenshot` in `hideEvent`
|
|
980
1002
|
* before the toolbar close button hides the webview.
|
package/dist/esm/definitions.js
CHANGED
|
@@ -48,4 +48,15 @@ export var CloseAction;
|
|
|
48
48
|
*/
|
|
49
49
|
CloseAction["HIDE"] = "hide";
|
|
50
50
|
})(CloseAction || (CloseAction = {}));
|
|
51
|
+
export var CloseButtonPosition;
|
|
52
|
+
(function (CloseButtonPosition) {
|
|
53
|
+
/**
|
|
54
|
+
* Leading edge of the toolbar (left in left-to-right layouts).
|
|
55
|
+
*/
|
|
56
|
+
CloseButtonPosition["START"] = "start";
|
|
57
|
+
/**
|
|
58
|
+
* Trailing edge of the toolbar (right in left-to-right layouts).
|
|
59
|
+
*/
|
|
60
|
+
CloseButtonPosition["END"] = "end";
|
|
61
|
+
})(CloseButtonPosition || (CloseButtonPosition = {}));
|
|
51
62
|
//# sourceMappingURL=definitions.js.map
|