<html>
<head>
<script>
function print(message, color) {
    var paragraph = document.createElement("div");
    paragraph.appendChild(document.createTextNode(message));
    paragraph.style.fontFamily = "monospace";
    if (color)
        paragraph.style.color = color;
    document.getElementById("console").appendChild(paragraph);
}


function shouldBe(description, actual, expected, useFuzzyMath)
{
    if (useFuzzyMath) {
        if (Math.abs(expected - actual) < 20) { // >
            print("PASS: " + description + " should be approximately " + expected + 
                  " and is " + actual + "\n", 
                  "green");
        } else {
            print("FAIL: " + description + " should be approximately " + expected + 
                  " but instead is " + actual + "\n", 
                  "red");
        }
    } else {
        if (expected === actual) {
            print("PASS: " + description + " should be " + expected + 
                  " and is\n", 
                  "green");
        } else {
            print("FAIL: " + description + " should be " + expected + 
                  " but instead is " + actual + "\n", 
                  "red");
        }
    }
}

function listener(event)
{
    document.getElementById("console").innerHTML = "";
    
    shouldBe("event target", document.getElementById('test'), event.target, false);

    var useFuzzyMath;
    if (window.eventSender)
        useFuzzyMath = false;
    else {
        // Use fuzzy math, because we can't predict exactly where the user will click
        useFuzzyMath = true;        
    }
    
    shouldBe("event.pageX", event.pageX, 175, useFuzzyMath);
    shouldBe("event.pageY", event.pageY, 105, useFuzzyMath);
    shouldBe("event.clientX", event.clientX, 175, useFuzzyMath);
    shouldBe("event.clientY", event.clientY, 105, useFuzzyMath);
    shouldBe("event.layerX", event.layerX, 7, useFuzzyMath); // not really sure why this isn't 5
    shouldBe("event.layerY", event.layerY, 5, useFuzzyMath);
    shouldBe("event.offsetX", event.offsetX, 7, useFuzzyMath); // not really sure why this isn't 5
    shouldBe("event.offsetY", event.offsetY, 5, useFuzzyMath);
    shouldBe("event.x", event.x, 175, useFuzzyMath);
    shouldBe("event.y", event.y, 105, useFuzzyMath);
}

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

    document.getElementById('test').addEventListener("click", listener, false);

    if (window.eventSender) {
        eventSender.mouseMoveTo(175, 105);
        eventSender.mouseDown();
        eventSender.mouseUp();
    }
    
    if (window.testRunner)
        testRunner.notifyDone();
}
</script>
</head>
<body onload="test();">
<p>This page tests whether a click event propogates with the correct target and positioning.
See <a href="rdar://problem/4477126">rdar://problem/4477126</a>.
</p>
<hr>
<div style="position:absolute; top: 100">
click inside the red box:<span id="test" style="position:absolute; left:160; color:red">[]</span>
</div>
<div style="position:absolute; top: 150;" id='console'></div>
</body>
</html>
