# Three Monkeys, Three Typewriters, Two Days

## March 25, 2011

### Capability sniffing done wrong

Object or capability sniffing is touted as the right way to test for features. It's better than UA string sniffing, because it treats all UAs based on a given engine the same. But it's still commonly misused. The failure mode is assuming that the presence or absence of feature A implies something about feature B. This is a valid assumption if UAs never add or remove features, but that's not the world we're in right now.

Our example today is MathJax. This sniffs for features to decide what browser it's dealing with, then uses slightly different downloadable font stuff in different browsers. It has to do this last because of differences in supported font formats and perhaps syntax, though browsers are converging on all of these. The problem is that the sniffing is not sniffing anything about downloadable fonts directly. The second problem is that if MathJax sees an "unknown" UA it falls back to not using downloadable fonts at all instead of falling back on current CSS3 downloadable fonts with WOFF.

In particular I found that MathJax 1.0 uses this test to decide whether a browser is "Firefox":

   isFirefox: (document.ATTRIBUTE_NODE != null && window.directories != null)


The problem, of course, is that Firefox 4 has removed support for window.directories. So MathJax was deciding that this is a browser it doesn't know about, and falling back to not even trying to use downloadable fonts.

Now someone at MathJax actually tests their stuff with pre-release browsers, or is at least willing to look into and fix user-reported bugs with them (unlike StackExchange). So MathJax 1.1 has changed its UA detection like so:

  isFirefox: (window.netscape != null && document.ATTRIBUTE_NODE != null &&
window.opera == null)


This works in Firefox 4, but window.netscape is non-standard, just like window.directories was. So at some point we might well remove it, and things will break again.

Again the right way to handle this is to either test the feature you're actually using instead of some unrelated feature or to at least fall back to using the standard approach when faced with an unknown UA. I've sent feedback to that effect to MathJax, of course.

Posted by bzbarsky at March 25, 2011 11:21 AM