6 padding:
0px
0px
0px
0px;
14 function print(message
, color
)
16 var paragraph
= document
.createElement("div");
17 paragraph
.appendChild(document
.createTextNode(message
));
18 paragraph
.style
.fontFamily
= "monospace";
20 paragraph
.style
.color
= color
;
21 document
.getElementById("console").appendChild(paragraph
);
24 function shouldBe(a
, b
)
28 print("PASS: " + a
+ " should be " + b
+ " and is.", "green");
30 print("FAIL: " + a
+ " should be " + b
+ " but instead is " + evalA
+ ".", "red");
35 if (window
.GCController
)
36 return GCController
.collect();
38 for (var i
= 0; i
< 10000; i
++) { // > force garbage collection (FF requires about 9K allocations before a collect)
39 var s
= new String("");
44 function parentEventListener(e
)
46 print("DOM EVENT AFTER GARBAGE COLLECTION");
49 shouldBe("event.myCustomProperty", 1);
50 event
= null; // clear JS reference
53 function childEventListener(e
)
55 print("DOM EVENT BEFORE GARBAGE COLLECTION");
56 e
.myCustomProperty
= 1;
58 shouldBe("event.myCustomProperty", 1);
59 event
= null; // clear JS reference
64 var parent
= document
.createElement("p");
65 var child
= document
.createElement("p");
66 parent
.appendChild(child
);
67 document
.body
.appendChild(parent
);
69 if (parent
.addEventListener
) {
70 child
.addEventListener("click", childEventListener
, false);
71 parent
.addEventListener("click", parentEventListener
, false);
73 child
.attachEvent("onclick", childEventListener
);
74 parent
.attachEvent("onclick", parentEventListener
);
77 if (document
.createEvent
) {
78 var event
= document
.createEvent("MouseEvents");
79 event
.initEvent("click", true, true);
80 child
.dispatchEvent(event
);
82 child
.fireEvent("onclick");
86 function testDOMImplementation()
88 var impl
= document
.implementation
.createHTMLDocument('').implementation
;
90 impl
.createHTMLDocument(''); // May crash or throw an exception if we collect parent document of impl.
95 if (window
.testRunner
)
96 testRunner
.dumpAsText();
98 print("DOM OBJECTS BEFORE GARBAGE COLLECTION:");
103 print("DOM OBJECTS AFTER GARBAGE COLLECTION:");
104 testPropertiesAgain();
107 testDOMImplementation();
110 // By default, we expect that custom properties are not allowed.
111 // If "allow custom" is specified, then custom properties are allowed and survive garbage collection.
112 // If "allow custom skip" is specified, this means this property is not guaranteed to survive garbage
113 // collection, so we don't test it at all, since there is a chance it might due to conservative GC algorithm.
114 // Any uses of "allow custom skip" represent bugs that need to be fixed.
116 var objectsToTest
= [
117 [ "document.implementation", "allow custom" ], // DOMImplementation
118 [ "document", "allow custom" ],
119 [ "document.body", "allow custom" ],
120 [ "document.body.attributes", "allow custom" ], // NamedNodeMap
121 [ "document.getElementsByTagName('body')", "allow custom" ], // NodeList
122 [ "document.getElementsByTagName('canvas')[0].getContext('2d')", "allow custom" ], // CanvasRenderingContext2D
123 [ "document.getElementsByTagName('canvas')[0].getContext('2d').createLinearGradient(0, 0, 0, 0)" ], // CanvasGradient
124 [ "document.getElementsByTagName('canvas')[0].getContext('2d').createPattern(document.getElementsByTagName('canvas')[0], 'no-repeat')" ], // CanvasPattern
125 [ "document.getElementsByTagName('select')[0].options", "allow custom" ],
126 [ "document.body.childNodes", "allow custom" ],
128 [ "document.all", "allow custom" ],
129 [ "document.images", "allow custom" ],
130 [ "document.embeds", "allow custom" ],
131 [ "document.applets", "allow custom" ],
132 [ "document.links", "allow custom" ],
133 [ "document.forms", "allow custom" ],
134 [ "document.anchors", "allow custom" ],
135 [ "document.scripts", "allow custom" ],
137 [ "document.getElementsByTagName('form')[0].elements", "allow custom" ],
138 [ "document.getElementsByTagName('table')[0].rows", "allow custom" ],
139 [ "document.getElementsByTagName('table')[0].rows[0].cells", "allow custom" ],
140 [ "document.getElementsByTagName('table')[0].tBodies", "allow custom" ],
141 [ "document.getElementsByTagName('table')[0].tBodies[0].rows", "allow custom" ],
142 [ "document.body.children", "allow custom" ],
143 [ "document.getElementsByTagName('map')[0].areas", "allow custom" ],
145 [ "document.body.style", "allow custom" ],
146 [ "document.styleSheets", "allow custom" ],
147 [ "document.styleSheets[0]", "allow custom" ],
148 [ "document.styleSheets[0].cssRules", "allow custom"],
149 [ "document.styleSheets[0].cssRules[0]", "allow custom" ],
151 [ "new XPathEvaluator()" ], // XPathEvaluator
152 [ "new XPathEvaluator().evaluate('/', document, null, 0, null)" ], // XPathResult
153 [ "document.createNSResolver(document)" ], // XPathNSResolver
154 [ "document.createExpression('/', document.createNSResolver(document))" ] // XPathExpression
156 // should not cache: NodeIterator, NodeFilter, TreeWalker, XMLHttpRequest
157 // add to test: DOMRect, MediaList, Counter, Range
160 function generateProperties()
162 for (var i
= 0; i
< objectsToTest
.length
; i
++) { // >
164 eval(objectsToTest
[i
][0] + ".myCustomProperty = 1;");
166 print("NOT SUPPORTED: " + objectsToTest
[i
][0] + "[ " + e
.message
+ " ]");
168 var expectedResult
= objectsToTest
[i
][1] ? 1 : undefined;
170 shouldBe(objectsToTest
[i
][0] + ".myCustomProperty", expectedResult
);
176 function testPropertiesAgain()
178 for (var i
= 0; i
< objectsToTest
.length
; i
++) { // >
179 if (objectsToTest
[i
][1] === "allow custom skip")
181 var expectedResult
= objectsToTest
[i
][1] ? 1 : undefined;
183 shouldBe(objectsToTest
[i
][0] + ".myCustomProperty", expectedResult
);
192 <body style=
"color: black" onload=
"test();">
193 <p>This page tests whether custom properties on DOM objects persist after garbage collection.
</p>
194 <p>If the test passes, you'll see a series of 'PASS' messages below.
</p>
195 <p>Because neither WinIE nor FF has reasonable or predictable behavior in this scenario, this
196 test just documents our behavior to ensure that we don't change it accidentally. It is not
197 a prescription for how things should behave.
</p>
200 <div id='console'
></div>
205 <object name=
"object"></object>
207 <table><tbody><tr></tr></tbody></table>