Some DOM related comments

In 1.3.1: I think the issues related to prototype delegation have to
be addressed. More specifically:

- DOM methods should be specified in the ECMAScript bindings to have
the [[Prototype]] internal property set to the initial Function
prototype.

    document.appendChild instanceof Function

    // Results:
    //     WebKit/saf1.3: false
    //     Presto/op9.50: true
    //     Trident/ie6: false
    //     Gecko 1.8: true


- DOM methods should either be specified in the ECMAScript bindings to
work with any this value with a certain value of the [[Class]]
internal property or be specified to entirely ignore the this value
and only use the original instance. (Throwing an exception would be
inappropriate for this.) The choice of which should not be left
unspecified.

    var
        div=document.createElement('div'),
        span=document.createElement('span'),
        text=document.createTextNode('What am I?');
    Function.prototype.call.call(div.appendChild,span,text);
    // That's equivalent to
    //     div.appendChild.call(span.text)
    // but will work even if the DOM method doesn't delegate to Function
    text.data+='\r\nā€” I\'m a '+text.parentNode.tagName;

    // Results:
    //     Webkit/saf1.3: SPAN
    //     Presto/op9.50: SPAN
    //     Trident/ie6: DIV
    //     Gecko 1.8: Uncaught exception:
    //         [Exception... "Illegal operation on WrappedNative
prototype object"
    //         nsresult: "0x8057000c (NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)"
    //         ...
    //         ]



In 1.3.1: Maybe referring to the ECMAScript ToBoolean, ToNumber,
ToInteger, ToInt32, ToUInt32, ToInt16, ToString algorithms for
implicit type conversions is appropriate? (The return types of
ToInteger, ToInt32, ToUInt32, ToInt16 is not specified but assumed
elsewhere to be the Number type and not a hardware integral type.)
E.g.: When constraining array length to uint32, the ECMAScript
specification states that an implementation should throw a RangeError
if the result of passing the value through the ToNumber algorithm and
the result of passing the value through the ToUint32 algorithm are not
equal.

~~~~<ECMA-262 3ed>~~~~
15.4.5.1 [[Put]] (P, V)
Array objects use a variation of the [[Put]] method used for other
native ECMAScript objects (8.6.2.2).
Assume A is an Array object and P is a string.
When the [[Put]] method of A is called with property P and value V,
the following steps are taken:
1. Call the [[CanPut]] method of A with name P.
2. If Result(1) is false, return.
3. If A doesn't have a property with name P, go to step 7.
4. If P is "length", go to step 12.
5. Set the value of property P of A to V.
6. Go to step 8.
7. Create a property with name P, set its value to V and give it empty
attributes.
8. If P is not an array index, return.
9. If ToUint32(P) is less than the value of the length property of A,
then return.
10. Change (or set) the value of the length property of A to ToUint32(P)+1.
11. Return.
12. Compute ToUint32(V).
13. If Result(12) is not equal to ToNumber(V), throw a RangeError exception.
14. For every integer k that is less than the value of the length
property of A but not less than Result(12), if A itself has a property
(not an inherited property) named ToString(k), then delete that
property.
15. Set the value of property P of A to Result(12).
~~~~</ECMA-262 3ed>~~~~

A bit more layman-friendly formulation than that would be necessary, of course:)



In 2.6: You define behaviour for Element.setAttributeNode and
Element.setAttribute to always lowercase the name.
NamedNodeMap.setNamedItem should be specified to the same behaviour.



In 3.16.1 or WF2 : I feel the HTMLDocument.getElementsByName method of
DOM2HTML is misplaced since form control names are scoped to forms and
not documents, and would be more fit on HTMLFormElement.
HTMLFormElement.getElementsByName should then have behaviour similar
to that of the HTMLFormElement.elements collection.




