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.
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 | |
Comments | All 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 | |
Comments | Non-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 | |
Comments | Despite 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 | |
Comments | A 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 | |
Comments | When 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 | |
Comments | On 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 | |
Comments | The 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 | |
Comments | Opera 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 | |
Comments | The 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 | |
Comments | All 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 | |
Comments | The 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 | |
Comments | Opera 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 | |
Comments | Opera 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 | |
Comments | All 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 | |
Comments | All 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 | |
Comments | In 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 | |
Comments | All 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 => |
Firefox 3.0a5pre (20070522) | undefined undefined => |
Opera 9.20 | undefined undefined => |
WebKit r21612 | undefined undefined => |
Internet Explorer 7 | undefined undefined => |
This browser | |
Comments | All 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 | |
Comments | All 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 | |
Comments | Again, 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 => |
This browser | |
Comments | The 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 => |
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 => |
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 => |
WebKit r21612 | undefined undefined => |
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 => |
This browser | |
Comments | This 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 | |
Comments | No 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 | |
Comments | All 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 | |
Comments | All 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 | |
Comments | WebKit 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 | |
Comments | All 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 | |
Comments | No 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 |
|
Firefox 3.0a5pre (20070522) |
|
Opera 9.20 |
|
WebKit r21612 | after assignment, .nodeName is HTML |
Internet Explorer 7 |
|
This browser | |
Comments | WebKit 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 |
|
Firefox 3.0a5pre (20070522) | handler invoked, this is (handler object) |
Opera 9.20 |
|
WebKit r21612 |
|
Internet Explorer 7 |
|
This browser | |
Comments | Only 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 |
|
Firefox 3.0a5pre (20070522) | handler invoked, this is (handler function) |
Opera 9.20 |
|
WebKit r21612 |
|
Internet Explorer 7 |
|
This browser | |
Comments | Only 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 |
|
Firefox 3.0a5pre (20070522) | handler invoked via [[Call]], this is (handler function) |
Opera 9.20 |
|
WebKit r21612 |
|
Internet Explorer 7 |
|
This browser | |
Comments | Only 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 |
Firefox 3.0a5pre (20070522) | [-1] throws |
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 | |
Comments | The 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 |
This browser | |
Comments | All 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 |
Firefox 3.0a5pre (20070522) | setting [1] succeeds setting [-1] succeeds setting [5] succeeds [-1] throws |
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 |
This browser | |
Comments | The 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 |
Firefox 3.0a5pre (20070522) | [-1] throws |
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 | |
Comments | The 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 |
Firefox 3.0a5pre (20070522) | delete [-1] == true delete [1] == true delete [5] == true delete [a1] == true delete [item] == true delete [length] == true [-1] throws |
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 |
This browser | |
Comments | As 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 |
Firefox 3.0a5pre (20070522) | setting [1] succeeds setting [-1] succeeds setting [5] succeeds [-1] throws |
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 |
This browser | |
Comments | The 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 |