| <!DOCTYPE html><!-- webkit-test-runner [ IntersectionObserverEnabled=true ] --> |
| <head> |
| <script src="../resources/gc.js"></script> |
| <body> |
| <pre id="log">This tests removing the root node of IntersectionObserver. The root node should be eligible for GC. |
| |
| </pre> |
| <script> |
| |
| function createRoot(rootId) |
| { |
| const container = document.createElement('div'); |
| container.innerHTML = `<div id="${rootId}" class="root" style="position:absolute"><div class="target" style="width: 100px; height: 100px; background-color: green"></div></div>`; |
| const root = container.getElementsByClassName('root')[0]; |
| root.remove(); |
| return root; |
| } |
| |
| let initialNodeCount = 0; |
| window.onload = () => { |
| if (!window.testRunner || !window.internals) { |
| log.textContent += 'FAIL - This test requires internals'; |
| return; |
| } |
| if (internals.numberOfIntersectionObservers(document)) { |
| log.textContent += 'FAIL - Initial intersection observer count is not zero'; |
| return; |
| } |
| initialNodeCount = internals.referencingNodeCount(document); |
| testRunner.dumpAsText(); |
| testRunner.waitUntilDone(); |
| setTimeout(() => testRunner.notifyDone(), 5000); |
| runTest(1); |
| } |
| |
| const totalTestCount = 20; |
| function runTest(testNumber) { |
| log.textContent += `Test ${testNumber}: `; |
| const rootId = 'root-' + testNumber; |
| let root = createRoot(rootId); |
| root.alive = true; |
| document.body.appendChild(root); |
| |
| let observer = new IntersectionObserver(() => { }, { root }); |
| let target = root.getElementsByClassName('target')[0]; |
| if (observer.root != root) |
| return testFailed(testNumber, 'observer.root != root after construction'); |
| observer.observe(target); |
| |
| root.remove(); |
| root = null; |
| target = null; |
| requestAnimationFrame(function () { |
| observer.takeRecords(); |
| gc(); |
| |
| if (!observer.root) |
| return testFailed(testNumber, 'observer.root is null'); |
| if (observer.root.id != rootId) |
| return testFailed(testNumber, `observer.root.id (${observer.root.id}) != rootId (${rootId}) after running rAF and GC`); |
| if (!observer.root.alive) |
| return testFailed(testNumber, 'observer.alive is false'); |
| |
| observer = null; |
| gc(); |
| |
| log.textContent += 'PASS\n'; |
| |
| if (testNumber < totalTestCount) |
| setTimeout(() => runTest(testNumber + 1), 0); |
| else |
| setTimeout(() => finish(testNumber), 0); |
| }); |
| } |
| |
| function testFailed(testNumber, error) |
| { |
| log.textContent += `FAIL: ${error}\n`; |
| finish(testNumber); |
| } |
| |
| function finish(finishedTestCount) |
| { |
| log.textContent += 'Node count: '; |
| log.textContent += (internals.referencingNodeCount(document) < initialNodeCount + 2 * finishedTestCount * 0.8) ? 'PASS' : 'FAIL - Less than 20% of the root nodes were collected'; |
| log.textContent += '\n'; |
| log.textContent += 'Intersection observer count: '; |
| log.textContent += (internals.numberOfIntersectionObservers(document) < finishedTestCount * 0.8) ? 'PASS' : 'FAIL - Less than 20% of the intersection observers were collected'; |
| log.textContent += '\n'; |
| testRunner.notifyDone(); |
| } |
| |
| </script> |
| </body> |
| </html> |