25

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.

Community
  • 1
  • 1
PixelAcorn
  • 494
  • 8
  • 26
  • chrome on windows is important, which prototcol do you need to detect? – dandavis Mar 17 '15 at 19:53
  • 1
    @dandavis I agree. It is a custom protocol... for example "foo://" – PixelAcorn Mar 17 '15 at 19:54
  • @dandavis It doesn't have a mime type. As far as the name goes, it could be whatever I wanted it to be. – PixelAcorn Mar 17 '15 at 20:03
  • you might be able to sniff the side-effect from a popup window's behavior, like if it closed right away or stayed stalled on the google plug (i don't know, it just sounds reasonable) – dandavis Mar 17 '15 at 20:08
  • what do you expect it to do ? ignore your protcol ? please clarify the problem and the expected solution. – ProllyGeek Mar 27 '15 at 11:26
  • @ProllyGeek "I am trying to detect if my application to handle a custom protocol is installed and working using the different browsers." - What I expect it to do; "I was able to get my function working on everything except Chrome on Windows 8+."- The problem; "Is there any way...to detect a custom protocol handler in Windows 8+ on Chrome?"-The expected solution. What more do you need? – PixelAcorn Mar 27 '15 at 16:34
  • Hi PixelAcorn, I am in the same problem on Chrome. Have you solved it and if yes, could you tell me how you solved it? – yo2011 Jun 01 '16 at 15:17

2 Answers2

2

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.

risutoru
  • 455
  • 5
  • 13
-1

I think this might help you here with different browsers, but please define you question better or add at least some kinda example to make it clear.

Jon Doe
  • 2,172
  • 1
  • 18
  • 35
Talha Habib
  • 33
  • 1
  • 7
  • 3
    I've looked at solutions like that. The problem is that that Chrome solution only works on Windows 7. I don't quite see how my question isn't clear.... – PixelAcorn Mar 27 '15 at 16:31
  • Hi PixelAcorn, I am in the same problem on Chrome and waiting your feedback – yo2011 Jun 01 '16 at 15:18