@capgo/capacitor-inappbrowser 8.16.3 → 8.16.5
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/android/build.gradle +7 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/CapgoInAppBrowserPlugin.java +10 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/SystemUiChromeSupport.java +10 -19
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewBackNavigationSupport.java +33 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewCustomFullscreenSupport.java +26 -15
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewDialog.java +75 -16
- package/ios/Sources/InAppBrowserPlugin/InAppBrowserPlugin.swift +1 -1
- package/ios/Sources/InAppBrowserPlugin/WKWebView+SchemeHandling.swift +13 -1
- package/package.json +1 -1
package/android/build.gradle
CHANGED
|
@@ -34,6 +34,11 @@ android {
|
|
|
34
34
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
testOptions {
|
|
38
|
+
unitTests {
|
|
39
|
+
includeAndroidResources = true
|
|
40
|
+
}
|
|
41
|
+
}
|
|
37
42
|
lintOptions {
|
|
38
43
|
abortOnError = false
|
|
39
44
|
}
|
|
@@ -56,6 +61,8 @@ dependencies {
|
|
|
56
61
|
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
|
57
62
|
implementation "androidx.window:window:1.5.1"
|
|
58
63
|
testImplementation "junit:junit:$junitVersion"
|
|
64
|
+
testImplementation 'org.robolectric:robolectric:4.14.1'
|
|
65
|
+
testImplementation 'androidx.activity:activity:1.10.1'
|
|
59
66
|
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
|
60
67
|
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
|
61
68
|
implementation "androidx.browser:browser:$androidxBrowserVersion"
|
|
@@ -428,12 +428,21 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
428
428
|
webViewStack.addLast(id);
|
|
429
429
|
if (makeActive || activeWebViewId == null || webViewDialog == null) {
|
|
430
430
|
setActiveWebView(id, dialog);
|
|
431
|
+
} else {
|
|
432
|
+
dialog.setActiveForBackNavigation(false);
|
|
431
433
|
}
|
|
432
434
|
}
|
|
433
435
|
|
|
434
436
|
private void setActiveWebView(String id, WebViewDialog dialog) {
|
|
435
437
|
activeWebViewId = id;
|
|
436
438
|
webViewDialog = dialog;
|
|
439
|
+
syncActiveWebViewBackNavigation();
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
private void syncActiveWebViewBackNavigation() {
|
|
443
|
+
for (Map.Entry<String, WebViewDialog> entry : webViewDialogs.entrySet()) {
|
|
444
|
+
entry.getValue().setActiveForBackNavigation(java.util.Objects.equals(entry.getKey(), activeWebViewId));
|
|
445
|
+
}
|
|
437
446
|
}
|
|
438
447
|
|
|
439
448
|
private void unregisterWebView(String id) {
|
|
@@ -441,6 +450,7 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
441
450
|
webViewStack.remove(id);
|
|
442
451
|
activeWebViewId = webViewStack.peekLast();
|
|
443
452
|
webViewDialog = activeWebViewId != null ? webViewDialogs.get(activeWebViewId) : null;
|
|
453
|
+
syncActiveWebViewBackNavigation();
|
|
444
454
|
if (webViewDialog != null) {
|
|
445
455
|
String url = webViewDialog.getUrl();
|
|
446
456
|
if (url != null) {
|
|
@@ -41,14 +41,14 @@ final class SystemUiChromeSupport {
|
|
|
41
41
|
WindowCompat.setDecorFitsSystemWindows(window, decorFitsSystemWindows);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
static void prepareInitialDialogWindow(Window window) {
|
|
44
|
+
static void prepareInitialDialogWindow(Window window, View statusBarColorView) {
|
|
45
45
|
if (window == null) {
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
|
50
50
|
if (shouldApplyLegacySystemBarColors(Build.VERSION.SDK_INT)) {
|
|
51
|
-
|
|
51
|
+
applyLegacyStatusBarColorViaView(statusBarColorView, Color.TRANSPARENT);
|
|
52
52
|
clearLegacyTranslucentStatusFlag(window);
|
|
53
53
|
}
|
|
54
54
|
}
|
|
@@ -56,9 +56,9 @@ final class SystemUiChromeSupport {
|
|
|
56
56
|
static void applyDialogWindowChrome(
|
|
57
57
|
Window window,
|
|
58
58
|
View decorView,
|
|
59
|
+
View statusBarColorView,
|
|
59
60
|
boolean edgeToEdge,
|
|
60
61
|
Integer statusBarColor,
|
|
61
|
-
Integer navigationBarColor,
|
|
62
62
|
Boolean lightStatusBars
|
|
63
63
|
) {
|
|
64
64
|
if (window == null || decorView == null) {
|
|
@@ -69,10 +69,10 @@ final class SystemUiChromeSupport {
|
|
|
69
69
|
setDecorFitsSystemWindows(window, false);
|
|
70
70
|
} else if (!shouldUsePreApi30LayoutFlags(Build.VERSION.SDK_INT)) {
|
|
71
71
|
setDecorFitsSystemWindows(window, true);
|
|
72
|
-
|
|
72
|
+
applyLegacyStatusBarColorViaView(statusBarColorView, statusBarColor);
|
|
73
73
|
} else {
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
setDecorFitsSystemWindows(window, false);
|
|
75
|
+
applyLegacyStatusBarColorViaView(statusBarColorView, statusBarColor);
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(window, decorView);
|
|
@@ -81,22 +81,13 @@ final class SystemUiChromeSupport {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
@SuppressWarnings("deprecation")
|
|
90
|
-
static void applyLegacySystemBarColors(Window window, Integer statusBarColor, Integer navigationBarColor) {
|
|
91
|
-
if (window == null || !shouldApplyLegacySystemBarColors(Build.VERSION.SDK_INT)) {
|
|
84
|
+
static void applyLegacyStatusBarColorViaView(View statusBarColorView, Integer statusBarColor) {
|
|
85
|
+
if (!shouldApplyLegacySystemBarColors(Build.VERSION.SDK_INT)) {
|
|
92
86
|
return;
|
|
93
87
|
}
|
|
94
88
|
|
|
95
|
-
if (statusBarColor != null &&
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
if (navigationBarColor != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
99
|
-
window.setNavigationBarColor(navigationBarColor);
|
|
89
|
+
if (statusBarColor != null && statusBarColorView != null) {
|
|
90
|
+
statusBarColorView.setBackgroundColor(statusBarColor);
|
|
100
91
|
}
|
|
101
92
|
}
|
|
102
93
|
|
package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewBackNavigationSupport.java
CHANGED
|
@@ -22,6 +22,39 @@ final class WebViewBackNavigationSupport {
|
|
|
22
22
|
return isShowing && !hiddenMode && !backLayerActive;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* When {@code disableGoBackOnNativeApplication} is true, the dialog must not be cancelable on
|
|
27
|
+
* back/gesture. Otherwise {@link androidx.activity.ComponentDialog}'s built-in back callback
|
|
28
|
+
* dismisses the dialog before our handler can return {@link Action#IGNORE}.
|
|
29
|
+
*/
|
|
30
|
+
static boolean isCancelableOnBack(boolean disableGoBackOnNativeApplication) {
|
|
31
|
+
return !disableGoBackOnNativeApplication;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Activity-level back handling is required when the overlay is hosted on the activity window
|
|
36
|
+
* (back layer) or when predictive-back can bypass the dialog dispatcher while the flag blocks
|
|
37
|
+
* dismiss.
|
|
38
|
+
*/
|
|
39
|
+
static boolean shouldRegisterActivityBackHandler(
|
|
40
|
+
boolean isShowing,
|
|
41
|
+
boolean backLayerActive,
|
|
42
|
+
boolean hiddenMode,
|
|
43
|
+
boolean disableGoBackOnNativeApplication,
|
|
44
|
+
boolean isActiveForBackNavigation
|
|
45
|
+
) {
|
|
46
|
+
if (!isActiveForBackNavigation) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
if (hiddenMode) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
if (!isShowing && !backLayerActive) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return backLayerActive || disableGoBackOnNativeApplication;
|
|
56
|
+
}
|
|
57
|
+
|
|
25
58
|
static Action resolveAction(
|
|
26
59
|
boolean customFullscreenActive,
|
|
27
60
|
boolean webViewCanGoBack,
|
package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewCustomFullscreenSupport.java
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
package ee.forgr.capacitor_inappbrowser;
|
|
2
2
|
|
|
3
3
|
import android.view.View;
|
|
4
|
+
import android.view.Window;
|
|
5
|
+
import androidx.core.view.WindowCompat;
|
|
6
|
+
import androidx.core.view.WindowInsetsCompat;
|
|
7
|
+
import androidx.core.view.WindowInsetsControllerCompat;
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* Testable helpers for HTML5/iframe fullscreen routed through WebChromeClient custom views
|
|
@@ -22,16 +26,28 @@ final class WebViewCustomFullscreenSupport {
|
|
|
22
26
|
return isActive;
|
|
23
27
|
}
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
);
|
|
29
|
+
static int immersiveSystemBarsBehavior() {
|
|
30
|
+
return WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static void enterImmersiveFullscreen(Window window, View decorView) {
|
|
34
|
+
if (window == null || decorView == null) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
WindowCompat.setDecorFitsSystemWindows(window, false);
|
|
39
|
+
WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(window, decorView);
|
|
40
|
+
controller.hide(WindowInsetsCompat.Type.systemBars());
|
|
41
|
+
controller.setSystemBarsBehavior(immersiveSystemBarsBehavior());
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static void exitImmersiveFullscreen(Window window, View decorView) {
|
|
45
|
+
if (window == null || decorView == null) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(window, decorView);
|
|
50
|
+
controller.show(WindowInsetsCompat.Type.systemBars());
|
|
35
51
|
}
|
|
36
52
|
|
|
37
53
|
static boolean shouldUseHostActivityWindow(boolean backLayerActive) {
|
|
@@ -41,9 +57,4 @@ final class WebViewCustomFullscreenSupport {
|
|
|
41
57
|
static boolean shouldRegisterHostBackHandler(boolean backLayerActive) {
|
|
42
58
|
return backLayerActive;
|
|
43
59
|
}
|
|
44
|
-
|
|
45
|
-
@SuppressWarnings("deprecation")
|
|
46
|
-
static int restoredSystemUiVisibility() {
|
|
47
|
-
return View.SYSTEM_UI_FLAG_VISIBLE;
|
|
48
|
-
}
|
|
49
60
|
}
|
|
@@ -345,6 +345,8 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
345
345
|
private Window customFullscreenWindow;
|
|
346
346
|
private OnBackPressedCallback customFullscreenBackCallback;
|
|
347
347
|
private OnBackPressedCallback dialogBackCallback;
|
|
348
|
+
private OnBackPressedCallback dialogActivityBackCallback;
|
|
349
|
+
private boolean activeForBackNavigation = true;
|
|
348
350
|
private Toolbar _toolbar;
|
|
349
351
|
private Options _options = null;
|
|
350
352
|
private final Context _context;
|
|
@@ -461,17 +463,18 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
461
463
|
void bindToHostActivity() {
|
|
462
464
|
ensureFileChooserLaunchers();
|
|
463
465
|
registerDialogBackHandler();
|
|
466
|
+
registerDialogActivityBackHandler();
|
|
464
467
|
}
|
|
465
468
|
|
|
466
469
|
@Override
|
|
467
470
|
protected void onStart() {
|
|
468
471
|
super.onStart();
|
|
469
|
-
|
|
472
|
+
syncBackNavigationHandlers();
|
|
470
473
|
}
|
|
471
474
|
|
|
472
475
|
@Override
|
|
473
476
|
protected void onStop() {
|
|
474
|
-
|
|
477
|
+
syncBackNavigationHandlers();
|
|
475
478
|
super.onStop();
|
|
476
479
|
}
|
|
477
480
|
|
|
@@ -670,7 +673,7 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
670
673
|
backLayerActive = false;
|
|
671
674
|
backLayerParent = null;
|
|
672
675
|
restoreHostTransparency();
|
|
673
|
-
|
|
676
|
+
syncBackNavigationHandlers();
|
|
674
677
|
}
|
|
675
678
|
|
|
676
679
|
private void attachContentToDialogWindow() {
|
|
@@ -713,7 +716,7 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
713
716
|
super.hide();
|
|
714
717
|
}
|
|
715
718
|
refreshInsetsForHostingLayer();
|
|
716
|
-
|
|
719
|
+
syncBackNavigationHandlers();
|
|
717
720
|
return true;
|
|
718
721
|
}
|
|
719
722
|
|
|
@@ -2145,7 +2148,7 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
2145
2148
|
@SuppressLint({ "SetJavaScriptEnabled", "AddJavascriptInterface" })
|
|
2146
2149
|
public void presentWebView() {
|
|
2147
2150
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
2148
|
-
|
|
2151
|
+
applyBackNavigationPolicy();
|
|
2149
2152
|
setContentView(R.layout.activity_browser);
|
|
2150
2153
|
|
|
2151
2154
|
// If custom dimensions are set, configure for touch passthrough
|
|
@@ -2172,7 +2175,7 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
2172
2175
|
// Set dimensions if specified, otherwise fullscreen
|
|
2173
2176
|
applyDimensions();
|
|
2174
2177
|
|
|
2175
|
-
SystemUiChromeSupport.prepareInitialDialogWindow(getWindow());
|
|
2178
|
+
SystemUiChromeSupport.prepareInitialDialogWindow(getWindow(), findViewById(R.id.status_bar_color_view));
|
|
2176
2179
|
|
|
2177
2180
|
WindowInsetsControllerCompat insetsController = new WindowInsetsControllerCompat(
|
|
2178
2181
|
getWindow(),
|
|
@@ -2926,13 +2929,66 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
2926
2929
|
}
|
|
2927
2930
|
};
|
|
2928
2931
|
getOnBackPressedDispatcher().addCallback(dialogBackCallback);
|
|
2929
|
-
|
|
2932
|
+
syncBackNavigationHandlers();
|
|
2930
2933
|
}
|
|
2931
2934
|
|
|
2932
|
-
private void
|
|
2935
|
+
private void registerDialogActivityBackHandler() {
|
|
2936
|
+
if (!(activity instanceof ComponentActivity componentActivity) || dialogActivityBackCallback != null) {
|
|
2937
|
+
return;
|
|
2938
|
+
}
|
|
2939
|
+
dialogActivityBackCallback = new OnBackPressedCallback(false) {
|
|
2940
|
+
@Override
|
|
2941
|
+
public void handleOnBackPressed() {
|
|
2942
|
+
handleBrowserBackNavigation();
|
|
2943
|
+
}
|
|
2944
|
+
};
|
|
2945
|
+
componentActivity.getOnBackPressedDispatcher().addCallback(componentActivity, dialogActivityBackCallback);
|
|
2946
|
+
syncBackNavigationHandlers();
|
|
2947
|
+
}
|
|
2948
|
+
|
|
2949
|
+
void applyBackNavigationPolicy() {
|
|
2950
|
+
boolean disableGoBack = _options != null && _options.getDisableGoBackOnNativeApplication();
|
|
2951
|
+
setCancelable(WebViewBackNavigationSupport.isCancelableOnBack(disableGoBack));
|
|
2952
|
+
syncBackNavigationHandlers();
|
|
2953
|
+
}
|
|
2954
|
+
|
|
2955
|
+
private void syncBackNavigationHandlers() {
|
|
2933
2956
|
if (dialogBackCallback != null) {
|
|
2934
2957
|
dialogBackCallback.setEnabled(shouldConsumeBackPress());
|
|
2935
2958
|
}
|
|
2959
|
+
if (dialogActivityBackCallback != null) {
|
|
2960
|
+
dialogActivityBackCallback.setEnabled(shouldRegisterActivityBackHandler());
|
|
2961
|
+
}
|
|
2962
|
+
}
|
|
2963
|
+
|
|
2964
|
+
private boolean shouldRegisterActivityBackHandler() {
|
|
2965
|
+
return WebViewBackNavigationSupport.shouldRegisterActivityBackHandler(
|
|
2966
|
+
isShowing(),
|
|
2967
|
+
backLayerActive,
|
|
2968
|
+
isHiddenModeActive,
|
|
2969
|
+
_options != null && _options.getDisableGoBackOnNativeApplication(),
|
|
2970
|
+
activeForBackNavigation
|
|
2971
|
+
);
|
|
2972
|
+
}
|
|
2973
|
+
|
|
2974
|
+
void setActiveForBackNavigation(boolean active) {
|
|
2975
|
+
if (activeForBackNavigation == active) {
|
|
2976
|
+
return;
|
|
2977
|
+
}
|
|
2978
|
+
activeForBackNavigation = active;
|
|
2979
|
+
syncBackNavigationHandlers();
|
|
2980
|
+
}
|
|
2981
|
+
|
|
2982
|
+
boolean isActiveForBackNavigation() {
|
|
2983
|
+
return activeForBackNavigation;
|
|
2984
|
+
}
|
|
2985
|
+
|
|
2986
|
+
boolean isBackLayerActive() {
|
|
2987
|
+
return backLayerActive;
|
|
2988
|
+
}
|
|
2989
|
+
|
|
2990
|
+
boolean isActivityBackHandlerEnabled() {
|
|
2991
|
+
return dialogActivityBackCallback != null && dialogActivityBackCallback.isEnabled();
|
|
2936
2992
|
}
|
|
2937
2993
|
|
|
2938
2994
|
private void unregisterDialogBackHandler() {
|
|
@@ -2940,6 +2996,10 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
2940
2996
|
dialogBackCallback.remove();
|
|
2941
2997
|
dialogBackCallback = null;
|
|
2942
2998
|
}
|
|
2999
|
+
if (dialogActivityBackCallback != null) {
|
|
3000
|
+
dialogActivityBackCallback.remove();
|
|
3001
|
+
dialogActivityBackCallback = null;
|
|
3002
|
+
}
|
|
2943
3003
|
}
|
|
2944
3004
|
|
|
2945
3005
|
private boolean shouldConsumeBackPress() {
|
|
@@ -3020,7 +3080,7 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
3020
3080
|
}
|
|
3021
3081
|
|
|
3022
3082
|
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
|
3023
|
-
|
|
3083
|
+
WebViewCustomFullscreenSupport.enterImmersiveFullscreen(window, decorView);
|
|
3024
3084
|
|
|
3025
3085
|
if (WebViewCustomFullscreenSupport.shouldRegisterHostBackHandler(backLayerActive)) {
|
|
3026
3086
|
registerCustomFullscreenBackHandler();
|
|
@@ -3078,7 +3138,7 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
3078
3138
|
Window window = customFullscreenWindow != null ? customFullscreenWindow : getWindow();
|
|
3079
3139
|
if (window != null) {
|
|
3080
3140
|
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
|
3081
|
-
window.getDecorView()
|
|
3141
|
+
WebViewCustomFullscreenSupport.exitImmersiveFullscreen(window, window.getDecorView());
|
|
3082
3142
|
reapplyInsetsFromWindowRoot();
|
|
3083
3143
|
if (SystemUiChromeSupport.requiresEdgeToEdgeChrome(Build.VERSION.SDK_INT)) {
|
|
3084
3144
|
refreshEdgeToEdgeChrome();
|
|
@@ -3146,7 +3206,7 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
3146
3206
|
}
|
|
3147
3207
|
|
|
3148
3208
|
isHiddenModeActive = true;
|
|
3149
|
-
|
|
3209
|
+
syncBackNavigationHandlers();
|
|
3150
3210
|
}
|
|
3151
3211
|
|
|
3152
3212
|
private void restoreVisibleMode() {
|
|
@@ -3184,7 +3244,7 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
3184
3244
|
previousWebViewAlpha = 1f;
|
|
3185
3245
|
previousWebViewVisibility = View.VISIBLE;
|
|
3186
3246
|
isHiddenModeActive = false;
|
|
3187
|
-
|
|
3247
|
+
syncBackNavigationHandlers();
|
|
3188
3248
|
}
|
|
3189
3249
|
|
|
3190
3250
|
public void setHidden(boolean hidden) {
|
|
@@ -3210,7 +3270,7 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
3210
3270
|
// Set flag immediately to prevent race condition if setHidden(false)
|
|
3211
3271
|
// is called before the posted runnable executes
|
|
3212
3272
|
isHiddenModeActive = true;
|
|
3213
|
-
|
|
3273
|
+
syncBackNavigationHandlers();
|
|
3214
3274
|
decorView.post(this::applyHiddenMode);
|
|
3215
3275
|
} catch (Exception e) {
|
|
3216
3276
|
Log.w("InAppBrowser", "Unable to show dialog before hiding", e);
|
|
@@ -3275,7 +3335,6 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
3275
3335
|
if (getWindow() != null) {
|
|
3276
3336
|
View decorView = getWindow().getDecorView();
|
|
3277
3337
|
Integer statusBarColor = null;
|
|
3278
|
-
Integer navigationBarColor = Color.TRANSPARENT;
|
|
3279
3338
|
Boolean lightStatusBars = null;
|
|
3280
3339
|
|
|
3281
3340
|
if (isAndroid15Plus) {
|
|
@@ -3316,9 +3375,9 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
3316
3375
|
SystemUiChromeSupport.applyDialogWindowChrome(
|
|
3317
3376
|
getWindow(),
|
|
3318
3377
|
decorView,
|
|
3378
|
+
findViewById(R.id.status_bar_color_view),
|
|
3319
3379
|
isAndroid15Plus,
|
|
3320
3380
|
statusBarColor,
|
|
3321
|
-
navigationBarColor,
|
|
3322
3381
|
lightStatusBars
|
|
3323
3382
|
);
|
|
3324
3383
|
}
|
|
@@ -4913,7 +4972,7 @@ public class WebViewDialog extends ComponentDialog implements ProxyResponseRouti
|
|
|
4913
4972
|
|
|
4914
4973
|
// Also ensure status bar gets the color
|
|
4915
4974
|
if (getWindow() != null) {
|
|
4916
|
-
SystemUiChromeSupport.
|
|
4975
|
+
SystemUiChromeSupport.applyLegacyStatusBarColorViaView(findViewById(R.id.status_bar_color_view), toolbarColor);
|
|
4917
4976
|
|
|
4918
4977
|
// Determine proper status bar text color (light or dark icons)
|
|
4919
4978
|
boolean isDarkBackground = isDarkColor(toolbarColor);
|
|
@@ -446,7 +446,7 @@ public class CapgoInAppBrowserPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
446
446
|
case aware = "AWARE"
|
|
447
447
|
case fakeVisible = "FAKE_VISIBLE"
|
|
448
448
|
}
|
|
449
|
-
private let pluginVersion: String = "8.16.
|
|
449
|
+
private let pluginVersion: String = "8.16.5"
|
|
450
450
|
public let identifier = "CapgoInAppBrowserPlugin"
|
|
451
451
|
public let jsName = "CapgoInAppBrowser"
|
|
452
452
|
public let pluginMethods: [CAPPluginMethod] = [
|
|
@@ -5,6 +5,10 @@ import WebKit
|
|
|
5
5
|
extension WKWebView {
|
|
6
6
|
private static var _overriddenSchemes = Set<String>()
|
|
7
7
|
private static let _overriddenSchemesLock = NSLock()
|
|
8
|
+
private static var _originalHandlesURLSchemeIMP: IMP?
|
|
9
|
+
|
|
10
|
+
// Original +[WKWebView handlesURLScheme:] IMP (saved before swizzle).
|
|
11
|
+
private typealias HandlesURLSchemeIMP = @convention(c) (AnyClass, Selector, NSString) -> Bool
|
|
8
12
|
|
|
9
13
|
private static let _swizzleOnce: Void = {
|
|
10
14
|
let original = class_getClassMethod(WKWebView.self, #selector(WKWebView.handlesURLScheme(_:)))
|
|
@@ -18,6 +22,7 @@ extension WKWebView {
|
|
|
18
22
|
return
|
|
19
23
|
}
|
|
20
24
|
|
|
25
|
+
_originalHandlesURLSchemeIMP = method_getImplementation(original)
|
|
21
26
|
method_exchangeImplementations(original, swizzled)
|
|
22
27
|
}()
|
|
23
28
|
|
|
@@ -28,7 +33,14 @@ extension WKWebView {
|
|
|
28
33
|
_overriddenSchemesLock.unlock()
|
|
29
34
|
|
|
30
35
|
if isOverridden { return false }
|
|
31
|
-
|
|
36
|
+
|
|
37
|
+
guard let imp = _originalHandlesURLSchemeIMP else {
|
|
38
|
+
print("[InAppBrowser][Proxy] WARNING: Original handlesURLScheme IMP missing; assuming not handled")
|
|
39
|
+
return false
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let original: HandlesURLSchemeIMP = unsafeBitCast(imp, to: HandlesURLSchemeIMP.self)
|
|
43
|
+
return original(WKWebView.self, #selector(WKWebView.handlesURLScheme(_:)), urlScheme as NSString)
|
|
32
44
|
}
|
|
33
45
|
|
|
34
46
|
static func enableCustomSchemeHandling(for schemes: [String]) {
|