chromium/third_party/blink/web_tests/fast/events/scroll-event-handler-count.html

<div id="scrolltarget">
<script src="../../resources/js-test.js"></script>
<script>
description('This test checks that we correctly update the scroll event handler count as event handlers are added and removed');
(function() {
    // Test addEventListener/removeEventListener on the document.
    var listener = function() { }

    shouldBe('internals.scrollEventHandlerCount(document)', '0');
    document.addEventListener('scroll', listener, true);
    shouldBe('internals.scrollEventHandlerCount(document)', '1');
    document.addEventListener('scroll', listener, false);
    shouldBe('internals.scrollEventHandlerCount(document)', '2');
    document.removeEventListener('scroll', listener, true);
    shouldBe('internals.scrollEventHandlerCount(document)', '1');

    // Try removing the capturing listener again.
    document.removeEventListener('scroll', listener, true);
    shouldBe('internals.scrollEventHandlerCount(document)', '1');

    document.removeEventListener('scroll', listener, false);
    shouldBe('internals.scrollEventHandlerCount(document)', '0');
})();

debug('Test setting onscroll on the document.');
(function() {
    shouldBe('internals.scrollEventHandlerCount(document)', '0');
    document.onscroll = function() { }
    shouldBe('internals.scrollEventHandlerCount(document)', '1');
    document.onscroll = function() { }
    shouldBe('internals.scrollEventHandlerCount(document)', '1');
    document.onscroll = null;
    shouldBe('internals.scrollEventHandlerCount(document)', '0');
})();

debug('Test that nested Documents\' scroll handlers are properly tracked in their parent Document.');
(function() {
    var iframe = document.createElement('iframe');
    var scrolltarget = document.getElementById('scrolltarget');
    scrolltarget.onscroll = function() {};

    shouldBe('internals.scrollEventHandlerCount(document)', '1');

    scrolltarget.appendChild(iframe);

    nestedDocument = iframe.contentWindow.document;
    nestedDocument.open('text/html', 'replace');
    nestedDocument.write('<!DOCTYPE html>\n<script>\ndocument.onscroll=function(){};\n</' + 'script>\n');
    shouldBe('internals.scrollEventHandlerCount(nestedDocument)', '2');
    shouldBe('internals.scrollEventHandlerCount(document)', '2');

    nestedDocument.write('<script>document.onscroll=undefined</' + 'script>\n');
    shouldBe('internals.scrollEventHandlerCount(nestedDocument)', '1');
    shouldBe('internals.scrollEventHandlerCount(document)', '1');

    nestedDocument.close();

    scrolltarget.removeChild(iframe);
    shouldBe('internals.scrollEventHandlerCount(document)', '1');
    scrolltarget.onscroll = undefined;
})();

debug('Test that detaching a nested Document with handlers works properly.');
(function() {
    var iframe = document.createElement('iframe');
    var scrolltarget = document.getElementById('scrolltarget');

    scrolltarget.appendChild(iframe);

    nestedDocument = iframe.contentWindow.document;
    nestedDocument.open('text/html', 'replace');
    nestedDocument.write('<!DOCTYPE html>\n<script>\ndocument.onscroll=function(){};\n' +
                         'window.onscroll=function(){};</' + 'script>\n');
    shouldBe('internals.scrollEventHandlerCount(nestedDocument)', '2');
    shouldBe('internals.scrollEventHandlerCount(document)', '2');

    nestedDocument.close();
    scrolltarget.removeChild(iframe);
    shouldBe('internals.scrollEventHandlerCount(document)', '0');
})();

debug('Test moving event listeners from an unattached document to an attached one');
(function() {
    doc = document.implementation.createHTMLDocument('');
    var div = doc.createElement('div');
    var childDiv = doc.createElement('div');

    div.addEventListener('scroll', function() { });
    childDiv.addEventListener('scroll', function() { });
    div.appendChild(childDiv);

    // Since we only track event handlers on documents that attached to a page,
    // |doc| should not have any registered handlers at this point.
    shouldBe('internals.scrollEventHandlerCount(doc)', '0');
    shouldBe('internals.scrollEventHandlerCount(document)', '0');

    // Move the top level div into the current document. Both event handlers should
    // get registered.
    document.body.appendChild(div);
    shouldBe('internals.scrollEventHandlerCount(document)', '2');

    // Removing the div from the document does not affect the event handler count.
    document.body.removeChild(div);
    shouldBe('internals.scrollEventHandlerCount(document)', '2');

    // Once the divs are destroyed the handlers go away.
    div = null;
    childDiv = null;
    doc = null;
    gc();
    shouldBe('internals.scrollEventHandlerCount(document)', '0');
})();

debug('Test moving event listeners from an attached document to an unattached one');
(function() {
    var div = document.createElement('div');
    div.addEventListener('scroll', function() { });
    document.body.appendChild(div);

    var iframe = document.createElement('iframe');
    div.appendChild(iframe);
    var nestedDocument = iframe.contentWindow.document;
    nestedDocument.open('text/html', 'replace');
    nestedDocument.write('<!DOCTYPE html>\n<script>\ndocument.onscroll=function(){};\n' +
                         'window.onscroll=function(){};</' + 'script>\n');
    nestedDocument.close();

    shouldBe('internals.scrollEventHandlerCount(document)', '3');

    var unattachedDoc = document.implementation.createHTMLDocument('');
    unattachedDoc.body.appendChild(div);
    shouldBe('internals.scrollEventHandlerCount(document)', '0');
})();

debug('Test moving a scroll event listener between documents belonging to the same page');
(function() {
    var iframe = document.createElement('iframe');
    document.body.appendChild(iframe);
    var nestedDocument = iframe.contentWindow.document;
    nestedDocument.open('text/html', 'replace');
    nestedDocument.write('<!DOCTYPE html><div id=foo></div>');
    nestedDocument.close();

    var element = frames[0].document.getElementById('foo');
    var listener = function() { }
    element.addEventListener('scroll', listener, false);
    frames[0].window.addEventListener('scroll', listener, false);
    shouldBe('internals.scrollEventHandlerCount(document)', '2');

    document.body.appendChild(element);
    shouldBe('internals.scrollEventHandlerCount(document)', '2');

    element.removeEventListener('scroll', listener, false);
    frames[0].window.removeEventListener('scroll', listener, false);
    shouldBe('internals.scrollEventHandlerCount(document)', '0');
})();

debug('Test addEventListener/removeEventListener on the window.');
(function() {
    var listener = function() { }

    shouldBe('internals.scrollEventHandlerCount(document)', '0');
    window.addEventListener('scroll', listener, true);
    shouldBe('internals.scrollEventHandlerCount(document)', '1');
    window.addEventListener('scroll', listener, false);
    shouldBe('internals.scrollEventHandlerCount(document)', '2');
    window.removeEventListener('scroll', listener, true);
    shouldBe('internals.scrollEventHandlerCount(document)', '1');

    // Try removing the capturing listener again.
    window.removeEventListener('scroll', listener, true);
    shouldBe('internals.scrollEventHandlerCount(document)', '1');

    window.removeEventListener('scroll', listener, false);
    shouldBe('internals.scrollEventHandlerCount(document)', '0');
})();

debug('Test setting onscroll on the window.');
(function() {
    shouldBe('internals.scrollEventHandlerCount(document)', '0');
    window.onscroll = function() { }
    shouldBe('internals.scrollEventHandlerCount(document)', '1');
    window.onscroll = function() { }
    shouldBe('internals.scrollEventHandlerCount(document)', '1');
    window.onscroll = null;
    shouldBe('internals.scrollEventHandlerCount(document)', '0');
})();
</script>
</body>