ECMAScript binding tests

This page details some differences between ECMAScript bindings implementations in different UAs. For each script, the (stringification of the) contents of the result variable is shown. Some of the scripts use some utility functions.

Tests

Show only , , , , and .

001 — Exposing interfaces as a property on the global object
Script
result = this.Node + '\n' + typeof this.Node
Firefox 2.0.0.3
[Node]
function
Firefox 3.0a5pre (20070522)
[object Node]
object
Opera 9.20
function Node() { [native code] }
function
WebKit r21612
[object NodeConstructor]
object
Internet Explorer 7
undefined
undefined
This browser
CommentsAll browsers except IE have an object representing the interface. Firefox 2 and Opera 9 use a function object and the others have a plain object.
002 — What properties are exposed on the Node interface object
Script
result = all(Node)
Firefox 2.0.0.3
ATTRIBUTE_NODE
CDATA_SECTION_NODE
COMMENT_NODE
DOCUMENT_FRAGMENT_NODE
DOCUMENT_NODE
DOCUMENT_POSITION_CONTAINED_BY
DOCUMENT_POSITION_CONTAINS
DOCUMENT_POSITION_DISCONNECTED
DOCUMENT_POSITION_FOLLOWING
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
DOCUMENT_POSITION_PRECEDING
DOCUMENT_TYPE_NODE
ELEMENT_NODE
ENTITY_NODE
ENTITY_REFERENCE_NODE
NOTATION_NODE
PROCESSING_INSTRUCTION_NODE
QueryInterface
TEXT_NODE
Firefox 3.0a5pre (20070522)
ATTRIBUTE_NODE
CDATA_SECTION_NODE
COMMENT_NODE
DOCUMENT_FRAGMENT_NODE
DOCUMENT_NODE
DOCUMENT_POSITION_CONTAINED_BY
DOCUMENT_POSITION_CONTAINS
DOCUMENT_POSITION_DISCONNECTED
DOCUMENT_POSITION_FOLLOWING
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
DOCUMENT_POSITION_PRECEDING
DOCUMENT_TYPE_NODE
ELEMENT_NODE
ENTITY_NODE
ENTITY_REFERENCE_NODE
NOTATION_NODE
PROCESSING_INSTRUCTION_NODE
QueryInterface
TEXT_NODE
Opera 9.20
ATTRIBUTE_NODE
CDATA_SECTION_NODE
COMMENT_NODE
DOCUMENT_FRAGMENT_NODE
DOCUMENT_NODE
DOCUMENT_TYPE_NODE
ELEMENT_NODE
ENTITY_NODE
ENTITY_REFERENCE_NODE
NOTATION_NODE
PROCESSING_INSTRUCTION_NODE
TEXT_NODE
prototype
WebKit r21612
ATTRIBUTE_NODE
CDATA_SECTION_NODE
COMMENT_NODE
DOCUMENT_FRAGMENT_NODE
DOCUMENT_NODE
DOCUMENT_TYPE_NODE
ELEMENT_NODE
ENTITY_NODE
ENTITY_REFERENCE_NODE
NOTATION_NODE
PROCESSING_INSTRUCTION_NODE
TEXT_NODE
prototype
Internet Explorer 7
exception thrown: [object Error]
'Node' is undefined
This browser
CommentsNon-IE browsers expose all of the Node constants on the Node interface object. (Firefox 2 and 3 have the DOM 3 Core constants; Opera and WebKit have the DOM 2 Core constants.) The Firefoxes also have an enumerable QueryInterface property, which presumably is some XPCOM thing. The Firefoxes, Opera and WebKit all have a prototype property (as demonstrated in test 007), but in the Firefoxes it is DontEnum.
003 — Calling the Node interface object as a function
Script
result = Node()
Firefox 2.0.0.3
exception thrown: TypeError: Node is not a function
Firefox 3.0a5pre (20070522)
exception thrown: TypeError: Node is not a function
Opera 9.20
exception thrown: [object DOMException]
NOT_SUPPORTED_ERR Backtrace: Line 6 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=003 result = Node(); return result; Line 6 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=003 (function () { result = Node(); return result; } )();
WebKit r21612
exception thrown: TypeError: Object [object NodeConstructor] (result of expression Node) does not allow calls.
Internet Explorer 7
exception thrown: [object Error]
Object expected
This browser
CommentsDespite Firefox 2 and Opera 9 indicating that the Node interface object is also a function, calling it performs nothing useful. (Technically, since the Node interface object is a host object, the typeof operator could return anything, so "function" doesn't necessarily mean that you can [[Call]] it.) Opera throws a NOT_SUPPORTED_ERR DOMException, while WebKit throws a TypeError exception.
004 — Get [[Class]] property of Node interface object
Script
result = __Class__(Node)
Firefox 2.0.0.3
Constructor
Firefox 3.0a5pre (20070522)
Prototype
Opera 9.20
Node
WebKit r21612
NodeConstructor
Internet Explorer 7
exception thrown: [object Error]
'Node' is undefined
This browser
CommentsA different [[Class]] name is used for the Node interface object in those browsers that have one.
005 — Try using [[Construct]] on the Node interface object
Script
result = new Node()
Firefox 2.0.0.3
exception thrown: [Exception... "Object cannot be created in this context" code: "9" nsresult: "0x80530009 (NS_ERROR_DOM_NOT_SUPPORTED_ERR)" location: "http://mcc.id.au/2007/05/binding-tests/ Line: 270"] (code 9)
Firefox 3.0a5pre (20070522)
exception thrown: [Exception... "Cannot convert WrappedNative to function" nsresult: "0x8057000d (NS_ERROR_XPC_CANT_CONVERT_WN_TO_FUN)" location: "JS frame :: http://mcc.id.au/2007/05/binding-tests/ :: anonymous :: line 250" data: no]
Opera 9.20
exception thrown: [object DOMException] (code 9)
NOT_SUPPORTED_ERR Backtrace: Line 6 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=005 result = new Node(); return result; Line 6 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=005 (function () { result = new Node(); return result; } )();
WebKit r21612
exception thrown: TypeError: Value [object NodeConstructor] (result of expression Node) is not a constructor. Cannot be used with new.
Internet Explorer 7
exception thrown: [object Error]
'Node' is undefined
This browser
CommentsWhen trying to use the Node interface object as a constructor (on those browsers that have such an object), an exception is thrown. Firefox 2 and Opera 9 throw a NOT_SUPPORTED_ERR DOMException, while Firefox 3 throws some XPCOM-related exception and WebKit throws a TypeError.
006 — Test [[HasInstance]] on the Node interface object
Script
result = document instanceof Node
Firefox 2.0.0.3
true
Firefox 3.0a5pre (20070522)
true
Opera 9.20
true
WebKit r21612
true
Internet Explorer 7
exception thrown: [object Error]
'Node' is undefined
This browser
CommentsOn the non-IE browsers, [[HasInstance]] identifies the Node interface object's prototype object as being in the prototype chain of the document object.
007 — Look at the prototype and [[Prototype]] of the Node interface object
Script
result = 'Node.prototype                             == ' + Node.prototype + '\n'
       + 'Node.prototype.[[Class]]                   == ' + __Class__(Node.prototype) + '\n'
       + '(document.[[Prototype]] == Node.prototype) == ' + Object.prototype.isPrototypeOf.apply(Node.prototype, [document]) + '\n'
Firefox 2.0.0.3
Node.prototype                             == [object DOM Constructor.prototype]
Node.prototype.[[Class]]                   == DOM Constructor.prototype
(document.[[Prototype]] == Node.prototype) == true
Firefox 3.0a5pre (20070522)
Node.prototype                             == [object DOM Constructor.prototype]
Node.prototype.[[Class]]                   == DOM Constructor.prototype
(document.[[Prototype]] == Node.prototype) == true
Opera 9.20
Node.prototype                             == [object Object]
Node.prototype.[[Class]]                   == Object
(document.[[Prototype]] == Node.prototype) == true
WebKit r21612
Node.prototype                             == [object NodePrototype]
Node.prototype.[[Class]]                   == NodePrototype
(document.[[Prototype]] == Node.prototype) == true
Internet Explorer 7
exception thrown: [object Error]
'Node' is undefined
This browser
CommentsThe non-IE browsers all have an object as the value of the prototype property on the Node interface object. Firefox, Opera and WebKit all have different [[Class]] names for their prototype object. This prototype object is confirmed to be in the prototype chain of the document object.
008 — What properties are exposed on the Node.prototype object
Script
result = all(Node.prototype)
Firefox 2.0.0.3

Firefox 3.0a5pre (20070522)

Opera 9.20
addEventListener
appendChild
attachEvent
cloneNode
detachEvent
dispatchEvent
getFeature
hasAttributes
hasChildNodes
insertBefore
isDefaultNamespace
isSupported
lookupNamespaceURI
lookupPrefix
normalize
removeChild
removeEventListener
replaceChild
selectNodes
selectSingleNode
WebKit r21612
ATTRIBUTE_NODE
CDATA_SECTION_NODE
COMMENT_NODE
DOCUMENT_FRAGMENT_NODE
DOCUMENT_NODE
DOCUMENT_TYPE_NODE
ELEMENT_NODE
ENTITY_NODE
ENTITY_REFERENCE_NODE
NOTATION_NODE
PROCESSING_INSTRUCTION_NODE
TEXT_NODE
appendChild
cloneNode
hasAttributes
hasChildNodes
insertBefore
isDefaultNamespace
isEqualNode
isSameNode
isSupported
lookupNamespaceURI
lookupPrefix
normalize
removeChild
replaceChild
Internet Explorer 7
exception thrown: [object Error]
'Node' is undefined
This browser
CommentsOpera has each of the Node methods as an enumerable property on the Node prototype object, while WebKit has the Node methods plus the constants. The Firefoxes have no enumerable properties on the Node prototype object.
009 — Try deleting a property of the Node.prototype object
Script
result = 'Node.prototype.appendChild        == ' + String(Node.prototype.appendChild).replace(/\n/g, ' ') + '\n'
       + 'delete Node.prototype.appendChild == ' + delete Node.prototype.appendChild + '\n'
       + 'Node.prototype.appendChild        == ' + String(Node.prototype.appendChild).replace(/\n/g, ' ') + '\n'
Firefox 2.0.0.3
Node.prototype.appendChild        == undefined
delete Node.prototype.appendChild == true
Node.prototype.appendChild        == undefined
Firefox 3.0a5pre (20070522)
Node.prototype.appendChild        == undefined
delete Node.prototype.appendChild == true
Node.prototype.appendChild        == undefined
Opera 9.20
Node.prototype.appendChild        ==  function appendChild() { [native code] }
delete Node.prototype.appendChild == true
Node.prototype.appendChild        == undefined
WebKit r21612
Node.prototype.appendChild        ==  function appendChild() {     [native code] } 
delete Node.prototype.appendChild == true
Node.prototype.appendChild        ==  function appendChild() {     [native code] } 
Internet Explorer 7
exception thrown: [object Error]
'Node' is undefined
This browser
CommentsThe Firefoxes don't have the Node methods as properties of the Node prototype object at all. Using [[Delete]] on one of the methods returns true, regardless of whether the browser has such a property on the Node prototype object. Opera does allow you to delete the method, while WebKit does not. (This could indicate either that WebKit has the methods set to DontDelete, or they may be in a prototype object further up the chain.)
010 — Try adding a property into the Node.prototype object
Script
Node.prototype.abc = 123;
result = 'Node.prototype.abc == ' + Node.prototype.abc + '\n'
       + 'document.abc       == ' + document.abc + '\n'
Firefox 2.0.0.3
Node.prototype.abc == 123
document.abc       == 123
Firefox 3.0a5pre (20070522)
Node.prototype.abc == 123
document.abc       == 123
Opera 9.20
Node.prototype.abc == 123
document.abc       == 123
WebKit r21612
Node.prototype.abc == 123
document.abc       == 123
Internet Explorer 7
exception thrown: [object Error]
'Node' is undefined
This browser
CommentsAll of the non-IE browsers allow you to create a new property on the Node prototype object and for it then to be accessed on the document object.
011 — Try replacing an existing property on the Node.prototype object
Script
Node.prototype.hasChildNodes = function() { return 'You bet it does' };
result = 'document.hasChildNodes() == ' + document.hasChildNodes()
Firefox 2.0.0.3
document.hasChildNodes() == true
Firefox 3.0a5pre (20070522)
document.hasChildNodes() == true
Opera 9.20
document.hasChildNodes() == You bet it does
WebKit r21612
document.hasChildNodes() == You bet it does
Internet Explorer 7
exception thrown: [object Error]
'Node' is undefined
This browser
CommentsThe Firefoxes do not allow the replacement of an object on the Node prototype object, but Opera and WebKit do.
012 — Test getting one of the Node constants from the Node.prototype object, from an actual instance of Node, then test overwriting it on the Node.prototype object
Script
result = 'Node.prototype.DOCUMENT_NODE == ' + Node.prototype.DOCUMENT_NODE + '\n'
       + 'document.DOCUMENT_NODE       == ' + document.DOCUMENT_NODE + '\n';
Node.prototype.DOCUMENT_NODE = 123;
result += 'now, document.DOCUMENT_NODE  == ' + document.DOCUMENT_NODE + '\n';
Firefox 2.0.0.3
Node.prototype.DOCUMENT_NODE == undefined
document.DOCUMENT_NODE       == 9
now, document.DOCUMENT_NODE  == 9
Firefox 3.0a5pre (20070522)
Node.prototype.DOCUMENT_NODE == undefined
document.DOCUMENT_NODE       == 9
now, document.DOCUMENT_NODE  == 9
Opera 9.20
Node.prototype.DOCUMENT_NODE == undefined
document.DOCUMENT_NODE       == undefined
now, document.DOCUMENT_NODE  == 123
WebKit r21612
Node.prototype.DOCUMENT_NODE == 9
document.DOCUMENT_NODE       == 9
now, document.DOCUMENT_NODE  == 9
Internet Explorer 7
exception thrown: [object Error]
'Node' is undefined
This browser
CommentsOpera is the only browser to allow redefining one of the Node constants, and it doesn't have the constant on the Node prototype object anyway.
013 — Try deleting the Node interface object
Script
result = 'Before: ' + (typeof this.Node == 'undefined' ? 'undefined' : Node) + '\n';
delete this.Node;
result += 'After:  ' + this.Node + '\n';
Firefox 2.0.0.3
Before: [Node]
After:  [Node]
Firefox 3.0a5pre (20070522)
Before: [object Node]
After:  [object Node]
Opera 9.20
exception thrown: [Error: name: ReferenceError message: Statement on line 8: Reference to undefined variable: Node Backtrace: Line 8 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=013 result += "After: " + Node + "\n"; Line 10 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=013 (function () { result = "Before: " + (typeof this.Node == "undefined" ? "undefined" : Node) + "\n"; delete this.Node; result += "After: " + Node + "\n"; } )(); ]
WebKit r21612
Before: [object NodeConstructor]
After:  [object NodeConstructor]
Internet Explorer 7
exception raised: [object Error]
Object doesn't support this action
This browser
CommentsOpera is the only browser to allow deleting the Node interface object.
014 — Try overwriting the Node interface object
Script
result = 'Before: ' + (typeof this.Node == 'undefined' ? 'undefined' : Node) + '\n';
this.Node = null;
result += 'After:  ' + Node + '\n';
Firefox 2.0.0.3
Before: [Node]
After:  null
Firefox 3.0a5pre (20070522)
Before: [object Node]
After:  null
Opera 9.20
Before: 
function Node() { [native code] }
After:  null
WebKit r21612
Before: [object NodeConstructor]
After:  null
Internet Explorer 7
Before: undefined
After:  null
This browser
CommentsAll browsers allow writing to the the Node interface object property.
015 — Test if the html element has a constructor property and if it's equal to the HTMLHtmlElement interface object
Script
result = document.documentElement.constructor + '\n'
       + this.HTMLHtmlElement + '\n'
       + (document.documentElement.constructor == this.HTMLHtmlElement)
Firefox 2.0.0.3
[HTMLHtmlElement]
[HTMLHtmlElement]
true
Firefox 3.0a5pre (20070522)
[object HTMLHtmlElement]
[object HTMLHtmlElement]
true
Opera 9.20
function Object() { [native code] }

function HTMLHtmlElement() { [native code] }
false
WebKit r21612
[function]
[object HTMLHtmlElementConstructor]
false
Internet Explorer 7
undefined
undefined
true
This browser
CommentsAll non-IE browsers have a constructor property, however only the Firefoxes use the interface object as the value of that property; Opera and WebKit use some other object.
016 — Try modifying the a prototype through the constructor property
Script
result = document.documentElement.constructor.prototype + '\n'
       + (document.documentElement.constructor.prototype == HTMLHtmlElement.prototype) + '\n'
document.documentElement.constructor.prototype.abc = 123;
result += document.documentElement.abc;
Firefox 2.0.0.3
[xpconnect wrapped native prototype]
true
123
Firefox 3.0a5pre (20070522)
[xpconnect wrapped native prototype]
true
123
Opera 9.20
[object Object]
123
WebKit r21612
[object Object]
false
123
Internet Explorer 7
exception thrown: [object Error]
'document.documentElement.constructor.prototype' is null or not an object
This browser
CommentsIn the non-IE browsers, adding a property to the .constructor.prototype object of a DOM node object results in the property being visible from that node object, even though the .constructor.prototype object isn't the same as the HTMLHtmlElement.prototype object.
017 — Check the type mapping of DOMTimeStamp
Script
window.onload =
  function(evt) {
    try {
      result = evt.timeStamp + '\n' + typeof evt.timeStamp;
    } catch (e) {
      result = showException(e);
    }
  };
Firefox 2.0.0.3
0
number
Firefox 3.0a5pre (20070522)
0
number
Opera 9.20
0
number
WebKit r21612
1180248713919
number
Internet Explorer 7
exception thrown: [object Error]
'timeStamp' is null or not an object
This browser
CommentsAll browsers (except IE, which doesn't have the timeStamp property on event objects) use a number to represent a DOMTimeStamp, and not a Date object as DOM Core specifies. (Also, WebKit is the only one that sets a non-zero value for the property.) See also ISSUE-52.
018 — Try passing values of incorrect types to a function expecting a Node
Script
var xs = [undefined, false, 0, 'abc', { }];
result = '';
for (var i = 0; i < xs.length; i++) {
  var x = xs[i];
  try {
    document.documentElement.appendChild(x);
    result += typeof x + ' ' + x + ' => no exception\n';
  } catch (e) {
    result += typeof x + ' ' + x + ' => ' + showException(e) + '\n';
  }
}
Firefox 2.0.0.3
undefined undefined => 
exception thrown: [Exception... "Component returned failure code: 0x80004003 (NS_ERROR_INVALID_POINTER) [nsIDOMHTMLHtmlElement.appendChild]" nsresult: "0x80004003 (NS_ERROR_INVALID_POINTER)" location: "JS frame :: http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 :: anonymous :: line 37" data: no]
boolean false =>
exception thrown: [Exception... "Could not convert JavaScript argument" nsresult: "0x80570009 (NS_ERROR_XPC_BAD_CONVERT_JS)" location: "JS frame :: http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 :: anonymous :: line 37" data: no]
null
number 0 =>
exception thrown: [Exception... "Could not convert JavaScript argument - 0 was passed, expected object. Did you mean null?" nsresult: "0x80570035 (NS_ERROR_XPC_BAD_CONVERT_JS_ZERO_ISNOT_NULL)" location: "JS frame :: http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 :: anonymous :: line 37" data: no]
string abc =>
exception thrown: [Exception... "Could not convert JavaScript argument" nsresult: "0x80570009 (NS_ERROR_XPC_BAD_CONVERT_JS)" location: "JS frame :: http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 :: anonymous :: line 37" data: no]
null
object [object Object] =>
exception thrown: [Exception... "Node cannot be inserted at the specified point in the hierarchy" code: "3" nsresult: "0x80530003 (NS_ERROR_DOM_HIERARCHY_REQUEST_ERR)" location: "http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 Line: 37"]
Firefox 3.0a5pre (20070522)
undefined undefined => 
exception thrown: [Exception... "Component returned failure code: 0x80004003 (NS_ERROR_INVALID_POINTER) [nsIDOMHTMLHtmlElement.appendChild]" nsresult: "0x80004003 (NS_ERROR_INVALID_POINTER)" location: "JS frame :: http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 :: anonymous :: line 37" data: no]
boolean false =>
exception thrown: [Exception... "Could not convert JavaScript argument arg 0 [nsIDOMHTMLHtmlElement.appendChild]" nsresult: "0x80570009 (NS_ERROR_XPC_BAD_CONVERT_JS)" location: "JS frame :: http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 :: anonymous :: line 37" data: no]
number 0 =>
exception thrown: [Exception... "Could not convert JavaScript argument - 0 was passed, expected object. Did you mean null? arg 0 [nsIDOMHTMLHtmlElement.appendChild]" nsresult: "0x80570035 (NS_ERROR_XPC_BAD_CONVERT_JS_ZERO_ISNOT_NULL)" location: "JS frame :: http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 :: anonymous :: line 37" data: no]
string abc =>
exception thrown: [Exception... "Could not convert JavaScript argument arg 0 [nsIDOMHTMLHtmlElement.appendChild]" nsresult: "0x80570009 (NS_ERROR_XPC_BAD_CONVERT_JS)" location: "JS frame :: http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 :: anonymous :: line 37" data: no]
object [object Object] =>
exception thrown: [Exception... "Node cannot be inserted at the specified point in the hierarchy" code: "3" nsresult: "0x80530003 (NS_ERROR_DOM_HIERARCHY_REQUEST_ERR)" location: "http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 Line: 37"]
Opera 9.20
undefined undefined => 
exception thrown: [object InternalException] WRONG_ARGUMENTS_ERR Backtrace: Line 13 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 document.documentElement.appendChild(x); Line 20 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 (function () { var xs = [undefined, false, 0, "abc", {}]; result = ""; for (var i = 0;i < xs.length;i++) { var x = xs[i]; try { document.documentElement.appendChild(x); result += x + " => no exception\n"; } catch (e) { result += x + " => " + showException(e) + "\n"; } } } )();
boolean false =>
exception thrown: [object InternalException] WRONG_ARGUMENTS_ERR Backtrace: Line 13 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 document.documentElement.appendChild(x); Line 20 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 (function () { var xs = [undefined, false, 0, "abc", {}]; result = ""; for (var i = 0;i > xs.length;i++) { var x = xs[i]; try { document.documentElement.appendChild(x); result += x + " => no exception\n"; } catch (e) { result += x + " => " + showException(e) + "\n"; } } } )();
number 0 =>
exception thrown: [object InternalException] WRONG_ARGUMENTS_ERR Backtrace: Line 13 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 document.documentElement.appendChild(x); Line 20 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 (function () { var xs = [undefined, false, 0, "abc", {}]; result = ""; for (var i = 0;i < xs.length;i++) { var x = xs[i]; try { document.documentElement.appendChild(x); result += x + " => no exception\n"; } catch (e) { result += x + " => " + showException(e) + "\n"; } } } )();
string abc =>
exception thrown: [object InternalException] WRONG_ARGUMENTS_ERR Backtrace: Line 13 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 document.documentElement.appendChild(x); Line 20 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 (function () { var xs = [undefined, false, 0, "abc", {}]; result = ""; for (var i = 0;i < xs.length;i++) { var x = xs[i]; try { document.documentElement.appendChild(x); result += typeof x + " " + x + " => no exception\n"; } catch (e) { result += typeof x + " " + x + " => " + showException(e) + "\n"; } } } )();
object [object Object] =>
exception thrown: [object InternalException] WRONG_ARGUMENTS_ERR Backtrace: Line 13 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 document.documentElement.appendChild(x); Line 20 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=018 (function () { var xs = [undefined, false, 0, "abc", {}]; result = ""; for (var i = 0;i < xs.length;i++) { var x = xs[i]; try { document.documentElement.appendChild(x); result += x + " => no exception\n"; } catch (e) { result += x + " => " + showException(e) + "\n"; } } } )();
WebKit r21612
undefined undefined => 
exception thrown: Error: NOT_FOUND_ERR: DOM Exception 8
boolean false =>
exception thrown: Error: NOT_FOUND_ERR: DOM Exception 8
number 0 =>
exception thrown: Error: NOT_FOUND_ERR: DOM Exception 8
string abc =>
exception thrown: Error: NOT_FOUND_ERR: DOM Exception 8
object [object Object] =>
exception thrown: Error: NOT_FOUND_ERR: DOM Exception 8
Internet Explorer 7
undefined undefined => 
exception thrown: [object Error] Type mismatch.
boolean false =>
exception thrown: [object Error] Type mismatch.
number 0 =>
exception thrown: [object Error] Type mismatch.
string abc =>
exception thrown: [object Error] Type mismatch.
object [object Object] =>
exception thrown: [object Error] No such interface supported
This browser
CommentsAll browsers throw an exception when trying to pass something other than a Node object to a function expecting a Node. The Firefoxes throw some browser-specific exception for all cases except when a (new, empty) native object is passed, in which case a HIERARCHY_REQUEST_ERR DOMException is curiously thrown. Opera throws a browser-specific exception in all cases. WebKit consistently throws a NOT_FOUND_ERR DOMException. Internet Explorer consistently throws an Error object.
019 — Try passing values of incorrect types to a function expecting a boolean
Script
var xs = [undefined, 0, 1, 2, new Boolean(false), new Boolean(true), '', 'abc', 'true', 'false', { }, document];
result = '';
for (var i = 0; i < xs.length; i++) {
  var x = xs[i];
  try {
    var elt = document.createElement('test');
    elt.appendChild(document.createElement('test2'));
    var clone = elt.cloneNode(x);
    result += typeof x + ' ' + x + ' => no exception, deep == ' + !!clone.firstChild + '\n';
  } catch (e) {
    result += typeof x + ' ' + x + ' => ' + showException(e) + '\n';
  }
}
Firefox 2.0.0.3
undefined undefined => no exception, deep == false
number 0 => no exception, deep == false
number 1 => no exception, deep == true
number 2 => no exception, deep == true
object false => no exception, deep == true
object true => no exception, deep == true
string  => no exception, deep == false
string abc => no exception, deep == true
string true => no exception, deep == true
string false => no exception, deep == true
object [object Object] => no exception, deep == true
object [object HTMLDocument] => no exception, deep == true
Firefox 3.0a5pre (20070522)
undefined undefined => no exception, deep == false
number 0 => no exception, deep == false
number 1 => no exception, deep == true
number 2 => no exception, deep == true
object false => no exception, deep == true
object true => no exception, deep == true
string  => no exception, deep == false
string abc => no exception, deep == true
string true => no exception, deep == true
string false => no exception, deep == true
object [object Object] => no exception, deep == true
object [object HTMLDocument] => no exception, deep == true
Opera 9.20
undefined undefined => no exception, deep == false
number 0 => no exception, deep == false
number 1 => no exception, deep == true
number 2 => no exception, deep == true
object false => no exception, deep == true
object true => no exception, deep == true
string  => no exception, deep == false
string abc => no exception, deep == true
string true => no exception, deep == true
string false => no exception, deep == true
object [object Object] => no exception, deep == true
object [object HTMLDocument] => no exception, deep == true
WebKit r21612
undefined undefined => no exception, deep == false
number 0 => no exception, deep == false
number 1 => no exception, deep == true
number 2 => no exception, deep == true
object false => no exception, deep == true
object true => no exception, deep == true
string  => no exception, deep == false
string abc => no exception, deep == true
string true => no exception, deep == true
string false => no exception, deep == true
object [object Object] => no exception, deep == true
object [object HTMLDocument] => no exception, deep == true
Internet Explorer 7
undefined undefined => no exception, deep == false
number 0 => no exception, deep == false
number 1 => no exception, deep == true
number 2 => no exception, deep == true
object false => no exception, deep == true
object true => no exception, deep == true
string  => no exception, deep == false
string abc => no exception, deep == true
string true => no exception, deep == true
string false => no exception, deep == true
object [object Object] => no exception, deep == true
object [object] => no exception, deep == true
This browser
CommentsAll browsers convert values to a boolean in a consistent manner, which seems to be the same as the ECMAScript ToBoolean operator.
020 — Try passing values of incorrect types to a function expecting a DOMString
Script
var xs = [undefined, 0, 2, new Boolean(false), true, { }, document];
result = '';
for (var i = 0; i < xs.length; i++) {
  var x = xs[i];
  try {
    var n = document.createTextNode(x);
    result += typeof x + ' ' + x + ' => no exception, string data == ' + n.data + '\n';
  } catch (e) {
    result += typeof x + ' ' + x + ' => ' + showException(e) + '\n';
  }
}
Firefox 2.0.0.3
undefined undefined => no exception, string data == undefined
number 0 => no exception, string data == 0
number 2 => no exception, string data == 2
object false => no exception, string data == false
boolean true => no exception, string data == true
object [object Object] => no exception, string data == [object Object]
object [object HTMLDocument] => no exception, string data == [object HTMLDocument]
Firefox 3.0a5pre (20070522)
undefined undefined => no exception, string data == undefined
number 0 => no exception, string data == 0
number 2 => no exception, string data == 2
object false => no exception, string data == false
boolean true => no exception, string data == true
object [object Object] => no exception, string data == [object Object]
object [object HTMLDocument] => no exception, string data == [object HTMLDocument]
Opera 9.20
undefined undefined => no exception, string data == undefined
number 0 => no exception, string data == 0
number 2 => no exception, string data == 2
object false => no exception, string data == false
boolean true => no exception, string data == true
object [object Object] => no exception, string data == [object Object]
object [object HTMLDocument] => no exception, string data == [object HTMLDocument]
WebKit r21612
undefined undefined => no exception, string data == undefined
number 0 => no exception, string data == 0
number 2 => no exception, string data == 2
object false => no exception, string data == false
boolean true => no exception, string data == true
object [object Object] => no exception, string data == [object Object]
object [object HTMLDocument] => no exception, string data == [object HTMLDocument]
Internet Explorer 7
undefined undefined => no exception, string data == undefined
number 0 => no exception, string data == 0
number 2 => no exception, string data == 2
object false => no exception, string data == false
boolean true => no exception, string data == true
object [object Object] => no exception, string data == [object Object]
object [object] => no exception, string data == [object]
This browser
CommentsAgain, passing values to a method expecting a DOMString results in consistent conversions, using ToString.
021 — Try passing values of incorrect types/values to NodeList.item(unsigned long)
Script
var xs = [undefined, false, true, new Number(1), 2.5, -3, 1e100, -1e100, NaN, Infinity, '', 'abc', '4', null, { }, document];
result = '';
var elt = document.createElement('test');
for (var i = 0; i < 10; i++) {
  elt.appendChild(document.createTextNode('#' + i));
}
for (var i = 0; i < xs.length; i++) {
  var x = xs[i];
  try {
    var val = elt.childNodes.item(x);
    result += typeof x + ' ' + x + ' => no exception, got child node ' + (val ? val.data : val) + '\n';
  } catch (e) {
    result += typeof x + ' ' + x + ' => ' + showException(e) + '\n';
  }
}
Firefox 2.0.0.3
undefined undefined => no exception, got child node #0
boolean false => no exception, got child node #0
boolean true => no exception, got child node #1
object 1 => no exception, got child node #1
number 2.5 => no exception, got child node #2
number -3 => no exception, got child node null
number 1e+100 => no exception, got child node #0
number -1e+100 => no exception, got child node #0
number NaN => no exception, got child node #0
number Infinity => no exception, got child node #0
string  => no exception, got child node #0
string abc => no exception, got child node #0
string 4 => no exception, got child node #4
object [object Object] => no exception, got child node #0
object [object HTMLDocument] => no exception, got child node #0
Firefox 3.0a5pre (20070522)
undefined undefined => no exception, got child node #0
boolean false => no exception, got child node #0
boolean true => no exception, got child node #1
object 1 => no exception, got child node #1
number 2.5 => no exception, got child node #2
number -3 => no exception, got child node null
number 1e+100 => no exception, got child node #0
number -1e+100 => no exception, got child node #0
number NaN => no exception, got child node #0
number Infinity => no exception, got child node #0
string  => no exception, got child node #0
string abc => no exception, got child node #0
string 4 => no exception, got child node #4
object [object Object] => no exception, got child node #0
object [object HTMLDocument] => no exception, got child node #0
Opera 9.20
undefined undefined => no exception, got child node null
boolean false => no exception, got child node null
boolean true => no exception, got child node null
object 1 => no exception, got child node #1
number 2.5 => no exception, got child node null
number -3 => no exception, got child node null
number 1e+100 => no exception, got child node null
number NaN => no exception, got child node null
number Infinity => no exception, got child node null
string  => no exception, got child node null
string abc => no exception, got child node null
string 4 => no exception, got child node #4
object [object Object] => no exception, got child node null
object [object HTMLDocument] => no exception, got child node null
WebKit r21612
undefined undefined => no exception, got child node #0
boolean false => no exception, got child node #0
boolean true => no exception, got child node #1
object 1 => no exception, got child node #1
number 2.5 => no exception, got child node #2
number -3 => no exception, got child node null
number 1e+100 => no exception, got child node #0
number -1e+100 => no exception, got child node #0
number NaN => no exception, got child node #0
number Infinity => no exception, got child node #0
string  => no exception, got child node #0
string abc => no exception, got child node #0
string 4 => no exception, got child node #4
object [object Object] => no exception, got child node #0
object [object HTMLDocument] => no exception, got child node #0
Internet Explorer 7
undefined undefined => no exception, got child node #0
boolean false => no exception, got child node #0
boolean true => no exception, got child node #1
object 1 => no exception, got child node #1
number 2.5 => no exception, got child node #2
number -3 => 
exception thrown: [object Error] Invalid procedure call or argument
number 1e+100 => no exception, got child node #0 number -1e+100 => no exception, got child node #0 number NaN => no exception, got child node #0 number Infinity => no exception, got child node #0 string => no exception, got child node #0 string abc => no exception, got child node #0 string 4 => no exception, got child node #4 object [object Object] => no exception, got child node #0 object [object] => no exception, got child node #0
This browser
CommentsThe Firefoxes, WebKit and Internet Explorer all seem to use the ToInt32 ECMAScript operator to convert the parameter to an integer, and then have some special behaviour when the result of that is negative; IE throws an exception while the Firefoxes return null from .childNodes.item(). Opera on the other hand returns null for any value that is not a non-negative integer or a string that results in a non-negative integer when converting it with ToNumber.
022 — Try passing values of incorrect types/values to CharacterData.substringData(unsigned long, unsigned long)
Script
var xs = [undefined, new Number(1), 2.5, -3, NaN, Infinity, '', 'abc', '4', { }, document];
result = '';
var n = document.createTextNode('ABCDEFGHIJ');
for (var i = 0; i < xs.length; i++) {
  var x = xs[i];
  try {
    var val = n.substringData(x, 1);
    result += typeof x + ' ' + x + ' => no exception, got substring "' + val + '"\n';
  } catch (e) {
    result += typeof x + ' ' + x + ' => ' + showException(e) + '\n';
  }
}
Firefox 2.0.0.3
undefined undefined => no exception, got substring "A"
object 1 => no exception, got substring "B"
number 2.5 => no exception, got substring "C"
number -3 => 
exception thrown: [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=022 Line: 39"]
number NaN => no exception, got substring "A" number Infinity => no exception, got substring "A" string => no exception, got substring "A" string abc => no exception, got substring "A" string 4 => no exception, got substring "E" object [object Object] => no exception, got substring "A" object [object HTMLDocument] => no exception, got substring "A"
Firefox 3.0a5pre (20070522)
undefined undefined => no exception, got substring "A"
object 1 => no exception, got substring "B"
number 2.5 => no exception, got substring "C"
number -3 => 
exception thrown: [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=022 Line: 39"]
number NaN => no exception, got substring "A" number Infinity => no exception, got substring "A" string => no exception, got substring "A" string abc => no exception, got substring "A" string 4 => no exception, got substring "E" object [object Object] => no exception, got substring "A" object [object HTMLDocument] => no exception, got substring "A"
Opera 9.20
undefined undefined => no exception, got substring "A"
object 1 => no exception, got substring "B"
number 2.5 => no exception, got substring "C"
number -3 => 
exception thrown: [object DOMException] INDEX_SIZE_ERR Backtrace: Line 14 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=022 var val = n.substringData(x, 1); Line 21 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=022 (function () { var xs = [undefined, new Number(1), 2.5, - 3, NaN, Infinity, "", "abc", "4", {}, document]; result = ""; var n = document.createTextNode("ABCDEFGHIJ"); for (var i = 0;i < xs.length;i++) { var x = xs[i]; try { var val = n.substringData(x, 1); result += typeof x + " " + x + " => no exception, got substring \"" + val + "\"\n"; } catch (e) { result += typeof x + " " + x + " => " + showException(e) + "\n"; } } } )();
number NaN => no exception, got substring "A" number Infinity =>
exception thrown: [object DOMException] INDEX_SIZE_ERR Backtrace: Line 14 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=022 var val = n.substringData(x, 1); Line 21 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=022 (function () { var xs = [undefined, new Number(1), 2.5, - 3, NaN, Infinity, "", "abc", "4", {}, document]; result = ""; var n = document.createTextNode("ABCDEFGHIJ"); for (var i = 0;i < xs.length;i++) { var x = xs[i]; try { var val = n.substringData(x, 1); result += typeof x + " " + x + " => no exception, got substring \"" + val + "\"\n"; } catch (e) { result += typeof x + " " + x + " => " + showException(e) + "\n"; } } } )();
string => no exception, got substring "A" string abc => no exception, got substring "A" string 4 => no exception, got substring "E" object [object Object] => no exception, got substring "A" object [object HTMLDocument] => no exception, got substring "A"
WebKit r21612
undefined undefined => 
exception thrown: Error: TYPE_MISMATCH_ERR: DOM Exception 17
object 1 => no exception, got substring "B" number 2.5 => no exception, got substring "C" number -3 =>
exception thrown: Error: INDEX_SIZE_ERR: DOM Exception 1
number NaN =>
exception thrown: Error: TYPE_MISMATCH_ERR: DOM Exception 17
number Infinity =>
exception thrown: Error: TYPE_MISMATCH_ERR: DOM Exception 17
string => no exception, got substring "A" string abc =>
exception thrown: Error: TYPE_MISMATCH_ERR: DOM Exception 17
string 4 => no exception, got substring "E" object [object Object] =>
exception thrown: Error: TYPE_MISMATCH_ERR: DOM Exception 17
object [object HTMLDocument] =>
exception thrown: Error: TYPE_MISMATCH_ERR: DOM Exception 17
Internet Explorer 7
undefined undefined => no exception, got substring "A"
object 1 => no exception, got substring "B"
number 2.5 => no exception, got substring "C"
number -3 => 
exception thrown: [object Error] Invalid argument.
number NaN => no exception, got substring "A" number Infinity => no exception, got substring "A" string => no exception, got substring "A" string abc => no exception, got substring "A" string 4 => no exception, got substring "E" object [object Object] => no exception, got substring "A" object [object] => no exception, got substring "A"
This browser
CommentsThis test is similar to the previous one (021), but results in different behaviour. The Firefoxes seem to use ToInt32 to convert the parameter to an integer, and then throw a INDEX_SIZE_ERR DOMException on negative integers. Opera does the same, but also throws an exception if the parameter was Infinity. IE does the same as the Firefoxes, but throws an Error object rather than a DOMException for negative integers. WebKit looks like it converts its parameter with ToNumber, and if the result not a regular number, it throws a TYPE_MISMATCH_ERR DOMException; otherwise it uses ToInt32, and if the result is a negative number it throws an INDEX_SIZE_ERR DOMException.
023 — Try passing a DOMString that contains an invalid UTF-16 string
Script
var n = document.createTextNode('a\uD800bc');
result = n.data.length;
Firefox 2.0.0.3
4
Firefox 3.0a5pre (20070522)
4
Opera 9.20
4
WebKit r21612
4
Internet Explorer 7
4
This browser
CommentsNo browser throws an exception when given a malformed UTF-16 string.
024 — Registering an EventListener with a function object
Script
result = 'not invoked';
function handler(evt) {
  var s = '';
  if (this == window) {
    s = ' (window)';
  }
  result = 'invoked, this is ' + this + s;
}
handler.toString = function() {
  return '(handler function)';
};
if (window.addEventListener) {
  window.addEventListener('load', handler, false);
} else {
  window.attachEvent('onload', handler);
}
Firefox 2.0.0.3
invoked, this is [object Window] (window)
Firefox 3.0a5pre (20070522)
invoked, this is [object Window] (window)
Opera 9.20
invoked, this is [object HTMLDocument]
WebKit r21612
invoked, this is [object DOMWindow] (window)
Internet Explorer 7
invoked, this is [object] (window)
This browser
CommentsAll browsers accept a function object as an EventListener. Opera uses the document as the value of this when calling the function, while the other browsers use the window object.
025 — Registering an EventListener with an object with a handleEvent property
Script
result = 'not invoked';
var handler = {
  handleEvent: function(evt) {
    var s = '';
    if (this == window) {
      s = ' (window)';
    }
    result = 'invoked, this is ' + this + s;
  },
  toString: function() {
    return '(handler object)';
  }
};
if (window.addEventListener) {
  window.addEventListener('load', handler, false);
} else {
  window.attachEvent('onload', handler);
}
Firefox 2.0.0.3
invoked, this is (handler object)
Firefox 3.0a5pre (20070522)
invoked, this is (handler object)
Opera 9.20
invoked, this is (handler object)
WebKit r21612
invoked, this is (handler object)
Internet Explorer 7
not invoked
This browser
CommentsAll browsers except IE accept an object with a handleEvent function property as an EventListener. Those browsers that do accept it use the object as the value of this when calling the function.
026 — Registering an EventListener with a function object that also has a handleEvent property
Script
result = 'not invoked';
function identify(o) {
  if (o == window) {
    return ' (window)';
  }
  return '';
}
function handler(evt) {
  result = 'invoked via [[Call]], this is ' + this + identify(this);
}
handler.handleEvent = function(evt) {
  result = 'invoked via .handleEvent, this is ' + this + identify(this);
};
handler.toString = function() {
  return '(handler function)';
};
if (window.addEventListener) {
  window.addEventListener('load', handler, false);
} else {
  window.attachEvent('onload', handler);
}
Firefox 2.0.0.3
invoked via [[Call]], this is [object Window] (window)
Firefox 3.0a5pre (20070522)
invoked via [[Call]], this is [object Window] (window)
Opera 9.20
invoked via [[Call]], this is [object HTMLDocument]
WebKit r21612
invoked via .handleEvent, this is (handler function)
Internet Explorer 7
invoked via [[Call]], this is [object] (window)
This browser
CommentsWebKit prefers to use handleEvent property as the implementation of the EventListener and uses the function object as the value of this, while all other browsers prefer to call the function itself (with the same this value shown in the previous test (025)).
027 — Registering an EventListener with an object whose handleEvent property comes from the prototype
Script
result = 'not invoked';
function Handler() {
  this.toString = function() {
    return '(handler object)';
  };
}
Handler.toString = function() {
  return '(handler constructor function)';
}
Handler.prototype = {
  handleEvent: function(evt) {
    var s = '';
    if (this == window) {
      s = ' (window)';
    }
    result = 'invoked, this is ' + this + s;
  },
  toString: function() {
    return '(handler prototype object)';
  }
};
var handler = new Handler();
if (window.addEventListener) {
  window.addEventListener('load', handler, false);
} else {
  window.attachEvent('onload', handler);
}
Firefox 2.0.0.3
invoked, this is (handler object)
Firefox 3.0a5pre (20070522)
invoked, this is (handler object)
Opera 9.20
invoked, this is (handler object)
WebKit r21612
invoked, this is (handler object)
Internet Explorer 7
not invoked
This browser
CommentsAll non-IE browsers find the handleEvent property from the prototype.
028 — Registering two EventListeners: one with an object whose handleEvent property is a function with no arguments, and another with two arguments
Script
result = '';
var handler0 = {
  handleEvent: function() {
    result += 'zero-argument handler invoked, this is ' + this + '\n';
  },
  toString: function() {
    return '(zero-argument handler object)';
  }
};
var handler2 = {
  handleEvent: function(a, b) {
    result += 'two-argument handler invoked, this is ' + this + '\n';
  },
  toString: function() {
    return '(two-argument handler object)';
  }
};
if (window.addEventListener) {
  window.addEventListener('load', handler0, false);
  window.addEventListener('load', handler2, false);
} else {
  window.attachEvent('onload', handler0);
  window.attachEvent('onload', handler2);
}
Firefox 2.0.0.3
zero-argument handler invoked, this is (zero-argument handler object)
two-argument handler invoked, this is (two-argument handler object)
Firefox 3.0a5pre (20070522)
zero-argument handler invoked, this is (zero-argument handler object)
two-argument handler invoked, this is (two-argument handler object)
Opera 9.20
zero-argument handler invoked, this is (zero-argument handler object)
two-argument handler invoked, this is (two-argument handler object)
WebKit r21612
zero-argument handler invoked, this is (zero-argument handler object)
two-argument handler invoked, this is (two-argument handler object)
Internet Explorer 7

This browser
CommentsNo browser looks at the number of arguments the handleEvent function property is declared to take.
029 — Try assigning to a readonly attribute
Script
document.documentElement.nodeName = 'something';
result = 'after assignment, .nodeName is ' + document.documentElement.nodeName;
Firefox 2.0.0.3
exception thrown: TypeError: setting a property that has only a getter
Firefox 3.0a5pre (20070522)
exception thrown: TypeError: setting a property that has only a getter
Opera 9.20
exception thrown: [object DOMException] NO_MODIFICATION_ALLOWED_ERR
WebKit r21612
after assignment, .nodeName is HTML
Internet Explorer 7
exception thrown: [object Error] Object doesn't support this action
This browser
CommentsWebKit ignores the assignment (as if the property is ReadOnly), while the other browsers throw some sort of exception; the Firefoxes throw a TypeError, IE an Error, and Opera a NO_MODIFICATION_ALLOWED_ERR DOMException.
030 — Try registering a UserDataHandler as an object with a handle property
Script
result = 'handler not invoked';
var handler = {
  handle: function(op, key, data, src, dst) {
    result = 'handler invoked, this is ' + this;
  },
  toString: function() {
    return '(handler object)';
  }
};
var n = document.createTextNode('test');
n.setUserData('a', 'b', handler);
n.cloneNode(false);
Firefox 2.0.0.3
exception thrown: [Exception... "Failure arg 2 [nsIDOM3Node.setUserData]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=030 :: anonymous :: line 43" data: no]
Firefox 3.0a5pre (20070522)
handler invoked, this is (handler object)
Opera 9.20
exception thrown: [Error: name: TypeError message: Statement on line 18: Type mismatch (usually a non-object value used where an object is required) Backtrace: Line 18 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=030 n.setUserData("a", "b", handler); Line 21 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=030 (function () { result = "handler not invoked"; var handler = {handle : (function (op,key,data,src,dst) { result = "handler invoked, this is " + this; } ), toString : (function () { return "(handler object)"; } )}; var n = document.createTextNode("test"); n.setUserData("a", "b", handler); n.cloneNode(false); } )(); ]
WebKit r21612
exception thrown: TypeError: Value undefined (result of expression n.setUserData) is not object.
Internet Explorer 7
exception thrown: [object Error] Object doesn't support this property or method
This browser
CommentsOnly Firefox 3 implements DOM user data. Similarly to the EventListener test (025), an object with a handleEvent function property is accepted as a UserDataHandler. It uses the object as the value of this when calling the function.
031 — Try registering a UserDataHandler as function object
Script
result = 'handler not invoked';
function handler(op, key, data, src, dst) {
  result = 'handler invoked, this is ' + this;
}
handler.toString = function() {
  return '(handler function)';
};
var n = document.createTextNode('test');
n.setUserData('a', 'b', handler);
n.cloneNode(false);
Firefox 2.0.0.3
exception thrown: [Exception... "Failure arg 2 [nsIDOM3Node.setUserData]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=031 :: anonymous :: line 41" data: no]
Firefox 3.0a5pre (20070522)
handler invoked, this is (handler function)
Opera 9.20
exception thrown: [Error: name: TypeError message: Statement on line 16: Type mismatch (usually a non-object value used where an object is required) Backtrace: Line 16 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=031 n.setUserData("a", "b", handler); Line 19 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=031 (function () { function handler(op,key,data,src,dst) { result = "handler invoked, this is " + this; } result = "handler not invoked"; handler.toString = (function () { return "(handler function)"; } ); var n = document.createTextNode("test"); n.setUserData("a", "b", handler); n.cloneNode(false); } )(); ]
WebKit r21612
exception thrown: TypeError: Value undefined (result of expression n.setUserData) is not object.
Internet Explorer 7
exception thrown: [object Error] Object doesn't support this property or method
This browser
CommentsOnly Firefox 3 implements DOM user data. Similarly to the EventListener test (024), a function object is accepted as a UserDataHandler. It uses the function object as the value of this when calling the function. This differs from EventListeners, which get invoked with the window object as this in all browsers except Opera.
032 — Try registering a UserDataHandler with a function object that also has a handle property
Script
result = 'handler not invoked';
function handler(evt) {
  result = 'handler invoked via [[Call]], this is ' + this;
}
handler.handle = function(op, key, data, src, dst) {
  result = 'handler invoked via .handleEvent, this is ' + this;
};
handler.toString = function() {
  return '(handler function)';
};
var n = document.createTextNode('test');
n.setUserData('a', 'b', handler);
n.cloneNode(false);
Firefox 2.0.0.3
exception thrown: [Exception... "Failure arg 2 [nsIDOM3Node.setUserData]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=032 :: anonymous :: line 44" data: no]
Firefox 3.0a5pre (20070522)
handler invoked via [[Call]], this is (handler function)
Opera 9.20
exception thrown: [Error: name: TypeError message: Statement on line 19: Type mismatch (usually a non-object value used where an object is required) Backtrace: Line 19 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=032 n.setUserData("a", "b", handler); Line 22 of inline#1 script in http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=032 (function () { function handler(evt) { result = "handler invoked via [[Call]], this is " + this; } result = "handler not invoked"; handler.handle = (function (op,key,data,src,dst) { result = "handler invoked via .handleEvent, this is " + this; } ); handler.toString = (function () { return "(handler function)"; } ); var n = document.createTextNode("test"); n.setUserData("a", "b", handler); n.cloneNode(false); } )(); ]
WebKit r21612
exception thrown: TypeError: Value undefined (result of expression n.setUserData) is not object.
Internet Explorer 7
exception thrown: [object Error] Object doesn't support this property or method
This browser
CommentsOnly Firefox 3 implements DOM user data. Similarly to the EventListener test (026), the function itself is preferred as the implementation of UserDataHandler, rather than the handleEvent property. It uses the function object as the value of this when calling the function.
033 — Test [[Get]] with indexes on a NodeList
Script
var n = document.createElement('test');
for (var i = 0; i < 5; i++) {
  n.appendChild(document.createTextNode('child #' + i));
}
result = '';
for (var i = -1; i < 6; i++) {
  try {
    var c = n.childNodes[i];
    result += '[' + i + '] is ' + (c ? c.nodeValue : c) + '\n';
  } catch (ex) {
    result += '[' + i + '] throws ' + showException(ex) + '\n';
  }
}
Firefox 2.0.0.3
[-1] throws 
exception thrown: [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=033 Line: 40"]
[0] is child #0 [1] is child #1 [2] is child #2 [3] is child #3 [4] is child #4 [5] is undefined
Firefox 3.0a5pre (20070522)
[-1] throws 
exception thrown: [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=033 Line: 40"]
[0] is child #0 [1] is child #1 [2] is child #2 [3] is child #3 [4] is child #4 [5] is undefined
Opera 9.20
[-1] is undefined
[0] is child #0
[1] is child #1
[2] is child #2
[3] is child #3
[4] is child #4
[5] is undefined
WebKit r21612
[-1] is undefined
[0] is child #0
[1] is child #1
[2] is child #2
[3] is child #3
[4] is child #4
[5] is undefined
Internet Explorer 7
[-1] is undefined
[0] is child #0
[1] is child #1
[2] is child #2
[3] is child #3
[4] is child #4
[5] is undefined
This browser
CommentsThe Firefoxes throw an INDEX_SIZE_ERR DOMException when trying to get a property that is a negative integer, while the other browsers just return undefined. All browsers return undefined for integer properties beyond the number of child nodes.
034 — Try deleting an index property from a NodeList
Script
var n = document.createElement('test');
for (var i = 0; i < 5; i++) {
  n.appendChild(document.createTextNode('child #' + i));
}
try {
  result = 'delete [1] == ' + delete n.childNodes[1] + '\n';
} catch (ex) {
  result = 'delete [1] throws ' + showException(ex) + '\n';
}
try {
  result += 'delete [5] == ' + delete n.childNodes[5] + '\n';
} catch (ex) {
  result += 'delete [5] throws ' + showException(ex) + '\n';
}
try {
  result += 'delete [-1] == ' + delete n.childNodes[-1] + '\n';
} catch (ex) {
  result += 'delete [-1] throws ' + showException(ex) + '\n';
}
for (var i = 0; i < 5; i++) {
  try {
    var c = n.childNodes[i];
    result += '[' + i + '] is ' + (c ? c.nodeValue : c) + '\n';
  } catch (ex) {
    result += '[' + i + '] throws ' + showException(ex) + '\n';
  }
}
Firefox 2.0.0.3
delete [1] == true
delete [5] == true
delete [-1] == true
[0] is child #0
[1] is child #1
[2] is child #2
[3] is child #3
[4] is child #4
Firefox 3.0a5pre (20070522)
delete [1] == true
delete [5] == true
delete [-1] == true
[0] is child #0
[1] is child #1
[2] is child #2
[3] is child #3
[4] is child #4
Opera 9.20
delete [1] == true
delete [5] == true
delete [-1] == true
[0] is child #0
[1] is child #1
[2] is child #2
[3] is child #3
[4] is child #4
WebKit r21612
delete [1] == true
delete [5] == true
delete [-1] == true
[0] is child #0
[1] is child #1
[2] is child #2
[3] is child #3
[4] is child #4
Internet Explorer 7
delete [1] throws 
exception thrown: [object Error] Object doesn't support this action
delete [5] throws
exception thrown: [object Error] Object doesn't support this action
delete [-1] throws
exception thrown: [object Error] Object doesn't support this action
[0] is child #0 [1] is child #1 [2] is child #2 [3] is child #3 [4] is child #4
This browser
CommentsAll non-IE browsers return true from the delete operator on integer properties, but this doesn't actually make any difference to the effect of a subsequent [[Get]]. IE throws an Error object when trying to delete the properties.
035 — Try [[Put]] with an index property on a NodeList
Script
var n = document.createElement('test');
for (var i = 0; i < 5; i++) {
  n.appendChild(document.createTextNode('child #' + i));
}
var n1 = document.createTextNode('text node 1');
var n2 = document.createTextNode('text node 2');
var n3 = document.createTextNode('text node 3');
result = 'setting [1] ';
try {
  n.childNodes[1] = n1;
  result += 'succeeds\n';
} catch (ex) {
  result += 'throws ' + showException(ex);
}
result += 'setting [-1] ';
try {
  n.childNodes[-1] = n2;
  result += 'succeeds\n';
} catch (ex) {
  result += 'throws ' + showException(ex);
}
result += 'setting [5] ';
try {
  n.childNodes[5] = n3;
  result += 'succeeds\n';
} catch (ex) {
  result += 'throws ' + showException(ex);
}
for (var i = -1; i < 6; i++) {
  try {
    var c = n.childNodes[i];
    result += '[' + i + '] is ' + (c ? c.nodeValue : c) + '\n';
  } catch (ex) {
    result += '[' + i + '] throws ' + showException(ex) + '\n';
  }
}
n.appendChild(document.createTextNode('child #5'));
result += 'after appendChild, ';
try {
  var c = n.childNodes[5];
  result += '[5] is ' + (c ? c.nodeValue : c) + '\n';
} catch (ex) {
  result += '[5] throws ' + showException(ex) + '\n';
}
n.removeChild(n.lastChild);
result += 'after removeChild, ';
try {
  var c = n.childNodes[5];
  result += '[5] is ' + (c ? c.nodeValue : c) + '\n';
} catch (ex) {
  result += '[5] throws ' + showException(ex) + '\n';
}
Firefox 2.0.0.3
setting [1] succeeds
setting [-1] succeeds
setting [5] succeeds
[-1] throws 
exception thrown: [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=035 Line: 63"]
[0] is child #0 [1] is child #1 [2] is child #2 [3] is child #3 [4] is child #4 [5] is text node 3 after appendChild, [5] is child #5 after removeChild, [5] is child #5
Firefox 3.0a5pre (20070522)
setting [1] succeeds
setting [-1] succeeds
setting [5] succeeds
[-1] throws 
exception thrown: [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=035 Line: 63"]
[0] is child #0 [1] is child #1 [2] is child #2 [3] is child #3 [4] is child #4 [5] is text node 3 after appendChild, [5] is child #5 after removeChild, [5] is child #5
Opera 9.20
setting [1] succeeds
setting [-1] succeeds
setting [5] succeeds
[-1] is text node 2
[0] is child #0
[1] is child #1
[2] is child #2
[3] is child #3
[4] is child #4
[5] is text node 3
after appendChild, [5] is child #5
after removeChild, [5] is text node 3
WebKit r21612
setting [1] succeeds
setting [-1] succeeds
setting [5] succeeds
[-1] is undefined
[0] is child #0
[1] is child #1
[2] is child #2
[3] is child #3
[4] is child #4
[5] is undefined
after appendChild, [5] is child #5
after removeChild, [5] is undefined
Internet Explorer 7
setting [1] throws 
exception thrown: [object Error] Object doesn't support this property or method
setting [-1] throws
exception thrown: [object Error] Object doesn't support this property or method
setting [5] throws
exception thrown: [object Error] Object doesn't support this property or method
[-1] is undefined [0] is child #0 [1] is child #1 [2] is child #2 [3] is child #3 [4] is child #4 [5] is undefined after appendChild, [5] is child #5 after removeChild, [5] is undefined
This browser
CommentsThe Firefoxes allow assigning values to integer properties, but only return them from a [[Get]] if the integer property is non-negative and doesn't already correspond to a node in the child list. If one of these integer properties outside the range corresponding to child list nodes later falls into and back out of range, the child that was there is for some reason still returned from the [[Get]].

Opera has more consistent behaviour. Setting to any integer property succeeds, and getting an integer property that is outside the range corresponding to a node in the child list returns that property. If such a property goes in and back out of range, the property value that was set originally is returned.

WebKit doesn't throw an exception when setting the properties, but they aren't returned from the [[Get]].

IE has the same behaviour as WebKit, except it throws an exception when trying to set the properties.

036 — Test [[Get]] with indexes and names on an HTMLCollection
Script
for (var i = 0; i < 5; i++) {
  document.write('');
}
document.write('');
result = '';
var names = [-1, 0, 1, 2, 3, 4, 5, 'a1', 'length', 'toString', 'valueOf'];
for (var i in names) {
  var name = names[i];
  try {
    var c = document.links[name];
    result += '[' + name + '] is ' + (c && typeof c == 'object' && 'id' in c ? c.id : c) + '\n';
  } catch (ex) {
    result += '[' + name + '] throws ' + showException(ex) + '\n';
  }
}
Firefox 2.0.0.3
[-1] throws 
exception thrown: [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=036 Line: 42"]
[0] is a0 [1] is a1 [2] is a2 [3] is a3 [4] is a4 [5] is undefined [a1] is a1 [length] is 5 [toString] is function toString() { [native code] } [valueOf] is function valueOf() { [native code] }
Firefox 3.0a5pre (20070522)
[-1] throws 
exception thrown: [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=036 Line: 42"]
[0] is a0 [1] is a1 [2] is a2 [3] is a3 [4] is a4 [5] is undefined [a1] is a1 [length] is 5 [toString] is function toString() { [native code] } [valueOf] is function valueOf() { [native code] }
Opera 9.20
[-1] is undefined
[0] is a0
[1] is a1
[2] is a2
[3] is a3
[4] is a4
[5] is undefined
[a1] is a1
[length] is 5
[toString] is 
function toString() { [native code] }
[valueOf] is 
function valueOf() { [native code] }
WebKit r21612
[-1] is undefined
[0] is a0
[1] is a1
[2] is a2
[3] is a3
[4] is a4
[5] is null
[a1] is a1
[length] is 5
[toString] is 
function toString() {
    [native code]
}

[valueOf] is 
function valueOf() {
    [native code]
}
Internet Explorer 7
[-1] is undefined
[0] is a0
[1] is a1
[2] is a2
[3] is a3
[4] is a4
[5] is undefined
[a1] is undefined
[length] is 5
[toString] is 
function toString() {
    [native code]
}

[valueOf] is undefined
This browser
CommentsThe Firefoxes throw an INDEX_SIZE_ERR exception for negative integer indexes, while the other browsers return undefined. WebKit returns null for a non-negative integer index ≥ the length of the collection, while the other browsers return undefined. Getting the "length" property returns the size of the collection rather than the element with id "length". Getting properties with the names "toString" and "valueOf" returns the corresponding value from the prototype, despite the fact that there is an element with id "toString" in the collection, and that the toString property probably comes from the prototype. IE however returns undefined for "valueOf", despite that property existing on the Object prototype object.
037 — Try deleting an index and name property from a HTMLCollection
Script
for (var i = 0; i < 5; i++) {
  document.write('');
}
document.write('');
result = '';
var names = [-1, 1, 5, 'a1', 'item', 'length'];
for (var i in names) {
  var name = names[i];
  try {
    result += 'delete [' + name + '] == ' + delete document.links[name] + '\n';
  } catch (ex) {
    result += 'delete [' + name + '] throws ' + showException(ex) + '\n';
  }
}
for (var i in names) {
  var name = names[i];
  try {
    var c = document.links[name];
    result += '[' + name + '] is ' + (c && typeof c == 'object' && 'id' in c ? c.id : c) + '\n';
  } catch (ex) {
    result += '[' + name + '] throws ' + showException(ex) + '\n';
  }
}
Firefox 2.0.0.3
delete [-1] == true
delete [1] == true
delete [5] == true
delete [a1] == true
delete [item] == true
delete [length] == true
[-1] throws 
exception thrown: [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=037 Line: 50"]
[1] is a1 [5] is undefined [a1] is a1 [item] is function item() { [native code] } [length] is 5
Firefox 3.0a5pre (20070522)
delete [-1] == true
delete [1] == true
delete [5] == true
delete [a1] == true
delete [item] == true
delete [length] == true
[-1] throws 
exception thrown: [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=037 Line: 50"]
[1] is a1 [5] is undefined [a1] is a1 [item] is function item() { [native code] } [length] is 5
Opera 9.20
delete [-1] == false
delete [1] == false
delete [5] == false
delete [a1] == false
delete [item] == false
delete [length] == false
[-1] is undefined
[1] is a1
[5] is undefined
[a1] is a1
[item] is 
function item() { [native code] }
[length] is 5
WebKit r21612
delete [-1] == true
delete [1] == true
delete [5] == true
delete [a1] == true
delete [item] == true
delete [length] == true
[-1] is undefined
[1] is a1
[5] is null
[a1] is a1
[item] is 
function item() {
    [native code]
}

[length] is 5
Internet Explorer 7
delete [-1] throws 
exception thrown: [object Error] Object doesn't support this action
delete [1] throws
exception thrown: [object Error] Object doesn't support this action
delete [5] throws
exception thrown: [object Error] Object doesn't support this action
delete [a1] throws
exception thrown: [object Error] Object doesn't support this action
delete [item] throws
exception thrown: [object Error] Object doesn't support this action
delete [length] throws
exception thrown: [object Error] Object doesn't support this action
[-1] is undefined [1] is a1 [5] is undefined [a1] is undefined [item] is [object] [length] is 5
This browser
CommentsAs with test 034, deleting properties that correspond to indexes or names of items in the collection returns true but doesn't affect the collection. IE throws an exception rather than returning true.
038 — Test [[Put]] with indexes and names on an HTMLCollection
Script
for (var i = 0; i < 5; i++) {
  document.write('');
}
document.write('');

var n1 = document.createElement('a');
n1.setAttribute('id', 'newAnchor1');
var n2 = document.createElement('a');
n2.setAttribute('id', 'newAnchor2');
var n3 = document.createElement('a');
n3.setAttribute('id', 'newAnchor3');
var n4 = document.createElement('a');
n4.setAttribute('id', 'newAnchor4');
var n5 = document.createElement('a');
n5.setAttribute('id', 'newAnchor5');
var n6 = document.createElement('a');
n6.setAttribute('id', 'newAnchor6');

result = 'setting [1] ';
try {
  document.links[1] = n1;
  result += 'succeeds\n';
} catch (ex) {
  result += 'throws ' + showException(ex);
}
result += 'setting [-1] ';
try {
  document.links[-1] = n2;
  result += 'succeeds\n';
} catch (ex) {
  result += 'throws ' + showException(ex);
}
result += 'setting [5] ';
try {
  document.links[5] = n3;
  result += 'succeeds\n';
} catch (ex) {
  result += 'throws ' + showException(ex);
}
result += 'setting [asdf] ';
try {
  document.links.asdf = n4;
  result += 'succeeds\n';
} catch (ex) {
  result += 'throws ' + showException(ex);
}

for (var i = -1; i < 6; i++) {
  try {
    var c = document.links[i];
    result += '[' + i + '] is ' + (c && 'id' in c ? c.id : c) + '\n';
  } catch (ex) {
    result += '[' + i + '] throws ' + showException(ex) + '\n';
  }
}
try {
  var c = document.links.asdf;
  result += '[asdf] is ' + (c && 'id' in c ? c.id : c) + '\n';
} catch (ex) {
  result += '[asdf] throws ' + showException(ex) + '\n';
}

document.write('');
result += 'after appending a new "a", ';
try {
  var c = document.links[5];
  result += '[5] is ' + (c && 'id' in c ? c.id : c) + '\n';
} catch (ex) {
  result += '[5] throws ' + showException(ex) + '\n';
}

result += 'length is ' + document.links.length + '\n';

var x = document.getElementById('a5');
x.parentNode.removeChild(x);
result += 'after removing that new "a", ';
try {
  var c = document.links[5];
  result += '[5] is ' + (c && 'id' in c ? c.id : c) + '\n';
} catch (ex) {
  result += '[5] throws ' + showException(ex) + '\n';
}

document.links.toString = n5;
result += 'after assigning to an existing property, ';
try {
  var c = document.links.toString;
  result += '[toString] is ' + (c && 'id' in c ? c.id : c) + '\n';
} catch (ex) {
  result += '[toString] throws ' + showException(ex) + '\n';
}

document.links.valueOf = n6;
result += 'after assigning to a non-existing property, ';
try {
  var c = document.links.valueOf;
  result += '[valueOf] is ' + (c && 'id' in c ? c.id : c) + '\n';
} catch (ex) {
  result += '[valueOf] throws ' + showException(ex) + '\n';
}
Firefox 2.0.0.3
setting [1] succeeds
setting [-1] succeeds
setting [5] succeeds
[-1] throws 
exception thrown: [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=038 Line: 71"]
[0] is a0 [1] is a1 [2] is a2 [3] is a3 [4] is a4 [5] is newAnchor3 [asdf] is newAnchor4 after appending a new "a", [5] is newAnchor3 length is 5 after removing that new "a", [5] is newAnchor3 after assigning to an existing property, [toString] is newAnchor5 after assigning to a non-existing property, [valueOf] is newAnchor6
Firefox 3.0a5pre (20070522)
setting [1] succeeds
setting [-1] succeeds
setting [5] succeeds
[-1] throws 
exception thrown: [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "http://mcc.id.au/2007/05/binding-tests/tests/test.pl?id=038 Line: 71"]
[0] is a0 [1] is a1 [2] is a2 [3] is a3 [4] is a4 [5] is newAnchor3 [asdf] is newAnchor4 after appending a new "a", [5] is newAnchor3 length is 5 after removing that new "a", [5] is newAnchor3 after assigning to an existing property, [toString] is newAnchor5 after assigning to a non-existing property, [valueOf] is newAnchor6
Opera 9.20
setting [1] succeeds
setting [-1] succeeds
setting [5] succeeds
[-1] is newAnchor2
[0] is a0
[1] is a1
[2] is a2
[3] is a3
[4] is a4
[5] is newAnchor3
[asdf] is newAnchor4
after appending a new "a", [5] is newAnchor3
length is 5
after removing that new "a", [5] is newAnchor3
after assigning to an existing property, [toString] is newAnchor5
after assigning to a non-existing property, [valueOf] is newAnchor6
WebKit r21612
setting [1] succeeds
setting [-1] succeeds
setting [5] succeeds
[-1] is undefined
[0] is a0
[1] is a1
[2] is a2
[3] is a3
[4] is a4
[5] is null
[asdf] is undefined
after appending a new "a", [5] is null
length is 5
after removing that new "a", [5] is null
after assigning to an existing property, [toString] is 
function toString() {
    [native code]
}

after assigning to a non-existing property, [valueOf] is 
function valueOf() {
    [native code]
}
Internet Explorer 7
setting [1] throws 
exception thrown: [object Error] Object doesn't support this property or method
setting [-1] succeeds setting [5] succeeds [-1] is undefined [0] is a0 [1] is a1 [2] is a2 [3] is a3 [4] is a4 [5] is newAnchor3 [asdf] is newAnchor4 after appending a new "a", [5] is newAnchor3 length is 5 after removing that new "a", [5] is newAnchor3 after assigning to an existing property, [toString] is newAnchor5 after assigning to a non-existing property, [valueOf] is newAnchor6
This browser
CommentsThe Firefoxes allow assigning values to integer and name properties, but only return them from a [[Get]] if the property is a non-negative integer or a name that doesn't correspond to an item in the collection. Getting negative integer properties throws an INDEX_SIZE_ERR DOMException. In the test, after assigning to the property "5" (which initially is one past the last integer index that corresponds to an item in the collection), if the collection is added to, the value that was set to the "5" property is still returned rather than the new item in the collection.

Opera has the same behaviour, except that it will return the value assigned to a negative integer property.

WebKit returns only elements from the collection (or properties from the prototype, such as toString or valueOf) when using an integer index or a name property. Assigning to properties of the object makes no difference, but doesn't throw an exception.

IE allows assigning to properties that don't correspond to an index or name of an item in the collection, and will return them from a subsequent [[Get]]. Assigning to an index that already corresponds to an item throws an exception. As with the Firefoxes, newly added items to the collection don't "shadow" properties that have been assigned to the collection object previously.

039 — Check if functions from the Node interface has the Function prototype as their prototype object and inspect the [[Class]] property of the function
Script
result = document.appendChild instanceof Function + '\n'
       + __Class__(document.appendChild)
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
040 — Enumerate the properties of a Node method
Script
result = 'length == ' + document.appendChild.length + '\n'
       + all(document.appendChild)
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
041 — Look at the prototype property of a Node method
Script
result = '.prototype           == ' + document.appendChild.prototype + '\n'
       + '.prototype.[[Class]] == ' + __Class__(document.appendChild.prototype) + '\n'
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
042 — Enumerate the properties of the object at a Node method's prototype property
Script
result = all(document.appendChild.prototype)
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
043 — Get the [[Class]] property of the document object
Script
result = __Class__(document)
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
044 — Check what object a Node method works on when applied to an object different from the one from which it was retrieved
Script
var div = document.createElement('div');
var span = document.createElement('span');
var text = document.createTextNode('');
Function.prototype.call.call(div.appendChild, span, text);
result = text.parentNode.tagName;
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
045 — Try calling a Node method with fewer arguments than expected
Script
document.documentElement.appendChild()
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
046 — Try calling a Node method with more arguments than expected
Script
var t = document.createTextNode('');
document.documentElement.appendChild(t, 123);
result = 'child ' + (t.parentNode == document.documentElement ? '' : 'not ') + 'appended';
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
047 — Try calling a method with an omitted boolean argument
Script
var e = document.createElement('span');
e.appendChild(document.createTextNode('test'));
var e2 = e.cloneNode();
result = 'acted as if the argument was ' + !!e2.firstChild;
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
048 — Test if undefined values passed to an overloaded method influence which method is chosen
Script
var canvas = document.createElement('canvas');
canvas.width = 5;
canvas.height = 5;
var ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, 5, 5);
var canvas2 = document.createElement('canvas');
canvas2.width = 10;
canvas2.height = 10;
var ctx2 = canvas2.getContext('2d');
ctx2.drawImage(canvas, 0, 0, undefined, undefined);
result = 'pixel at (2,2) is ' + ctx2.getImageData(2, 2, 1, 1).data;
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
049 — Try assigning null to some DOMString attributes
Script
result = '';

try {
  var t = document.createTextNode('test');
  result += 'before: ' + typeof t.data + ' ' + t.data + ', ';
  t.data = null;
  result += 'after: ' + typeof t.data + ' ' + t.data + '\n';
} catch (ex) {
  result += showException(ex);
}

try {
  result += 'before: ' + typeof document.documentURI + ' ' + document.documentURI + ', ';
  document.documentURI = null;
  result += 'after: ' + typeof document.documentURI + ' ' + document.documentURI + '\n';
} catch (ex) {
  result += showException(ex);
}

try {
  var e = document.createElementNS('http://example.org/test', 'pre:test');
  result += 'before: ' + typeof e.prefix + ' ' + e.prefix + ', ';
  e.prefix = null;
  result += 'after: ' + typeof e.prefix + ' ' + e.prefix + '\n';
} catch (ex) {
  result += showException(ex);
}

try {
  var a = document.createAttribute('test');
  result += 'before: ' + typeof a.value + ' ' + a.value + ', ';
  a.value = null;
  result += 'after: ' + typeof a.value + ' ' + a.value + '\n';
} catch (ex) {
  result += showException(ex);
}

try {
  var pi = document.createProcessingInstruction('target', 'data');
  result += 'before: ' + typeof pi.data + ' ' + pi.data + ', ';
  pi.data = null;
  result += 'after: ' + typeof a.value + ' ' + a.value + '\n';
} catch (ex) {
  result += showException(ex);
}

try {
  var e = document.createElement('span');
  result += 'before: ' + typeof e.id + ' ' + e.id + ', ';
  e.id = null;
  result += 'after: ' + typeof e.id + ' ' + e.id + '\n';
} catch (ex) {
  result += showException(ex);
}

Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
050 — Test if the Node interface object is enumerable
Script
result = enumerable(this, 'Node')
Firefox 2.0.0.3
true
Firefox 3.0a5pre (20070522)
true
Opera 9.20@@
WebKit r21612
true
Internet Explorer 7@@
This browser
Comments
051 — Try deleting the protoype property from the Node interface object
Script
result = delete Node.prototype + '\n' + Node.prototype
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
052 — Try replacing the Node interface object prototype property
Script
var p = Node.prototype;
Node.prototype = { };
result = Node.prototype != p;
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
053 — Try deleting one of the constants from the Node interface object
Script
result = 'Before: ' + Node.ELEMENT_NODE + '\n'
       + delete Node.ELEMENT_NODE + '\n'
       + 'After: ' + Node.ELEMENT_NODE
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
054 — Try overwriting one of the constants on the Node interface object
Script
result = 'Before: ' + Node.ELEMENT_NODE + '\n';
Node.ELEMENT_NODE = 123;
result += 'After: ' + Node.ELEMENT_NODE;
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
055 — Try calling XMLHttpRequest as a function
Script
result = XMLHttpRequest()
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
056 — See if an IDL attribute corresponds to an actual property on a host object
Script
result = Object.prototype.hasOwnProperty.call(document, 'nodeValue') + '\n' + ('nodeValue' in document)
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
057 — Try calling isPrototypeOf and using instanceof with various interfaces on the document object
Script
result = '';
function test(n) {
  if (n in this) {
    result += 'Object.prototype.isPrototypeOf.call(' + n + '.prototype, document) == ' + Object.prototype.isPrototypeOf.call(this[n].prototype, document) + ', (document instanceof ' + n + ') == ' + (document instanceof this[n]) + '\n';
  } else {
    result += 'no ' + n + ' interface object\n';
  }
}
test('Node');
test('Document');
test('HTMLDocument');
test('EventTarget');
test('DocumentCSS');
test('DocumentStyle');
test('XPathEvaluator');
test('DocumentView');
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
058 — Test aspects of XMLHttpRequest
Script
var x = new XMLHttpRequest();
result = 'prototype: ' + XMLHttpRequest.prototype + '\n';
result += 'constructor in prototype: ' + ('constructor' in XMLHttpRequest.prototype) + '\n';
result += 'constructor: ' + x.constructor + '\n';
result += 'constructor == XMLHttpRequest: ' + (x.constructor == XMLHttpRequest) + '\n';
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments
059 — See how the Image constructor differs from HTMLImageElement
Script
result = 'Image == ' + Image + '\n'
       + 'HTMLImageElement == ' + HTMLImageElement + '\n'
       + 'new Image() == ' + new Image() + '\n'
       + '(Image == HTMLImageElement) == ' + (Image == HTMLImageElement);
Firefox 2.0.0.3@@
Firefox 3.0a5pre (20070522)@@
Opera 9.20@@
WebKit r21612@@
Internet Explorer 7@@
This browser
Comments