How best to mimic conditional comments in EnhanceJS

14 views
Skip to first unread message

ScottJehl

unread,
Apr 5, 2010, 1:25:37 PM4/5/10
to EnhanceJS
Recently, we received some feedback saying we could improve our
implementation of pseudo-conditional-comment support (a way to include
CSS and JS for certain versions of Internet Explorer) in EnhanceJS by
using "conditional compilation" in place of User Agent string
detection. For those unfamiliar with conditional compilation, it's
basically another way to target Internet Explorer, in this case from
within the JS itself through a special comment syntax.

Example from Dean Edwards' site:
var isMSIE = /*@cc_on!@*/false;

Anything inside that /*@cc_on ... @*/ comment will be seen by IE. From
there, you can detect the browser's jscript version (IE8 == jscript
5.8, IE7 == jscript 5.7, IE6 == jscript 5.6, etc), to get a good idea
of which version of IE you're dealing with.

As most IE workarounds go, it's not pretty, but the benefit here is
that it doesn't rely on the user agent string, which is considered bad
practice to use for a number of reasons (spoofing, etc). EnhanceJS
doesn't actually use the UA string at all internally (which makes
sense since it's entire goal is to detect feature support rather than
browser make/model when deciding whether a browser should receive a
basic or enhanced experience.), but it does offer an API option for
specifying CSS and JS files that should only apply in Internet
Explorer, since it's very common for developers to use conditional
comments to deliver specific files ONLY to certain versions of IE to
fix bugs, etc. It works by specifying a property called 'iecondition'
when you include styles and scripts with EnhanceJS:

enhance({
loadStyles: [
'css/screen.css',
{'href': 'css/ie6fixes.css', 'iecondition': 6}
]
});

In this case, ie6fixes.css would only go to Internet Explorer 6. In
addition to version numbers, you can specify 'all' as well, to include
all IE versions.

Behind the scenes, the implementation for the iecondition property
uses User Agent string parsing. In principle, and in practice, we
think it'd be great to find another way around the UA detect portion,
and conditional compilation looks like a good option. After some
fiddling, I found that the following function can drop into EnhanceJS
to replace the current isIE function in use:

function isIE(version) {
return /*@cc_on (version === 'all' || parseFloat('5.' +
parseInt(version,10)) === @_jscript_version)@*/;
}

This will return true in IE if the condition is set to 'all', or if
the IE version specified is the X in "5.X", which is how the jScript
versions happen to line up (for IE versions 6-8 anyway).

So it looks pretty good, but I did find one downfall to this
implementation: IE8 reports the same jscript version in standards mode
and compatibility mode, the latter of which is supposed to emulate IE
version 7. Because of this, only "pure" versions of IE7 will receive
scripts and styles targeted for IE7. This might be enough of an edge-
case to go with it anyway, but it will mean that anyone browsing a
site in compatibility mode (such as when a site uses the <meta http-
equiv="X-UA-Compatible" content="IE=EmulateIE7" /> tag, or when the
user actually chooses to view a site that way) will not receive IE7-
only assets, which might cause problems for those users.

So...
Should we go with this new approach and document this edge-case
issue?
Should we use it and limit the iecondition property to only support
targeting IE6 (do developers need to target IE7+ that often anyway)?

We'd love feedback.
Thanks!

ScottJehl

unread,
Apr 6, 2010, 3:34:43 PM4/6/10
to EnhanceJS
Following up on this thread..
Here's a different approach that seems to be a bit better than the
previously proposed solutions.
http://gist.github.com/357750

This approach wraps an injected conditional comment around an element
and then tests for that element's existence. It doesn't use UA string
or conditional compilation, and allows for regular isIE() ? checks, as
well as version checks. It even allows for "lte", "gte" checks since
they're natively supported in conditional comments.

I'm testing it in EnhanceJS now.

ScottJehl

unread,
Apr 6, 2010, 6:35:03 PM4/6/10
to EnhanceJS
Reply all
Reply to author
Forward
0 new messages