chromium/third_party/blink/web_tests/touchadjustment/nested-shadow-node.html

<!DOCTYPE html>
<html>
<head>
    <title>Touch Adjustment : Touch adjustment does not target shadow DOM elements - bug 89556</title>
    <script src="../resources/js-test.js"></script>
    <script src="resources/touchadjustment.js"></script>
    <style>
        #targetDiv {
            background: #00f;
            height: 100px;
            position: relative;
            width: 100px;
        }
    </style>

</head>

<body>

<div id="targetDiv">
</div>

<p id='description'></p>
<div id='console'></div>

<script>
    var element;
    var adjustedNode;
    var adjustedPoint;

    function findAbsolutePosition(node) {
        var pos = {left: 0, top: 0};
        do {
            pos.left += node.offsetLeft;
            pos.top += node.offsetTop;
        } while (node = node.offsetParent);
        return pos;
    }

    function addShadowDOM() {
        var targetDiv = document.getElementById("targetDiv");
        var root = targetDiv.attachShadow({mode: 'open'});
        var shadowDiv = document.createElement("div");
        shadowDiv.style.width = "20px";
        shadowDiv.style.height = "20px";
        shadowDiv.style.background = "#ff0";
        shadowDiv.style.position = "absolute";
        shadowDiv.style.right = "10px";
        shadowDiv.style.top = "10px";
        shadowDiv.addEventListener('click', function() {}, false);
        root.appendChild(shadowDiv);
    }

    function runTouchTests() {
        element = document.getElementById("targetDiv");
        element.addEventListener('click', function() {}, false);
        document.addEventListener('click', function() {}, false);

        var pos = findAbsolutePosition(element);
        var x = pos.left;
        var y = pos.top;
        var width = element.clientWidth;
        var height = element.clientHeight;
        var midX = x + width / 2;
        var midY = y + height / 2;
        var border = 10;
        var targetRadius = 10;
        var padding = 30;
        var targetX = x + width - targetRadius - border;
        var targetY = y + targetRadius + border;
        var offset = 2;

        // Test touches that are just outside the bounds of the shadow-DOM.  The adjusted point should be pulled within the bounds of the shadow-DOM node.
        testTouch(targetX + targetRadius + offset, targetY, padding, targetX, targetY, targetRadius);
        testTouch(targetX - targetRadius - offset, targetY, padding, targetX, targetY, targetRadius);
        testTouch(targetX, targetY + targetRadius + offset, padding, targetX, targetY, targetRadius);
        testTouch(targetX, targetY - targetRadius - offset, padding, targetX, targetY, targetRadius);
        
        // A touch in the center of targetDiv is sufficient distance from the shadow-DOM element that the position should not snap.
        testTouch(midX, midY, padding, midX, midY, 1);
    }

    function testTouch(touchX, touchY, padding, adjustedX, adjustedY, tolerance) {
        var left = touchX - padding / 2;
        var top = touchY - padding / 2;
        testTouchPoint(touchPoint(left, top, padding), element, /* allowTextNodes */ false, /* disallowShadowDOM */ true);
        adjustedPoint = internals.touchPositionAdjustedToBestClickableNode(left, top, padding, padding, document);
        shouldBeCloseTo('adjustedPoint.x', adjustedX, tolerance);
        shouldBeCloseTo('adjustedPoint.y', adjustedY, tolerance);
    }

    function runTests()
    {
        if (window.testRunner && window.internals && internals.touchNodeAdjustedToBestClickableNode) {
            description('Test the case where a clickable target contains a shadow-DOM element.  The adjusted point should snap to the location of the shadow-DOM element if close enough to the original touch position.')
            addShadowDOM();
            runTouchTests();
        }
    }
    runTests();
</script>
</body>
</html>