DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (c68fe15a81fc)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
<!DOCTYPE html>
<html>
<head>
<title>Shadow DOM: MouseEvent's offsetX and offsetY attributes must be relative to the relative target.</title>
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
<meta name="assert" content="The MouseEvent offsetX and offsetY attributes must return the coordinates relative to the origin of the padding edge of the relative target">
<link rel="help" href="http://w3c.github.io/webcomponents/spec/shadow/#event-dispatch">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/event-path-test-helpers.js"></script>
</head>
<body>
<style>
html, body { padding: 0; margin: 0; }
my-host { display: block; width: 180px; height: 80px; margin: 10px 20px; padding: 10px; background: #ccc; }
#log { margin: 1rem; }
</style>
<my-host></my-host>
<div id="log"></div>
<script>

var shadowStyle = '#container { width: 160px; height: 60px; padding: 10px; background: yellow; } #target { margin-left: 5px; background: orange; }';
var host = document.querySelector('my-host');

function attachLoggers(targets)
{
    var eventLogs = [];
    for (var i = 0; i < targets.length; i++) {
        targets[i].addEventListener('mousedown', function (event) {
            eventLogs.push({current: this, target: event.target, offsetX: event.offsetX, offsetY: event.offsetY});
        });
    }
    return eventLogs;
}

test(function () {
    host.innerHTML = '<style>' + shadowStyle + '</style><div id="container"><span id="target">Click here</div></div>';

    var target = host.querySelector('#target');
    var container = host.querySelector('#container');

    var eventLogs = attachLoggers([target, container, host, document.body]);
    var mouseEvent = new MouseEvent('mousedown', {clientX: 51, clientY: 37, composed: true, bubbles: true});
    target.dispatchEvent(mouseEvent);

    assert_equals(host.offsetLeft, 20, 'The host must be at (20px, 10px)');
    assert_equals(host.offsetTop, 10, 'The host must be at (20px, 10px)');
    assert_equals(target.offsetLeft, 45, 'The target must be at (45px, 30px)');
    assert_equals(target.offsetTop, 30, 'The target must be at (45px, 30px)');

    assert_equals(eventLogs[0].current, target);
    assert_equals(eventLogs[0].target, target);
    assert_equals(eventLogs[0].offsetX, 21); // Padding edge of target is at (30px, 20px)
    assert_equals(eventLogs[0].offsetY, 17);

    assert_equals(eventLogs[1].current, container);
    assert_equals(eventLogs[1].target, target);
    assert_equals(eventLogs[1].offsetX, 21);
    assert_equals(eventLogs[1].offsetY, 17);

    assert_equals(eventLogs[2].current, host);
    assert_equals(eventLogs[2].target, target);
    assert_equals(eventLogs[2].offsetX, 21);
    assert_equals(eventLogs[2].offsetY, 17);

    assert_equals(eventLogs[3].current, document.body);
    assert_equals(eventLogs[3].target, target);
    assert_equals(eventLogs[3].offsetX, 21);
    assert_equals(eventLogs[3].offsetY, 17);
}, 'MouseEvent\'s offsetX and offsetY attributes must be relative to the target.');

var shadowRoot = host.attachShadow({mode: 'closed'});
test(function () {
    shadowRoot.innerHTML = '<style>' + shadowStyle + '</style><div id="container"><span id="target">Click here</div></div>';

    var target = shadowRoot.querySelector('#target');
    var container = shadowRoot.querySelector('#container');

    var eventLogs = attachLoggers([target, container, shadowRoot, host, document.body]);
    var mouseEvent = new MouseEvent('mousedown', {clientX: 51, clientY: 37, composed: true, bubbles: true});
    target.dispatchEvent(mouseEvent);

    assert_equals(host.offsetLeft, 20, 'The host must be at (20px, 10px)');
    assert_equals(host.offsetTop, 10, 'The host must be at (20px, 10px)');
    assert_equals(target.offsetLeft, 45, 'The target must be at (45px, 30px)');
    assert_equals(target.offsetTop, 30, 'The target must be at (45px, 30px)');

    assert_equals(eventLogs[0].current, target);
    assert_equals(eventLogs[0].target, target);
    assert_equals(eventLogs[0].offsetX, 21); // Padding edge of target is at (30px, 20px)
    assert_equals(eventLogs[0].offsetY, 17);

    assert_equals(eventLogs[1].current, container);
    assert_equals(eventLogs[1].target, target);
    assert_equals(eventLogs[1].offsetX, 21);
    assert_equals(eventLogs[1].offsetY, 17);

    assert_equals(eventLogs[3].current, host);
    assert_equals(eventLogs[3].target, host);
    assert_equals(eventLogs[3].offsetX, 31); // Padding edge of host is at (20px, 10px)
    assert_equals(eventLogs[3].offsetY, 27);

    assert_equals(eventLogs[4].current, document.body);
    assert_equals(eventLogs[4].target, host);
    assert_equals(eventLogs[4].offsetX, 31);
    assert_equals(eventLogs[4].offsetY, 27);
}, 'MouseEvent\'s offsetX and offsetY attributes must be relative to the shadow host when an event is dispatched inside its shadow tree.');

test(function () {
    shadowRoot.innerHTML = '<style>' + shadowStyle + '</style><div id="container"><slot></slot></div>';
    host.innerHTML = '<style>' + shadowStyle + '</style><div id="target">Click here</div>';

    var target = host.querySelector('#target');
    var container = shadowRoot.querySelector('#container');

    var eventLogs = attachLoggers([target, container, shadowRoot, host, document.body]);
    var mouseEvent = new MouseEvent('mousedown', {clientX: 51, clientY: 37, composed: true, bubbles: true});
    target.dispatchEvent(mouseEvent);

    assert_equals(host.offsetLeft, 20, 'The host must be at (20px, 10px)');
    assert_equals(host.offsetTop, 10, 'The host must be at (20px, 10px)');
    assert_equals(target.offsetLeft, 45, 'The target must be at (45px, 30px)');
    assert_equals(target.offsetTop, 30, 'The target must be at (45px, 30px)');

    assert_equals(eventLogs[0].current, target);
    assert_equals(eventLogs[0].target, target);
    assert_equals(eventLogs[0].target.offsetParent, document.body);
    assert_equals(eventLogs[0].offsetX, 6); // Padding edge of target is at (45px, 30px)
    assert_equals(eventLogs[0].offsetY, 7);

    assert_equals(eventLogs[1].current, container);
    assert_equals(eventLogs[1].target, target);
    assert_equals(eventLogs[1].offsetX, 6);
    assert_equals(eventLogs[1].offsetY, 7);

    assert_equals(eventLogs[2].current, shadowRoot);
    assert_equals(eventLogs[2].target, target);
    assert_equals(eventLogs[2].offsetX, 6);
    assert_equals(eventLogs[2].offsetY, 7);

    assert_equals(eventLogs[3].current, host);
    assert_equals(eventLogs[3].target, target);
    assert_equals(eventLogs[3].offsetX, 6);
    assert_equals(eventLogs[3].offsetY, 7);

    assert_equals(eventLogs[4].current, document.body);
    assert_equals(eventLogs[4].target, target);
    assert_equals(eventLogs[4].offsetX, 6);
    assert_equals(eventLogs[4].offsetY, 7);
}, 'MouseEvent\'s offsetX and offsetY attributes must be relative to the target when an event is dispatched on a slotted content.');

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