javascriptsafaricustom-protocol

How do I handle a custom protocol not being installed on Safari still triggering the onblur event?


I have a custom protocol checker that checks if a protocol is installed.

For Safari (same as chrome) it focuses on an element, fires the protocol and listens for onblur.

However in Safari if the protocol is not installed the browser throws an alert esc popup saying: "Safari cannot open the page because the address is invalid." which in turns triggers the onblur event.

Has anyone found a better way of managing this? It can be a Safari specific solution if needs be.

//Chrome (and default for other browsers)
function checkChrome(){
    bodyElement.append("<input type='text' id='focusInput' style='background: transparent;border: none;height: 0px;width: 0px;' />");
    var focusBodyElement = $('#focusInput')[0], temporaryResult = false;
    focusBodyElement.focus();
    focusBodyElement.onblur = function () {
        updateResult(true);
        return;
    };
    //will trigger onblur
    location.href = protocolStr;

    //Note: timeout could vary as per the browser version, have a higher value
    setTimeout(function () {
        focusBodyElement.onblur = null;
        if (protocolSupport[protocolStr]===null) {
            updateResult(false)
        }
    }, 1000);

}

Solution

  • I've used custom-protocol-detection in the past here, though my target was all browsers.

    That being said - in digging through their source, it seems their strategy is to embed the content in a hidden frame with the javascript creates.

    function openUriWithHiddenFrame(uri, failCb, successCb) {
    
        var timeout = setTimeout(function () {
            failCb();
            handler.remove();
        }, 1000);
    
        var iframe = document.querySelector("#hiddenIframe");
        if (!iframe) {
            iframe = _createHiddenIframe(document.body, "about:blank");
        }
    
        var handler = _registerEvent(window, "blur", onBlur);
    
        function onBlur() {
            clearTimeout(timeout);
            handler.remove();
            successCb();
        }
    
        iframe.contentWindow.location.href = uri;
    }
    

    source

    The source also contains strategies for all browsers.