Finally: (Pretty sure this is not the realm of the HTML WG, but I'll
mention it anyway.)
The DOM should always specify whether a type is nullable or not and if
nullable how DOM methods are to behave if passed null. Currently Node
type properties may be null (e.g. Node.firstChild) but there is no
text on whether methods with Node type arguments (e.g.
Node.appendChild) may be passed null or what to do in those cases. If
the Node type for properties is nullable but the Node type for
arguments isn't then they should not be using the same type name but
be distinct. If they are indeed both nullable types then the DOM
methods need to specify the case of what to do with a null argument.
The Node.insertBefore method has a case of the Node type argument
refChild having a defined behaviour when passed null ā€” thus suggesting
Node type is indeed nullable in both cases ā€” but this is not the case
for many other Node type arguments to several DOM methods.
Also ECMAScript allows any arguments to be sent to any function and
formal parameters not present in the arguments sent to a function are
set to undefined (meaning a missing argument and an argument of
undefined should have exactly the same result), thus the ECMAScript
bindings also need to specify what behaviour passing the wrong type of
object gives. All major browsers currently handle these things very
differently from each other, and not necessarily internally
consistent:


    div.appendChild();

    // Results (error.name, error.message, error.toString()):
    //     Webkit/saf1.3: Error, DOM Exception 8, Error - DOM Exception 8
    //     Presto/op9.50: , WRONG_ARGUMENTS_ERR, [object InternalException]
    //     Trident/ie6: Error, Invalid Pointer, [object Error]
    //     Gecko 1.8:
    //         NS_ERROR_XPC_NOT_ENOUGH_ARGS,
    //         ,
    //         [Exception... "Not enough arguments"
    //         nsresult: "0x80570001 (NS_ERROR_XPC_NOT_ENOUGH_ARGS)"
    //         ...
    //         ]


    div.appendChild(undefined);

    // Results (error.name, error.message, error.toString()):
    //     Webkit/saf1.3: Error, DOM Exception 8, Error - DOM Exception 8
    //     Presto/op9.50: , WRONG_ARGUMENTS_ERR, [object InternalException]
    //     Trident/ie6: Error, Type mismatch., [object Error]
    //     Gecko 1.8:
    //         NS_ERROR_INVALID_POINTER,
    //         Component returned failure code: 0x80004003
(NS_ERROR_INVALID_POINTER) [nsIDOMHTMLDivElement.appendChild],
    //         [Exception... "Component returned failure code:
0x80004003 (NS_ERROR_INVALID_POINTER)
[nsIDOMHTMLDivElement.appendChild]"
    //         nsresult: "0x80004003 (NS_ERROR_INVALID_POINTER)"
    //         ...
    //         ]

    div.appendChild(null);

    // Results:
    //     Webkit/saf1.3: Error, DOM Exception 8, Error - DOM Exception 8
    //     Presto/op9.50: , WRONG_ARGUMENTS_ERR, [object InternalException]
    //     Trident/ie6: Error, Invalid pointer, [object Error]
    //     Gecko 1.8:
    //         NS_ERROR_INVALID_POINTER,
    //         Component returned failure code: 0x80004003
(NS_ERROR_INVALID_POINTER) [nsIDOMHTMLDivElement.appendChild],
    //         [Exception... "Component returned failure code:
0x80004003 (NS_ERROR_INVALID_POINTER)
[nsIDOMHTMLDivElement.appendChild]"
    //         nsresult: "0x80004003 (NS_ERROR_INVALID_POINTER)"
    //         ...
    //         ]

    div.appendChild({});

    // Results:
    //     Webkit/saf1.3: Error, DOM Exception 8, Error - DOM Exception 8
    //     Presto/op9.50: , WRONG_ARGUMENTS_ERR, [object InternalException]
    //     Trident/ie6: Error, No such interface supported, [object Error]
    //     Gecko 1.8:
    //         NS_ERROR_DOM_HIERARCHY_REQUEST_ERR,
    //         Node cannot be inserted at the specified point in the hierarchy,
    //         [Exception... "Node cannot be inserted at the specified
point in the hierarchy"
    //         code: "3"
    //         nsresult: "0x80530003 (NS_ERROR_DOM_HIERARCHY_REQUEST_ERR)"
    //         ...
    //         ]

I'm of the opinion that if the error lies in the ECMAScript code
passing the wrong type, that should always be defined to result in a
certain DOMException being thrown and never result in an uncaught
implementation specific exception, nor should which exception is
appropriate be left uncertain.
-- 
David "liorean" Andersson

Received on Saturday, 2 June 2007 06:43:14 UTC