Skip to content

Commit

Permalink
feat: Allow plugins to override navigation (#2872)
Browse files Browse the repository at this point in the history
Co-authored-by: Sean Bannigan <[email protected]>
  • Loading branch information
jcesarmobile and sbannigan authored May 6, 2020
1 parent 2775cb8 commit 41f9834
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 2 deletions.
13 changes: 13 additions & 0 deletions android/capacitor/src/main/java/com/getcapacitor/Bridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,19 @@ private void loadWebView() {
}

public boolean launchIntent(Uri url) {
/*
* Give plugins the chance to handle the url
*/
for (Map.Entry<String, PluginHandle> entry : plugins.entrySet()) {
Plugin plugin = entry.getValue().getInstance();
if (plugin != null) {
Boolean shouldOverrideLoad = plugin.shouldOverrideLoad(url);
if (shouldOverrideLoad != null) {
return shouldOverrideLoad;
}
}
}

if (!url.toString().contains(appUrl) && !appAllowNavigationMask.matches(url.getHost())) {
try {
Intent openIntent = new Intent(Intent.ACTION_VIEW, url);
Expand Down
10 changes: 10 additions & 0 deletions android/capacitor/src/main/java/com/getcapacitor/Plugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
Expand Down Expand Up @@ -548,6 +549,15 @@ protected void handleOnStop() {}
*/
protected void handleOnDestroy() {}

/**
* Give the plugins a chance to take control when a URL is about to be loaded in the WebView.
* Returning true causes the WebView to abort loading the URL.
* Returning false causes the WebView to continue loading the URL.
* Returning null will defer to the default Capacitor policy
*/
@SuppressWarnings("unused")
public Boolean shouldOverrideLoad(Uri url) { return null; }

/**
* Start a new Activity.
*
Expand Down
25 changes: 23 additions & 2 deletions ios/Capacitor/Capacitor/CAPBridgeViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,29 @@ public class CAPBridgeViewController: UIViewController, CAPBridgeDelegate, WKScr
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
NotificationCenter.default.post(name: Notification.Name(CAPNotifications.DecidePolicyForNavigationAction.name()), object: navigationAction)
let navUrl = navigationAction.request.url!

/*
* Give plugins the chance to handle the url
*/
if let plugins = bridge?.plugins {
for pluginObject in plugins {
let plugin = pluginObject.value
let selector = NSSelectorFromString("shouldOverrideLoad:")
if plugin.responds(to: selector) {
let shouldOverrideLoad = plugin.shouldOverrideLoad(navigationAction)
if (shouldOverrideLoad != nil) {
if (shouldOverrideLoad == true) {
decisionHandler(.cancel)
return
} else if shouldOverrideLoad == false {
decisionHandler(.allow)
return
}
}
}
}
}

if let allowNavigation = allowNavigationConfig, let requestHost = navUrl.host {
for pattern in allowNavigation {
if matchHost(host: requestHost, pattern: pattern.lowercased()) {
Expand All @@ -267,8 +290,6 @@ public class CAPBridgeViewController: UIViewController, CAPBridgeDelegate, WKScr
return
}

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

Expand Down
7 changes: 7 additions & 0 deletions ios/Capacitor/Capacitor/CAPPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
- (void)addListener:(CAPPluginCall *)call;
- (void)removeListener:(CAPPluginCall *)call;
- (void)removeAllListeners:(CAPPluginCall *)call;
/**
* Give the plugins a chance to take control when a URL is about to be loaded in the WebView.
* Returning true causes the WebView to abort loading the URL.
* Returning false causes the WebView to continue loading the URL.
* Returning nil will defer to the default Capacitor policy
*/
- (NSNumber *)shouldOverrideLoad:(WKNavigationAction *)navigationAction;

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

0 comments on commit 41f9834

Please sign in to comment.