Modified: trunk/LayoutTests/ChangeLog (121304 => 121305)
--- trunk/LayoutTests/ChangeLog 2012-06-27 00:06:19 UTC (rev 121304)
+++ trunk/LayoutTests/ChangeLog 2012-06-27 00:41:28 UTC (rev 121305)
@@ -1,3 +1,21 @@
+2012-06-26 Kevin Ellis <[email protected]>
+
+ Touch adjustment does not target shadow DOM elements
+ https://bugs.webkit.org/show_bug.cgi?id=89556
+
+ Cannot open calendar picker for input type=date using a touch tap
+ gesture if TOUCH_ADJUSTMENT is enabled. When touch adjustment is
+ enabled, the position of a touch point is snapped to the center of an
+ element when generating synthetic mouse events. The position of shadow
+ nodes was not being considered when determining the snap position.
+ This test verifies that touch adjustment now considers shadow-DOM
+ when calculating the snap position.
+
+ Reviewed by Antonio Gomes.
+
+ * touchadjustment/nested-shadow-node-expected.txt: Added.
+ * touchadjustment/nested-shadow-node.html: Added.
+
2012-06-26 Ryosuke Niwa <[email protected]>
Stop calling node() and deprecatedEditingOffset() in comparePositions
@@ -3703,7 +3721,6 @@
These make sure the alignment used in the first row of the span is correct when things like
the height of the cell and the height of the span are specified.
-
2012-06-18 Hayato Ito <[email protected]>
Event dispatcher should use InsertionPoint::hasDistribution instead of InsertinPoint::isActive in re-targeting.
Added: trunk/LayoutTests/touchadjustment/nested-shadow-node-expected.txt (0 => 121305)
--- trunk/LayoutTests/touchadjustment/nested-shadow-node-expected.txt (rev 0)
+++ trunk/LayoutTests/touchadjustment/nested-shadow-node-expected.txt 2012-06-27 00:41:28 UTC (rev 121305)
@@ -0,0 +1,24 @@
+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.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS adjustedNode.id is element.id
+PASS adjustedPoint.x is within 10 of 88
+PASS adjustedPoint.y is within 10 of 28
+PASS adjustedNode.id is element.id
+PASS adjustedPoint.x is within 10 of 88
+PASS adjustedPoint.y is within 10 of 28
+PASS adjustedNode.id is element.id
+PASS adjustedPoint.x is within 10 of 88
+PASS adjustedPoint.y is within 10 of 28
+PASS adjustedNode.id is element.id
+PASS adjustedPoint.x is within 10 of 88
+PASS adjustedPoint.y is within 10 of 28
+PASS adjustedNode.id is element.id
+PASS adjustedPoint.x is within 1 of 58
+PASS adjustedPoint.y is within 1 of 58
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/touchadjustment/nested-shadow-node.html (0 => 121305)
--- trunk/LayoutTests/touchadjustment/nested-shadow-node.html (rev 0)
+++ trunk/LayoutTests/touchadjustment/nested-shadow-node.html 2012-06-27 00:41:28 UTC (rev 121305)
@@ -0,0 +1,103 @@
+<html>
+<head>
+<style>
+ #targetDiv {
+ background: #00f;
+ height: 100px;
+ position: relative;
+ width: 100px;
+ }
+</style>
+<script src=""
+
+</head>
+
+<body _onload_="runTests()">
+
+<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 = internals.ensureShadowRoot(targetDiv);
+ var shadowDiv = document.createElement("div");
+ shadowDiv.style.width = "20px";
+ shadowDiv.style.height = "20px";
+ shadowDiv.style.background = ""
+ shadowDiv.style.position = "absolute";
+ shadowDiv.style.right = "10px";
+ shadowDiv.style.top = "10px";
+ 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;
+ adjustedNode = internals.touchNodeAdjustedToBestClickableNode(left, top, padding, padding, document);
+ shouldBe('adjustedNode.id', 'element.id');
+ 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 && internals.ensureShadowRoot) {
+ 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();
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ runTouchTests();
+ isSuccessfullyParsed();
+ testRunner.notifyDone();
+ }
+ }
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (121304 => 121305)
--- trunk/Source/WebCore/ChangeLog 2012-06-27 00:06:19 UTC (rev 121304)
+++ trunk/Source/WebCore/ChangeLog 2012-06-27 00:41:28 UTC (rev 121305)
@@ -1,3 +1,22 @@
+2012-06-26 Kevin Ellis <[email protected]>
+
+ Touch adjustment does not target shadow DOM elements
+ https://bugs.webkit.org/show_bug.cgi?id=89556
+
+ The position of internal shadow-DOM nodes were not being considered
+ when determining the snap position when TOUCH_ADJUSTMENT is enabled
+ for fine tuning the position of synthetic mouse events. This
+ restriction results in not being able to select the calendar picker
+ when input type=date, or to clear the search field for input
+ type=search.
+
+ Reviewed by Antonio Gomes.
+
+ Test: touchadjustment/nested-shadow-node.html
+
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::bestClickableNodeForTouchPoint):
+
2012-06-26 Ryosuke Niwa <[email protected]>
Stop calling node() and deprecatedEditingOffset() in comparePositions
Modified: trunk/Source/WebCore/page/EventHandler.cpp (121304 => 121305)
--- trunk/Source/WebCore/page/EventHandler.cpp 2012-06-27 00:06:19 UTC (rev 121304)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2012-06-27 00:41:28 UTC (rev 121305)
@@ -2483,11 +2483,19 @@
{
HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter);
- HitTestResult result = hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ false, /*ignoreClipping*/ false, DontHitTestScrollbars, hitType, touchRadius);
+ HitTestResult result = hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ true, /*ignoreClipping*/ false, DontHitTestScrollbars, hitType, touchRadius);
IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
RefPtr<StaticHashSetNodeList> nodeList = StaticHashSetNodeList::adopt(result.rectBasedTestResult());
- return findBestClickableCandidate(targetNode, targetPoint, touchCenter, touchRect, *nodeList.get());
+
+ // FIXME: Should be able to handle targetNode being a shadow DOM node to avoid performing uncessary hit tests
+ // in the case where further processing on the node is required. Returning the shadow ancestor prevents a
+ // regression in touchadjustment/html-label.html. Some refinement is required to testing/internals to
+ // handle targetNode being a shadow DOM node.
+ bool success = findBestClickableCandidate(targetNode, targetPoint, touchCenter, touchRect, *nodeList.get());
+ if (success && targetNode)
+ targetNode = targetNode->shadowAncestorNode();
+ return success;
}
bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode)