<!DOCTYPE html>
<html>
<body>
<p>This tests that changing selection in an iframe does not fire selectionchange event in the parent document and vice versa.</p>
<div id="container">
<iframe id="child" src="about:blank"></iframe>
<div id="parent">WebKit rocks</div>
</div>
<ul id="console">
</ul>
<script>

var parent = document.getElementById('parent');
var child = document.getElementById('child');
var childDocument = (child.contentWindow || child.contentDocument).document;
if (!childDocument.body)
   childDocument.appendChild(document.createElement('body'));
childDocument.body.innerHTML = 'hello world';

var selectionOfParent = window.getSelection();
var selectionOfChild = child.contentDocument.getSelection();

tests = [
    {
        selector: function() {
            selectionOfParent.selectAllChildren(document.body);
            return "all of parent's document body";
            },
        expected: 'parent',
        alt_expected: null,
    },
    {
        selector: function() {
                selectionOfChild.selectAllChildren(childDocument.body);
                return "all of parent's document body";
            },
        expected: 'child',
        alt_expected: null,
    },
    {
        selector: function() {
                var range = document.createRange();
                range.setStart(parent.firstChild, 7);
                range.setEnd(parent.firstChild, 12);
                selectionOfParent.removeAllRanges();
                selectionOfParent.addRange(range);
                return '"rocks" of "WebKit rocks" in the parent';
            },
        expected: 'parent, parent',
        alt_expected: 'parent',
    },
    {
        selector: function() {
                var range = childDocument.createRange();
                range.setStart(childDocument.body.firstChild, 6);
                range.setEnd(childDocument.body.firstChild, 11);
                selectionOfChild.removeAllRanges();
                selectionOfChild.addRange(range);
                return '"world" of "hello world" in the child';
            },
        expected: 'child, child',
        alt_expected: 'child',
    }
];
var i = 0;
var selected = null;

if (window.testRunner) {
    testRunner.dumpAsText();
    testRunner.waitUntilDone();
}

var log = [];

function logger(event) {
    if (event.target == childDocument)
        log.push('child');
    else if (event.target == document)
        log.push('parent');
    else
        log.push('unknown');
}

function verify(selected, expected, alt_expected) {
    setTimeout(function () {
        var actual = log.length ? '' : 'none';
        for (var i = 0; i < log.length; i++) {
            if (actual.length)
                actual += ', ';
            actual += log[i];
        }
        var result = 'selecting ' + selected + ' fired selection change events from ' + actual;
        if (actual == expected || actual == alt_expected)
            result = 'PASS: ' + result;
        else
            result = 'FAIL: ' + result + ' but expected ' + expected + (alt_expected ? ' or ' + alt_expected : '');
        var console = document.getElementById('console');
        var listItem = document.createElement('li');
        console.appendChild(listItem);
        listItem.appendChild(document.createTextNode(result));
    }, 0);
}

// selects and verify in turn until all tests are ran
function timer() {
    if (!selected) {
        log = [];
        selected = tests[i].selector();
    } else {
        verify(selected, tests[i].expected, tests[i].alt_expected);
        selected = null;
        i++;
        if (i == tests.length) {
            if (window.testRunner)
                document.getElementById('container').style.display = 'none';
            testRunner.notifyDone();
            return;
        }
    }
    setTimeout(timer, 0);
}

document.addEventListener('selectionchange', logger, false);
childDocument.onselectionchange = logger;

timer();

</script>
</body>
</html>
