Tuesday, March 08, 2005

Script Tag In Internet Explorer

After a sleepless night or two, I just discovered this bug in Internet Explorer the hard way.

I was bascially including a JavaScript file in my XHTML document. The scripts in this file were meant to attach to my XHTML elements unobtrusively, and this file was a unit by itself. So I didn't have any JavaScript within my script tags. This is how my tag looked.

<script language="javascript" type="text/javascript" src="script.js" />

This works like a dream everywhere, except in the world's most popular browser. In IE, the entire page is just blank! The markup is downloaded properly (I can see it when I view source), even my CSS background-color is applied to the page, but there's absolutely nothing on it! I blamed my content-negotiation scripts first (I am serving HTML Transitional to IE and XHTML everywhere else), and then on IE's support for CSS (I thought I made a grave little mistake somewhere). However, on removing this tag, everything worked fine in IE.

Turns out, IE doesn't like the script tags if they are using element minimization. I got the page rendering just as I intended by changing the tag to look like this:

<script language="javascript" type="text/javascript" src="script.js"></script>

Doing some research, I came across this post in theList by Eric Vitiello which clarifies this more. Apparently the DTD declaration for the script tag says <!ELEMENT script (#PCDATA)>, and the XHTML specs says (under Appendix C. 3):

Given an empty instance of an element whose content model is not EMPTY (for example, an empty title or paragraph) do not use the minimized form (e.g. use <p> </p> and not <p />).
So, I guess this isn't really a bug in IE. I'd think instead, that this is a bug in the DTD itself. The script tag doesn't have to contain #PCDATA (in fact, I consider it graceful if it doesn't), and forcing it is, well, stupid.

For now, I am explicitly closing the script tag with a seperate closing tag, and everything seems to be working well. Does anyone have any idea about handling this better, preferably with minimized element closures?

15 comments:

Charl van Niekerk said...

I don't believe this is a bug at all.

Your content negotiation script must have sent the document to IE as 'text/html' and as 'application/xhtml+xml' to browsers that support XHTML.

Since the shorthand for closing elements is valid in XML, browsers that get the document as 'application/xhtml+xml' (and therefore that parses the document through an XML parser) will build the intended DOM structure since an XML parser supports the shorthand.

All browsers that I know of, including Firefox, that get a document as 'text/html' parses the document as HTML, regardless of the doctype. In HTML, the abovementioned shorthand exists, but means something totally different. Therefore, the parser won't see the element as being closed and won't build the intended DOM structure. And there you get your "bug". :-)

Rakesh Pai said...

Thanks, Charl, for that info.

I tried this with Opera too. Here's my results.

With <script> </script> and "text/html":
IE - renders fine.
Opera - renders fine.
Firefox - renders fine.

With <script /> and "text/html":
IE - chokes up.
Opera - chokes up.
Firefox - renders fine.

With <script> </script> and "application/xhtml+xml":
IE - (tch tch)
Opera - renders fine.
Firefox - renders fine.

With <script /> and "application/xhtml+xml":
IE - *sigh*
Opera - renders fine.
Firefox - renders fine.

Obviously, <script> </script> is the only reliable piece of working code, irrespective of the doctype.

What confuses me is, how does Firefox work fine with <script /> while Opera chokes, when served with "text/html"? If Opera is right, so is IE, and Firefox is wrong. If Firefox is right, Opera is wrong.

How does the minimized element representation mean different things with different content-types? Considering that different browsers handle it differently, what is the correct implementation?

Tommy Olsson said...

This is not a bug at all. When you are serving a document as text/html, which you're probably doing since IE tries to render it, a user agent must interpret it as HTML. The <script/> syntax is not valid HTML (it's actually the same as <script>>, although virtually all browsers get that wrong). The closing tag is not optional for the SCRIPT element.

Charl van Niekerk said...

Yes, Tommy is right. That's exactly what it means in HTML (it's an SGML feature, and since the HTML spec doesn't override it like the XML spec, it stays like that).

Firefox's behavious is completely incorrect. Shame on it. :-)

I think Opera has the "perfect" implementation in this regard.

Roy Riggs said...

oh thank god! i was pulling my hair out trying to figure this one out!

Anonymous said...

I too had been having the same problem. Thanks for clearing it up.

Rob said...

Wow, over a year later and this is the only mention of this issue I have found on the Internet.

Thanks for helping me figure this annoyance out.

Christopher Yeleighton said...

If the XHTML DTD classified the script element as EMPTY you would be unable to use embedded scripts because embedding scripts would be prohibited. It is definitely not what you want.

Anonymous said...

Jeez, that one would have taken me forever. Thanks for bearing the pain for us all.

Rakesh Pai said...

Hey Christopher,

What I meant was that the script tag should be optionally empty, like it is completely logal to have an empty <p /> tag.

Cristian said...

Thank you for the explanation; it's excellent!

G0SUB said...

Heh, now Firefox 3.0 Beta 2 has the same problem, or shall I say the feature :)

It breaks if the <script> tag is closed on its own and the content-type is text/html.

Need to check with a different content-type.

I noticed it today when one of our internal apps I wrote suddenly stopped working.

--
BG

Woil said...

Thanks, solved my headache.

Anonymous said...

Another gotcha in IE. My script tag's type attribute had a trailing space: <script type="text/javascript "> which it probably shouldn't. FF loaded the script anyway, but IE barfed.

Alexei said...

This is really weird, im glad i found this out, i am using google analitycs and i was worried that i was just seen less than 10 visits per day for the last 3 days, when was i getting 100+ daily (This is a single page site (flash))

Thanks

ShareThis