2 <script src=
"../../../resources/js-test.js"></script>
3 <script src=
"testutils.js"></script>
6 description('Tests that Custom Elements does not induce leaks');
7 var jsTestIsAsync
= true;
10 testFailed('this test requires window.internals');
13 debug('Test a custom element with minimal capturing');
15 withFrame(function (frame
) {
16 // Create some upgrade candidates
17 frame
.contentDocument
.body
.innerHTML
= '<x-x><x-x></x-x></x-x>';
19 // Register a custom element
21 var proto
= Object
.create(frame
.contentWindow
.HTMLElement
.prototype);
22 proto
.createdCallback = function () {};
23 proto
.attachedCallback = function () {};
24 proto
.detachedCallback = function () {};
25 proto
.attributeChangedCallback = function () {};
27 var ctor
= frame
.contentDocument
.registerElement('x-x', {prototype: proto
});
29 // Create some instances
31 frame
.contentDocument
.createElement('x-x');
32 frame
.contentDocument
.body
.appendChild(new ctor());
33 frame
.contentDocument
.body
.firstElementChild
.innerHTML
= '<x-x></x-x>';
35 // Watch to see that some objects die
38 'frame': internals
.observeGC(frame
),
39 'window': internals
.observeGC(frame
.contentWindow
),
40 'document': internals
.observeGC(frame
.contentDocument
),
41 'proto': internals
.observeGC(proto
),
42 'ctor': internals
.observeGC(ctor
),
43 'callback': internals
.observeGC(proto
.attributeChangedCallback
)
46 // Throw everything away
49 // We check leaks in a separate closure.
55 debug('Test callbacks which close over a bunch of objects');
57 withFrame(function (frame
) {
58 // Register a custom element with a callback which closes over
59 // the prototype, constructor, document, window and frame.
61 var contentWindow
= frame
.contentWindow
;
62 var contentDocument
= frame
.contentDocument
;
64 var proto
= Object
.create(contentWindow
.HTMLElement
.prototype);
65 proto
.attributeChangedCallback = function () {
66 var goodies
= [proto
, ctor
, contentDocument
, contentWindow
, frame
];
67 goodies
.forEach(function (loot
) { console
.log(loot
); });
69 var ctor
= contentDocument
.registerElement('x-x', {prototype: proto
});
71 // Create an instance; put it in the document
72 var elem
= new ctor();
73 contentDocument
.body
.appendChild(elem
);
75 // Watch to see that some objects die
78 'frame': internals
.observeGC(frame
),
79 'window': internals
.observeGC(contentWindow
),
80 'document': internals
.observeGC(contentDocument
),
81 'proto': internals
.observeGC(proto
),
82 'ctor': internals
.observeGC(ctor
),
83 'callback': internals
.observeGC(proto
.attributeChangedCallback
)
86 // Throw everything away
93 debug('Test that navigating a frame with custom elements does not leak');
95 withFrame(function (frame
) {
96 // Register a custom element with a callback which closes over
97 // the prototype, constructor, document, window and frame.
99 var contentWindow
= frame
.contentWindow
;
100 var contentDocument
= frame
.contentDocument
;
102 var proto
= Object
.create(contentWindow
.HTMLElement
.prototype);
103 proto
.attributeChangedCallback = function () {
104 var goodies
= [proto
, ctor
, contentDocument
, contentWindow
, frame
];
105 goodies
.forEach(function (loot
) { console
.log(loot
); });
107 var ctor
= contentDocument
.registerElement('x-x', {prototype: proto
});
109 // Create an instance; put it in the document *and* point to
110 // it from the window.
111 var elem
= new ctor();
112 contentDocument
.body
.appendChild(elem
);
113 contentWindow
.thePrecious
= elem
;
115 // Watch to see that some objects die; we don't watch the
116 // window because Blink recycles the window
119 'document': internals
.observeGC(contentDocument
),
120 'proto': internals
.observeGC(proto
),
121 'ctor': internals
.observeGC(ctor
),
122 'callback': internals
.observeGC(proto
.attributeChangedCallback
)
125 // Throw everything away
126 frame
.onload
= checkLeaksAndFinishTest
;
127 frame
.src
= 'about:blank';
131 function checkLeaksAndFinishTest() {
132 checkLeaks(finishJSTest
);
135 function checkLeaks(nextStep
) {
136 setTimeout(function () {
139 // Check that everything that should have died, did die
140 for (var prop
in observations
)
141 shouldBeTrue('observations.' + prop
+ '.wasCollected');
150 var successfullyParsed
= true;