!document.all == true

If there was a web technology museum, document.all would be one of the main displays. Implemented in IE4 it's been available to JavaScript developers since September 1997.

Just about one year later, W3C's DOM1 specification gave us two methods that made document.all obsolete, document.getElementById and getElementsByTagName. But as usual web developers had to cater for the browsers people use – and for several years onwards that meant using document.all to keep things working in IE4. We're still stuck with hundreds of thousands of legacy pages using it.

When Opera started working on implementing the DOM standard (getElementsByTagName is available since Opera 5, released in December 2000) and we all eagerly looked forward to seeing dynamic menus and fancy scripting stuff start working, it soon became pretty obvious that much of the DHTML content of the day built on document.all. So it was implemented – first as a sort of hack when we identified as IE, later always enabled.

Sometimes supporting document.all caused problems. It still does. We go through IE branches when we would rather run the standards-compatible ones. I guess Mozilla learnt from our problems when they implemented document.all some four years later. Mozilla implemented it with a twist: document.all would be there, but invisible – you couldn't test for it and decide to go down the IE branch of a script. Making an object "invisibly" present isn't possible by the ECMA-262 spec, so it is a sort of standards violation to do so – quoting developer Lars Thomas Hansen:

it requires support directly from the ecmascript engine for a non-null non-undefined non-constant object value whose boolean value is false. It's doable, and probably not too expensive, but its existence directly contradicts section 9.2 of ES-262, which requires every object value to be converted to "true"

– but apparently it has worked well for both Firefox and Safari.

In the latest snapshot of Opera 9.5 you can play with Opera's new "undetectable document.all" support. It's a BIG experiment that will change the behaviour of millions of scripts all over the web. We don't do quite what Safari or Mozilla do either, and of course we'll have to figure out whether this change improves or damages compatibility with web content in general. That's where you come in – please use this build for daily browsing if you can, we need as much testing mileage for this as practically possible.

Feedback on JavaScript problems specific to this build welcome in the desktopteam blog, in comments below or as bug reports!

Advertisements

27 thoughts on “!document.all == true

  1. I dislike that Opera defines document.all during standards mode. (Firefox only defines document.all during quirks mode.)In both Firefox quirks mode and Opera 9.5, the test for ("all" in document) is true. I know the "in" operator isn't used very much, but If Opera is going to differ from Firefox, it might as well do a better job of hiding document.all than Firefox does.

  2. Maybe you should resurrect connection between document.all and identification? (Off when IDing as Firefox, On when IDing as IE, quantum-superposition by default 😉

  3. HeroreV: The purpose of hiding document.all is to prevent scripts from entering IE-specific code. A script author savvy enough to use ('all' in document) in unlikely to be writing such code.

  4. I think this is a good idea, Hallvord, by the Opera team. :)I'm having good luck with Build 4622 in my daily browsing, except for a couple sites I'll note at the ODT blog.Can you explain for us any ramifications of cloaking document.all relating to user-agent strings that Opera changes for a few sites like WSJ.com and MSNBC.com…?? <porneL> just asked also, I think. 🙂

  5. HeroreV: good point. I haven't considered that (probably because document.all support in Opera predates the doctype switching stuff so I've never made any connection).kamalesh: document.all basically doesn't relate to user-agent strings at all, except that some scripts use it to "detect" IE in a simpler way than parsing the user-agent string.

  6. I don't know whether it's because of document.all implementation, but the site http://www.mandrivaclub.pl/forum/index2 does not look as it should be, and not as it was on previous Opera build.I'm using Opera (downloaded as a shared qt rpm-file) 9.5 Beta 2 build 1772 on Mandriva 2008.0. The top of the site seems messed up.

  7. I think document.all could be hidden much better. It still is able to return values that evaluate to true.

    javascript:alert(document.all&&false)

    returns a true value in opera: "[object HTMLCollection]"It would be beneficial if there was no incarnation of document.all that could return a true value. It would also be sensible to hide it until masked as IE or in quirksmode as suggested.

  8. returns a true value in opera: "[object HTMLCollection]"

    nah.. it's return's an object which always evaluates to false, but toString returns what you see.

  9. document.all returns that object that then evaluates to a non-empty string which is true. Thats the problem. Perhaps toString should return the keyword value of undefined. It's illogical for any incarnation of a true value to be returned from document.all&&false. Unless excplicitly called, doc.all.toString should return some value that evals to false.

  10. This wasn't necessarily designed to be logical, just to evade the broken "isIE" sniffers we have had problems with, and hack the ECMAScript engine as little as posible in order to do so – which is a sensible goal for general correctness, maintainability and performance reasons. I disagree that we "should" do anything more unless the current implementation is proven insufficient and breaks scripts. Laziness can be a virtue 🙂

  11. On mandrivaclub.pl – they certainly use document.all "browser detection", look at the top function here:http://www.mandrivaclub.pl/forum/templates/strefa/rekl.js . Actually it's a typical example of a sniffer that will now return a different result (and a fairly braindead sniffer at that, since it first "detects" us as Opera, then proceeds to overwrite that result by "detecting" either IE, Netscape or Mozilla..). I don't have time to investigate the problems right now but will follow up.

  12. A bit unrelated but I'm still not using these snapshots for M2, just for browsing. M2 is too unpredictable in this Beta 2 version. But so far so good, no problems with browsing.

  13. Originally posted by hallvors:

    On mandrivaclub.pl – they certainly use document.all "browser detection", look at the top function here:

    They do, and because they use repeated "if" instead of "else if", they now detect Opera as "MO" instead of "OP". However, that function never gets used, so the browser version is always undefined, no matter what browser you use. Must be something else for us to look into ;)Edit:Got it. Known issue. Already fixed in core. Extra } in one of the stylesheets causes the rest of it to be ignored.

  14. @GoJoeGo: Did you read the same blog post I did? No, its just more well hidden. We are trying harder to not be identified as IE so I figured we'd stop acting like IE as well. document.getElementById was fixed in the first build of kestrel. Not sure why gEBN is lagging behind…

  15. @GoJoeGo: They are removing our chances of being ID'd as IE accidentally. @Hallvord: Any chance that window.opera will be cloaked when masking as FF/IE?

  16. fearphage: firstly we're still worried about what sites we might break if we fix the ugly getElementsByName IE-bug-compat behaviour.We don't currently plan to hide window.opera either. I should probably have a look and try to find sites where that might make a difference.

  17. Do other standards-compliant browsers switch getElementsByName into IE-compatible mode? As far as I can tell, ff doesn't. Do you have a list of sites that rely on IE-compatible getElementsByName? Can it be shared? How do ff and webkit work on those sites?

  18. With due respect to Lars (and the respect due him is immense!), document.all behaviour in Firefox and Safari doesn't contravene ECMA 262, though an object with magic conversion behaviour would as he describes. Rather, document's getter for "all" sometimes returns an object, and sometimes returns undefined, depending on the context in which it's accessed. ECMA 262 goes out of its way to permit arbitrary host-object behaviour, which is why document.forms or the dynamic-update capabilities of NodeLists are possible at all.

  19. shaver (first name Mike, right? 😉 ): true, neither Mozilla nor Opera actually went as far as implementing that ES-262 violating object evaluating to false, because it seems that few lesser hacks are sufficient.I'll be a bit more detailed on what exactly we do (and what Mozilla/Safari appear to do) in the future when I know if our implementation will stay what it is.

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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