Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting Custom Protocol Handler in Windows 8+ with Chrome

Tags:

I am trying to detect if my application to handle a custom protocol is installed and working using the different browsers. I have looked at other questions on this site such as: How to detect browser's protocol handlers?, and have looked at resources like this to make it work on most platforms in most browsers.

Before you flag this as duplicate, hear me out...

I was able to get my function working on everything except Chrome on Windows 8+. I cannot use the window focus method on Chrome like I can on Windows 7 because it pops up the message that asks me to find an app in the store.

Is there any way (short of an extension) to detect a custom protocol handler in Windows 8+ on Chrome?

UPDATE:

Using an onBlur to detect it only works on Windows 7, because in 8+, if it doesn't find something to open your protocol, it opens the 'find something from the app store' dialog that makes the browser lose focus.

like image 1000
PixelAcorn Avatar asked Mar 17 '15 19:03

PixelAcorn


People also ask

Where is the protocol handler in Chrome?

The Protocol Handler Icon Your first step is to start Chrome on your computer, open Gmail, then look up at your top address bar. Look for the Protocol Handler icon at the top right. This looks like a gray-colored diamond that's to the left of a star, with the latter being used for bookmarking.


1 Answers

Hey I think you were on the right track. It is definitly not that easy but chrome so far was not my problem, more like Edge + IE but my solution is assuming they don't support the protocol if anything fails or they don't respond correctly which they do sometimes.

The blur/focus is something to check but you need to check it in combination with a visibility change. The HTML5 Visiblity API and this post about it helped me figure out a solution that is pretty solid except the mentioned browsers above because they have some issues with the navigator.msLaunchUri function and have their own approach implemented which doesn't rely on blur/focus. But the function is bugged and doesn't respond correctly all the time.

You can find my codepen here. Hopefully that helps you even though it is a bit late for an answer. This works for mobile browsers as well but I didn't test multiple yet worked for my Android 6.0.2. Might need some tweaks in the long run but I think it is pretty solid.

(function() {   var noProtocolHash = '#protocolXYnotsupported',       checkDelay = 800, // apps might start slowly       isBlurred = false,       inCheck = false,       inLauncherCheck = false,    tabVisible = (function(){        var stateKey,            eventKey,            keys = {                   hidden: "visibilitychange",                   webkitHidden: "webkitvisibilitychange",                   mozHidden: "mozvisibilitychange",                   msHidden: "msvisibilitychange"       };       for (stateKey in keys) {           if (stateKey in document) {               eventKey = keys[stateKey];               break;           }       }       return function(c) {           if (c) document.addEventListener(eventKey, c);           return !document[stateKey];       }   })(),    isMSIE = function(){     var rv = -1;      if(navigator.appName == 'Microsoft Internet Explorer'){       var ua = navigator.userAgent;       var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");       if(re.exec(ua) != null){         rv = parseFloat(RegExp.$1);       }     }     else if(navigator.appName == 'Netscape'){       var ua = navigator.userAgent;       var re  = new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})");       if(re.exec(ua) != null){         rv = parseFloat(RegExp.$1);       }     }     return (rv !== -1)? true: false;   },    isEdge = function(){     return window.navigator.userAgent.indexOf("Edge") > -1;   },    checkIfFocusLost = function($el){     try {       document.location.href = $el.attr("href");     } catch (ex) {         document.location.href = document.location.href + '/' + noProtocolHash;     }      setTimeout(checkVisibility, checkDelay);   },    checkVisibility = function(){     if(tabVisible() && !isBlurred){       handleNoProtocol();     }     else {       handleProtocol();     }   },    handleNoProtocol = function(){     $('.result').text('has no protocol');      inLauncherCheck = false;   },    handleProtocol = function(){     $('.result').text('has the protocol');      inLauncherCheck = false;   },    checkHash = function(){     if(document.location.hash === noProtocolHash){       handleNoProtocol();     }   },    checkLauncherProtocol = function($el){     inLauncherCheck = true;      navigator.msLaunchUri($el.attr("href"), function(){       handleProtocol();     },      function(){       handleNoProtocol();     });      setTimeout(function(){       // fallback when edge is not responding correctly       if(inLauncherCheck === true){         handleNoProtocol();       }     }, 500);   },    checkIfHasProtocol = function($el){     inCheck = true;      if(isEdge() || isMSIE()){       checkLauncherProtocol($el);     }     else {       checkIfFocusLost($el)     }   };    checkHash();   tabVisible(function(){     if(tabVisible() && inCheck){       handleProtocol();       inCheck = false;     }       });    window.addEventListener("blur", function(){     isBlurred = true;      });    window.addEventListener("focus", function(){     isBlurred = false;      inCheck = false;   });    window.checkIfHasProtocol = checkIfHasProtocol; })();  $('.protocol').click(function(e) {   checkIfHasProtocol($(this));   e.preventDefault(); }); 

My code is tested with Win10: Chrome, Firefox, IE11, Edge + Android: Chrome (6.0.1)

there is also this github project https://github.com/ismailhabib/custom-protocol-detection which sorta has a similar approach maybe a little bit more maintained but i couldn't get their solution working for some reasons but maybe this is exactly what you need.

like image 63
risutoru Avatar answered Sep 21 '22 17:09

risutoru