Closing a WebView programmatically?

Is there a way to close a WebView programmatically?

The obvious option of webview.evaluateJavaScript('window.close()') does not do anything.

I am using a WebView for the first stage of OAuth authorisation, with a shouldAllowRequest handler extracting the code from the callback redirect:

function oauthAuthorise() {
    return new Promise(async (resolve, reject) => {
        let webview = new WebView();
        webview.shouldAllowRequest = request => {
            if (!request.url.startsWith(CALLBACK_URL)) return true;
            resolve(request.url);
            // HERE - Close the WebView
            webview.loadHTML('Please close this window');
            return false;
        }
        webview.loadURL(AUTHORISE_URL);
        await webview.present(false);
        reject(new Error('Authorisation abandoned'));
    });
}

The particular API that I am using requires a valid domain to be used for the OAuth Redirect URL, so it is not possible to use localhost or an x-callback-url. Hence, trapping the redirect with the shouldAllowRequest handler seems the best option.

I am currently using webview.loadHTML to prompt the user to close the WebView, but it would be neater if it could be close automatically…

You can open the same script with query parameters which allows you to use args.queryParameters to continue execution if needed. Scriptable can only have one script running at a time so this will dismiss all open WebViews.

  const scriptUrl = URLScheme.forRunningScript() + '&exit=true';
  Safari.open(scriptUrl);

I do something like:


if (!args.queryParameters.exit) {
   ...
}
2 Likes

Thank you @anyhotcountry. That’s fantastic. (Well slightly messy, but it achieves the desired result.)

I hadn’t considered that running another script (or another instance of the same script) would have the side-effect of closing any open WebViews.

1 Like