Microsoft’s Skydrive: gun, meet foot

I remember my first encounter with Microsoft's Atlas framework and the AtlasCompat.js file – being launched on back in 2005 or so. Back in those early days of JavaScript frameworks – jQuery 1.0 wasn't shipped until a year later – I had still seen lots of libraries and common utility scripts. Most of them had one thing in common: they would work hard to work around Internet Explorer's DOM bugs and try to make it behave more according to the W3C specs.

AtlasCompat.js was different. With confusion and some amusement we noticed that it did exactly the opposite: attempted to implement Internet Explorer's non-standard features in all other browsers.

Actually, for Opera this approach was generally useless – we had already been forced to support document.all, event.srcElement and friends in the endless quest to get scripts out there working. On one particularly painful point we had stuck to the W3C spec though: the return values of event.button. In Opera and other W3C-loving browsers clicking the left mouse button sets event.button to 0, in Internet Explorer the value to indicate the left button was clicked is 1. With no clean way to tell whether a browser supported the W3C or the IE way, browser sniffing, confusion and broken stuff was the inevitable result.

Because Microsoft wanted to let all programmers write code the IE way, they defined a getter returning "1" for event.button as part of the Atlas framework. (Then a couple of years later, Hotmail was broken because their code expected event.button to be "1" but that piece of compat scripting didn't run in Opera for some reason..)

This week, I've been looking at the newly updated Microsoft Skydrive and their online version of Microsoft Office. The first problem was pretty noticeable: having opened a Word document in "preview only" mode, I could not open it in the Word webapp. In fact, no links or buttons would respond at all.

Wasn't there something familiar about this problem..? Much like Hotmail used to behave because of event.button problems..?

Stepping through the code a bit made me somewhat confused. Unlike all Microsoft's code from up to and including the previous iteration of Hotmail, this code actually expects event.button to be 0. Even Microsoft's JavaScript coders use W3C's event.button values now?!? That's a sign of standardisation progress, I guess :).

However, in Opera, only on Skydrive, event.button actually returned 1. Like in IE6. And I did double-check and triple-check browser.js to make sure we had no obsolete workarounds in there..

We don't. But Microsoft has:

w.Event.prototype.__defineGetter__("button", function() { 
 return this.which == 1 ? 1 : this.which == 3 ? 2 : 0 

Gun, meet foot. So, first they tell us that event.button should be 1, then the rest of the code will only work as intended when it's 0?

It's sort of the opposite of what Hotmail used to do – Hotmail forgot the compat code and expected it to have some effect anyway, here they include the compat code but expect it to have no effect.

Well, why doesn't it break Skydrive in Chrome and Firefox? Presumably if it broke the site in one of the web browsers they actually test with, it would be detected and fixed?

Simply because Opera is trying to hard to be developer-friendly and easy to extend. You can define a 'button' getter on Event.prototype or on MouseEvent.prototype, either will work in Opera but only the latter works in Firefox and neither works in WebKit. Or, to quote the developer investigating this:

Interesting variation in behaviour on display here. If you use this instead:

Object.defineProperty(MouseEvent.prototype, "button", {get: function() { return 'b';}});
Object.defineProperty(Event.prototype, "type", {get: function() { return 't';}});
window.onclick = function(e) { document.write(e.type + e.button); };

– FF will pick up the getter for "button"..but not if you put the button getter on Event.prototype instead. Same for "type".
– WebKit doesn't invoke any of the getters, if provided on either Event.prototype or MouseEvent.prototype.
(In combination with FF's behaviour, I guess that explains the behaviour of the above.)
– Carakan will chase up the prototype chain looking for a getter, so it doesn't matter if the getter is defined on
MouseEvent or will be found.
– IE has another variation: it will use the getter for 'button' on MouseEvent and a getter for "type" at either MouseEvent or Event.

For some reason the web still works given that range of behaviour.

And the end result of that mess is that only Opera gives Skydrive the gun with which it shoots itself in the foot.


2 thoughts on “Microsoft’s Skydrive: gun, meet foot

  1. Even Microsoft's JavaScript coders use W3C's event.button values now?

    Feeling Hot & Lively with the SkyDriveThe twitter account @SkyDrive tho Poke @MicrosoftHelps

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s