Which whitespace was that again?

We recently saw this at $WORK. It appears corrupted in Internet Explorer only. Firefox and Safari show it normally.

Corrupted text in internet explorer

After much exploration in the debugger, we eventually found it was caused by using the innerText property in internet explorer. This has the mildly surprising property of turning multiple spaces into U+00A0 (NO-BREAK SPACE) characters (  to you and me). This behaviour doesn’t appear to be documented. And before you ask, this was all being done by a third-party — I know to not use proprietary extensions where possible.

Anyway, I nailed it down to a small test. Given this markup.

Then this script demonstrates the problem.

var foo = document.getElementById('foo');

// OK
foo.innerText = ['A', ' ', 'B'].join('');
alert(foo.innerHTML);   // "A B"

foo.innerText = ['A', ' ', ' ', 'B'].join('');
alert(foo.innerHTML);   // "A  B"

If you want to try it yourself, check out (jsbin is awesome! Thanks, rem!)

The quick solution is simple: normalize whitespace before insertion before using innerText.

var text = 'some       where        over      the      rainbow';

foo.innerText = text.split(/s+/).join(' ');

Of course, you should really be using appendChild() and createTextNode().


contype is an MSIE bug

Yesterday, I was helping a colleague debug a problem involving dynamically generated PDFs. For some reason, he was occaisionally getting double requests for the same file. Eventually, we cottoned on to the fact that the second request had a user-agent of “contype”. Not having heard of that before, I googled for it.

Tim Strehle is the first hit for user agent contype, and he has an explanation and a link to the MSDN article PRB: Three GET Requests Are Sent When You Retrieve Plug-in Served Content.

I have never been so astonished by what I saw.

Symptoms: When a server returns a document that is handled by a plug-in (such as an Adobe Acrobat PDF file), three requests are made for the document in Internet Explorer versions 4.x and 5, and two requests are made in Internet Explorer version 5.5.

Cause: The first behavior is by design. When an initial request is sent for the server file, this returns a data stream with a content-type that is handled by a plug-in (not an ActiveX control), and Internet Explorer closes the initial port and sends a new request with userAgent = contype. The only information that is needed in return from the contype request is the content-type.

That’s pretty broken design. You already have the information in the browser, yet you have to go across the network again to fetch it? What a crock. They didn’t even have the clue to use a HEAD request instead of a GET, which would have been a bit of a hint in the right direction.

But the bit that really infuriated me was this:

However, because most developers are unaware of this request style, they treat each GET the same and return the entire document.

Which I read as:

Because we fucked up and you didn’t know about it, you lose dumbass.

The whole thing has an infuriatingly arrogant tone to it. There’s no apology for their insane design. Just Nelson going “Har-Har”.

You have been warned.


Cross Browser JavaScript Still Hard

Recently, I’ve been doing a reasonable amount of playing around with prototype and scriptaculous. They’re both really great libraries that give you loads of features and take a lot of trouble out of your hands. But they certainly don’t absolve you from cross browser compatibility testing. Whilst the libraries themselves are pretty much cross browser compatible, your own code likely isn’t until proved otherwise…

The discoveries I have made that lead to this:

  • MSIE doesn’t like trailing commas. e.g. this throws up an a JScript error in Internet Explorer.
    foo: 1,
    bar: 2,
  • I’m still tracking this one down, but I started getting errors when I did'non-existent-id') in Internet Explorer, but not FireFox. Why doesn’t Firefox complain? I think it should do.
    • Oh all right, it does complain. I missed the warning.

Doubtless this is just the beginning of a list.

Of course, I managed to waste plenty of time arriving at these problems, because Internet Explorer has such incredibly lacklustre development tools. For example, to get any idea at all of where the error in your code is1, you have to install the Microsoft Script Debugger. This is very primitive, but it will show you where the error actually occurred, and gives you a fighting chance of examining some variables in the locality2.

In my case, the script debugger didn’t even work properly when first installed. After reading somewhere that Visual Studio surperceded the Script Debugger, I remembered an experiment I’d performed a while back. It turned out that something called MDM had gottened installed. Deleting it and all associated registry entries made the Script Debugger spring back into life. Finally!

Another hint worth noting about the Script Debugger: if you want it to run in a non-administrator account, you need to put yourself in the “Debugger Users” group.

1 The error that pops up in Internet Explorer gives you a line number without a filename which is none too helpful.

2 Hint: you have to use alert() to see any useful output in the command window, then flick back to the browser to see the popup.