Re: typeof document.all

On Oct 12, 2009, at 2:38 PM, Brendan Eich wrote:

> On Oct 12, 2009, at 1:44 PM, Maciej Stachowiak wrote:
>
>>> Right, of course -- but is 'all' supposed to be direct (or appear  
>>> to be that way), and not on any visible prototype? Or must it (by  
>>> hasOwnProperty) be a direct property of HTMLDocument.prototype?
>>
>> According to Web IDL as currently written, I believe it should be  
>> an "own" property.
>>
>>>
>>> This seems unimportant for interoperation based on what browsers  
>>> actually do so far. Must it be specified? If it must, what about  
>>> making it appear to be a direct ("own" in ES terms) property of  
>>> document? IIRC IE does that.
>>
>> I think Web IDL makes all non-method properties be "own" properties  
>> currently, so I think that is what is specified.
>
> Yes, but should these details be specified?

I have mixed feelings about these particular details being specified  
in Web IDL. Just stating facts in this case.

One relevant question is: will future programs care about the results  
of operations such as hasOwnProperty() or getOwnPropertyDescriptor()?  
Will it make things harder for them if the results are not consistent  
cross-browser?

It does seem that current code does not depend significantly on what  
is an own property and what is a prototype property (possibly a  
getter). But it seems to me that code wishing to extensively prototype- 
hack the DOM, or build a facade on top of the DOM, could benefit from  
these details being consistent.

In the past, we have learned that it's required to have global  
properties of the Window object with names like "HTMLInputElement" and  
properties named "prototype" which hold the prototype to be used for  
HTML input element instances, even though this was not spelled out by  
former specs. This leads me to assume by default that any browser  
differences on this are likely to create problems at some point (and  
in particular, as the bigger differences are smoothed out, smaller  
differences may start to matter more).

On the other hand, there are many potential performance tradeoffs to  
how exactly DOM attributes get implemented. This concern would be  
lessened if we could show that it's possible to use a variety of  
implementation strategies while getting consistent output from  
hasOwnProperty() and getOwnPropertyDescriptor().

> I realize I'm asking about leaving things unspecified. But the plain  
> fact is browsers don't agree today, so this can be considered. Lots  
> of specs (especially programming languages not interoperating across  
> the web, e.g. C and Scheme) are under-specified intentionally to  
> allow for diverse implementations and optimizations.
>
> I didn't want to assume that document.all had to be fully specified,  
> or to assume that, just because WebIDL does specify prototypes and  
> "own" status, that it is not forcing over-specification in this case.

Well, there's the general question of whether Web IDL should specify  
things to this level of detail for normal properties (which is a Web  
IDL question), and then if it does, the question of wether HTML5  
should be more loose for document.all specifically (perhaps by  
defining it completely outside IDL). I don't think document.all has a  
special need to be more loosely specified in this regard than other  
DOM attributes.

>
>
>>> I'm loath to volunteer Mozilla changing to match WebKit, unsinking  
>>> sunk costs and taking risks, but we might. Two issues stand in our  
>>> way:
>>>
>>> 1. The ES-purity point of ToBoolean(Object) -> true manded by all  
>>> ECMA-262 editions without host object exception, which is  
>>> reflected in our implementation, so it's not just a purity issue  
>>> for us (even if I'm not a purist about conformance).
>>
>> We had to make some minor changes to our JavaScript implementation  
>> to support this. I think the changes to support the Mozilla  
>> behavior would be quite a bit more extensive. The code that  
>> implements property accesses on Document (or any host object  
>> property access) has no way of knowing if the value will be used in  
>> a boolean context, as the rvalue of an assignment, as part of an  
>> object initializer, or whatever other cases behave unusually in  
>> Gecko. I think we considered doing something Gecko-like back in the  
>> day and decided it was more complicated.
>>
>> It would be useful if someone could explain the Gecko behavior in  
>> detail. I couldn't figure out exactly what it does either by  
>> testing or by reading the patch that implemented the behavior. Then  
>> we could consider technical pros and cons of both behaviors.
>
> Ok, but doing what you ask here doesn't address my point 1.

Maybe I misunderstood, but it sounded like your point 1 was really  
about implementation mechanics, not just a purity issue. I think I  
said above that the implementation mechanics were not that hard, and  
in text you snipped, I gave some of the details of our implementation.  
I don't really think either approach has full ES spec purity.  
Implementation difficulty is a more significant concern.

>
> We classify bytecode combinations implementing if, ?:, switch, {===,! 
> ==,==,!=} x {null,undefined} (null or undefined only on the right of  
> the operator, !, typeof, ||, &&, assignment, and property  
> initialization as "detecting" and suppress lazy creation of  
> document.all.
>
> (Testing showed that assignment to variables and initialisers led to  
> later detection, so we imputed detection to the = operator and the  
> property initialiser in d = {all: document.all}.)
>
> All other bytecode combinations are non-detecting and force lazy  
> creation of document.all.

Does anything different happen for the "detecting" bytecodes after  
lazy creation has occurred (didn't seem to in my testing)?

Do all looping constructs use different bytecodes in all cases? What  
about the comma operator? I noticed in testing that "detecting" taint  
seems to propagate through comma. Also through redundant grouping  
parentheses.

(Also, null and undefined equality comparisons seem to be special in  
either order, i.e. (null == document.all) is true, as is (document.all  
== null).)

Does the comparison have to be to constant undefined or null? It seems  
that comparing document.all for equality to "void 0" or an undefined  
local variable gives false.

What is it that makes (document.all == document.all) false? If I cheat  
and store document.all twice using functions for indirection, the  
stored values compare ==.

Regards,
Maciej

Received on Monday, 12 October 2009 23:46:56 UTC