Detecting Installed Plug-Ins in JavaScript

WebDevel.jpg

The support guys at the Shop have asked me if I could detect the presence/absence of the Flash plug-in on the allowed browsers for my web app. Currently, I check for IE and toss it out due to it's horrible JavaScript memory management. I also toss out versions of Firefox prior to 3 for the same reason. But after that, I was letting the browser deal with the existence of Flash and Java applet support. This was a mistake, as a lot of the folks didn't have these and it made for a bad user experience.

So I set about getting the detection code working. It turns out that it's really pretty easy to do because it's all pretty much there in the data within the browser, you just have to know how to parse it up. The method I came up with was part of a browser detection script, as it seemed most logical that I extend that and add methods like BrowserDetect.gotFlash and BrowserDetect.gotJava.

The code looks at the MIME types for the existence of the plug-in and then looks at the list of plug-ins to see if the version matches the minimum versions for my application.

  var BrowserDetect = {
    init: function() {
      // ...checking code for browser, version, and OS
      // check for the Flash plug-in
      this.gotFlash = this.checkPlugin('application/x-shockwave-flash',
                                       'Shockwave Flash', 10);
      // check for the Java Applet plug-in
      if (this.OS == 'Windows') {
        this.gotJava = this.checkPlugin('application/x-java-applet',
                                        'Java Plug-in', 1.6);
      } else {
        this.gotJava = this.checkPlugin('application/x-java-applet',
                                        'Java(TM) Plug-in', 1.6);
      }
    },
 
    // ...more methods...
 
    checkPlugin: function(mime, descKey, minVer) {
      // assume there's no valid plug-in matching these requirements
      var flag = false;
      var plugin = (navigator.mimeTypes && navigator.mimeTypes[mime]) ?
                   navigator.mimeTypes[mime].enabledPlugin : 0;
      if (plugin) {
        var cnt = navigator.plugins.length;
        for (var p = 0; p < cnt; ++p) {
          if (navigator.plugins[p].description.indexOf(descKey) >= 0) {
            var words = navigator.plugins[p].description.split(' ');
            for (var i = 0; i < words.length; ++i) {
              if (isNaN(parseFloat(words[i])))
                continue;
              var pluginVersion = parseFloat(words[i]);
            }
            flag = (pluginVersion >= minVer);
            // no need to check any further
            break;
          }
        }
      }
      return flag;
    },
 
    // ...more methods...
  };
  // initialize this guy so we can be ready to read all the values
  BrowserDetect.init();

With this code, I'm able to use the BrowserDetect.gotFlash call to put out a little notice about downloading the latest Flash plug-in - which is great because I'm not only detecting the existence, I'm also checking the version. This has proven to be a major hassle with Flash as the Google Visualization widget appears to work, but there are subtle things that make it seem broken. It's always been the version of Flash being less than 9. With version 10, we're good to go. That's a load off.

In general, I can see all these AJAX frameworks popping up. If I had known of one that had all this built-in, it'd be really nice. As it's already built, I'll look after-the-fact and if I run across something, I'll look at using it. But I can see why folks write these frameworks, and then use them over and over again.

Great code.