Skip to content

Commit 41f9834

Browse files
feat: Allow plugins to override navigation (#2872)
Co-authored-by: Sean Bannigan <bannigan@meetmaestro.com>
1 parent 2775cb8 commit 41f9834

File tree

4 files changed

+53
-2
lines changed

4 files changed

+53
-2
lines changed

android/capacitor/src/main/java/com/getcapacitor/Bridge.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,19 @@ private void loadWebView() {
224224
}
225225

226226
public boolean launchIntent(Uri url) {
227+
/*
228+
* Give plugins the chance to handle the url
229+
*/
230+
for (Map.Entry<String, PluginHandle> entry : plugins.entrySet()) {
231+
Plugin plugin = entry.getValue().getInstance();
232+
if (plugin != null) {
233+
Boolean shouldOverrideLoad = plugin.shouldOverrideLoad(url);
234+
if (shouldOverrideLoad != null) {
235+
return shouldOverrideLoad;
236+
}
237+
}
238+
}
239+
227240
if (!url.toString().contains(appUrl) && !appAllowNavigationMask.matches(url.getHost())) {
228241
try {
229242
Intent openIntent = new Intent(Intent.ACTION_VIEW, url);

android/capacitor/src/main/java/com/getcapacitor/Plugin.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import android.content.Intent;
66
import android.content.pm.PackageInfo;
77
import android.content.pm.PackageManager;
8+
import android.net.Uri;
89
import android.os.Bundle;
910

1011
import androidx.appcompat.app.AppCompatActivity;
@@ -548,6 +549,15 @@ protected void handleOnStop() {}
548549
*/
549550
protected void handleOnDestroy() {}
550551

552+
/**
553+
* Give the plugins a chance to take control when a URL is about to be loaded in the WebView.
554+
* Returning true causes the WebView to abort loading the URL.
555+
* Returning false causes the WebView to continue loading the URL.
556+
* Returning null will defer to the default Capacitor policy
557+
*/
558+
@SuppressWarnings("unused")
559+
public Boolean shouldOverrideLoad(Uri url) { return null; }
560+
551561
/**
552562
* Start a new Activity.
553563
*

ios/Capacitor/Capacitor/CAPBridgeViewController.swift

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,29 @@ public class CAPBridgeViewController: UIViewController, CAPBridgeDelegate, WKScr
252252
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
253253
NotificationCenter.default.post(name: Notification.Name(CAPNotifications.DecidePolicyForNavigationAction.name()), object: navigationAction)
254254
let navUrl = navigationAction.request.url!
255+
256+
/*
257+
* Give plugins the chance to handle the url
258+
*/
259+
if let plugins = bridge?.plugins {
260+
for pluginObject in plugins {
261+
let plugin = pluginObject.value
262+
let selector = NSSelectorFromString("shouldOverrideLoad:")
263+
if plugin.responds(to: selector) {
264+
let shouldOverrideLoad = plugin.shouldOverrideLoad(navigationAction)
265+
if (shouldOverrideLoad != nil) {
266+
if (shouldOverrideLoad == true) {
267+
decisionHandler(.cancel)
268+
return
269+
} else if shouldOverrideLoad == false {
270+
decisionHandler(.allow)
271+
return
272+
}
273+
}
274+
}
275+
}
276+
}
277+
255278
if let allowNavigation = allowNavigationConfig, let requestHost = navUrl.host {
256279
for pattern in allowNavigation {
257280
if matchHost(host: requestHost, pattern: pattern.lowercased()) {
@@ -267,8 +290,6 @@ public class CAPBridgeViewController: UIViewController, CAPBridgeDelegate, WKScr
267290
return
268291
}
269292

270-
// TODO: Allow plugins to handle this. See
271-
// https://github.com/ionic-team/cordova-plugin-ionic-webview/blob/608d64191405b233c01a939f5755f8b1fdd97f8c/src/ios/CDVWKWebViewEngine.m#L609
272293
decisionHandler(.allow)
273294
}
274295

ios/Capacitor/Capacitor/CAPPlugin.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@
2424
- (void)addListener:(CAPPluginCall *)call;
2525
- (void)removeListener:(CAPPluginCall *)call;
2626
- (void)removeAllListeners:(CAPPluginCall *)call;
27+
/**
28+
* Give the plugins a chance to take control when a URL is about to be loaded in the WebView.
29+
* Returning true causes the WebView to abort loading the URL.
30+
* Returning false causes the WebView to continue loading the URL.
31+
* Returning nil will defer to the default Capacitor policy
32+
*/
33+
- (NSNumber *)shouldOverrideLoad:(WKNavigationAction *)navigationAction;
2734

2835
// Called after init if the plugin wants to do
2936
// some loading so the plugin author doesn't

0 commit comments

Comments
 (0)