- Revision
- 143439
- Author
- [email protected]
- Date
- 2013-02-20 01:43:11 -0800 (Wed, 20 Feb 2013)
Log Message
Use EventPathWalker rather than parentNode() to normalize event targets in EventHandler.
https://bugs.webkit.org/show_bug.cgi?id=110037
Reviewed by Ryosuke Niwa.
Source/WebCore:
We need to teach EventHandler about Shadow DOM in a few places in order
to ensure that we properly target events dispatched upon text nodes.
Rather than naively grabbing the text node's direct parent via
parentNode(), we need to account for the case in which the text node is
distributed[1] to an insertion point inside a shadow host.
EventPathWalker::parent understands these relationships, and should
be used when dealing with mouse, drag, and touch events.
[1]: http://www.w3.org/TR/shadow-dom/#dfn-distribution
* page/EventHandler.cpp:
(WebCore::EventHandler::handleMouseDraggedEvent):
(WebCore::EventHandler::handleTouchEvent):
(WebCore::EventHandler::passGestureEventToWidgetIfPossible):
(WebCore::EventHandler::updateDragAndDrop):
Refactor parentNode callsites to use EventPathWalker::parent().
LayoutTests:
* fast/dom/shadow/resources/event-dispatching.js:
(scrollMouseWheel):
(addEventListeners):
Add MouseWheel, Drag, and Touch support to the event-dispatching
tests in Shadow DOM.
* fast/dom/shadow/shadow-dom-event-dispatching-distributed-text-node.html:
* fast/dom/shadow/shadow-dom-event-dispatching-text-node-in-shadow-root.html:
Scroll the mouse wheel, drag a bit, and touch before leaving the
text node, and record the generated events.
Modified Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (143438 => 143439)
--- trunk/LayoutTests/ChangeLog 2013-02-20 09:24:00 UTC (rev 143438)
+++ trunk/LayoutTests/ChangeLog 2013-02-20 09:43:11 UTC (rev 143439)
@@ -1,3 +1,20 @@
+2013-02-20 Mike West <[email protected]>
+
+ Use EventPathWalker rather than parentNode() to normalize event targets in EventHandler.
+ https://bugs.webkit.org/show_bug.cgi?id=110037
+
+ Reviewed by Ryosuke Niwa.
+
+ * fast/dom/shadow/resources/event-dispatching.js:
+ (scrollMouseWheel):
+ (addEventListeners):
+ Add MouseWheel, Drag, and Touch support to the event-dispatching
+ tests in Shadow DOM.
+ * fast/dom/shadow/shadow-dom-event-dispatching-distributed-text-node.html:
+ * fast/dom/shadow/shadow-dom-event-dispatching-text-node-in-shadow-root.html:
+ Scroll the mouse wheel, drag a bit, and touch before leaving the
+ text node, and record the generated events.
+
2013-02-20 Zoltan Arvai <[email protected]>
[Qt] Unreviewed gardening.
Modified: trunk/LayoutTests/fast/dom/shadow/resources/event-dispatching.js (143438 => 143439)
--- trunk/LayoutTests/fast/dom/shadow/resources/event-dispatching.js 2013-02-20 09:24:00 UTC (rev 143438)
+++ trunk/LayoutTests/fast/dom/shadow/resources/event-dispatching.js 2013-02-20 09:43:11 UTC (rev 143439)
@@ -16,6 +16,41 @@
eventSender.mouseMoveTo(x, y);
}
+function touchLocation(node)
+{
+ var x = node.offsetLeft + 5;
+ var y = node.offsetTop + defaultPaddingSize + 5;
+ eventSender.addTouchPoint(x, y);
+ eventSender.touchStart();
+ eventSender.leapForward(100);
+ eventSender.touchEnd();
+ eventSender.cancelTouchPoint(0);
+}
+
+function selectTextNode(node)
+{
+ getSelection().setBaseAndExtent(node, 0, node, node.length);
+}
+
+function dragMouse(node) {
+ var x = node.offsetLeft + 5;
+ var y = node.offsetTop + defaultPaddingSize + 5;
+
+ eventSender.mouseMoveTo(x, y);
+ eventSender.mouseDown();
+ eventSender.leapForward(100);
+ eventSender.mouseMoveTo(x + 100, y + 100);
+ eventSender.mouseUp();
+ eventSender.mouseMoveTo(x, y);
+}
+
+function scrollMouseWheel(node) {
+ var x = node.offsetLeft + 5;
+ var y = node.offsetTop + defaultPaddingSize + 5;
+ eventSender.mouseMoveTo(x, y);
+ eventSender.mouseScrollBy(0, 120);
+}
+
var eventRecords = {};
function clearEventRecords()
@@ -75,9 +110,12 @@
{
for (var i = 0; i < nodes.length; ++i) {
var node = getNodeInShadowTreeStack(nodes[i]);
+ node.addEventListener('click', recordEvent, false);
+ node.addEventListener('dragstart', recordEvent, false);
+ node.addEventListener('mouseout', recordEvent, false);
node.addEventListener('mouseover', recordEvent, false);
- node.addEventListener('mouseout', recordEvent, false);
- node.addEventListener('click', recordEvent, false);
+ node.addEventListener('mousewheel', recordEvent, false);
+ node.addEventListener('touchstart', recordEvent, false);
// <content> might be an inactive insertion point, so style it also.
if (node.tagName == 'DIV' || node.tagName == 'DETAILS' || node.tagName == 'SUMMARY' || node.tagName == 'CONTENT')
node.setAttribute('style', 'padding-top: ' + defaultPaddingSize + 'px;');
Modified: trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-distributed-text-node-expected.txt (143438 => 143439)
--- trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-distributed-text-node-expected.txt 2013-02-20 09:24:00 UTC (rev 143438)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-distributed-text-node-expected.txt 2013-02-20 09:43:11 UTC (rev 143439)
@@ -20,6 +20,18 @@
mouseover
@top (target: top) (related: shadow-host)
+
+ touchstart
+ @content (target: content)
+ @shadow-root (target: content)
+ @shadow-host (target: shadow-host)
+ @top (target: shadow-host)
+
+ mousewheel
+ @content (target: content)
+ @shadow-root (target: content)
+ @shadow-host (target: shadow-host)
+ @top (target: shadow-host)
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-distributed-text-node.html (143438 => 143439)
--- trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-distributed-text-node.html 2013-02-20 09:24:00 UTC (rev 143438)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-distributed-text-node.html 2013-02-20 09:43:11 UTC (rev 143439)
@@ -30,9 +30,16 @@
debug('\n' + 'Moving mouse from a distributed text node to top');
eventSender.mouseMoveTo(x, y);
clearEventRecords();
+
moveMouseOver(document.getElementById('top'));
debugDispatchedEvent('mouseout');
debugDispatchedEvent('mouseover');
+
+ touchLocation(host);
+ debugDispatchedEvent('touchstart');
+
+ scrollMouseWheel(host);
+ debugDispatchedEvent('mousewheel');
</script>
<script src=""
</body>
Modified: trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-text-node-in-shadow-root-expected.txt (143438 => 143439)
--- trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-text-node-in-shadow-root-expected.txt 2013-02-20 09:24:00 UTC (rev 143438)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-text-node-in-shadow-root-expected.txt 2013-02-20 09:43:11 UTC (rev 143439)
@@ -20,6 +20,16 @@
mouseover
@top (target: top) (related: shadow-host)
+
+ touchstart
+ @shadow-root (target: shadow-root)
+ @shadow-host (target: shadow-host)
+ @top (target: shadow-host)
+
+ mousewheel
+ @shadow-root (target: shadow-root)
+ @shadow-host (target: shadow-host)
+ @top (target: shadow-host)
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-text-node-in-shadow-root.html (143438 => 143439)
--- trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-text-node-in-shadow-root.html 2013-02-20 09:24:00 UTC (rev 143438)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-text-node-in-shadow-root.html 2013-02-20 09:43:11 UTC (rev 143439)
@@ -29,9 +29,16 @@
debug('\n' + 'Moving mouse from a direct child text node of the shadow root to top');
eventSender.mouseMoveTo(x, y);
clearEventRecords();
+
moveMouseOver(document.getElementById('top'));
debugDispatchedEvent('mouseout');
debugDispatchedEvent('mouseover');
+
+ touchLocation(host);
+ debugDispatchedEvent('touchstart');
+
+ scrollMouseWheel(host);
+ debugDispatchedEvent('mousewheel');
</script>
<script src=""
</body>
Modified: trunk/Source/WebCore/ChangeLog (143438 => 143439)
--- trunk/Source/WebCore/ChangeLog 2013-02-20 09:24:00 UTC (rev 143438)
+++ trunk/Source/WebCore/ChangeLog 2013-02-20 09:43:11 UTC (rev 143439)
@@ -1,3 +1,27 @@
+2013-02-20 Mike West <[email protected]>
+
+ Use EventPathWalker rather than parentNode() to normalize event targets in EventHandler.
+ https://bugs.webkit.org/show_bug.cgi?id=110037
+
+ Reviewed by Ryosuke Niwa.
+
+ We need to teach EventHandler about Shadow DOM in a few places in order
+ to ensure that we properly target events dispatched upon text nodes.
+ Rather than naively grabbing the text node's direct parent via
+ parentNode(), we need to account for the case in which the text node is
+ distributed[1] to an insertion point inside a shadow host.
+ EventPathWalker::parent understands these relationships, and should
+ be used when dealing with mouse, drag, and touch events.
+
+ [1]: http://www.w3.org/TR/shadow-dom/#dfn-distribution
+
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::handleMouseDraggedEvent):
+ (WebCore::EventHandler::handleTouchEvent):
+ (WebCore::EventHandler::passGestureEventToWidgetIfPossible):
+ (WebCore::EventHandler::updateDragAndDrop):
+ Refactor parentNode callsites to use EventPathWalker::parent().
+
2013-02-20 Vsevolod Vlasov <[email protected]>
Web Inspector: [Regression] Search in ProfilesPanel is broken
Modified: trunk/Source/WebCore/page/EventHandler.cpp (143438 => 143439)
--- trunk/Source/WebCore/page/EventHandler.cpp 2013-02-20 09:24:00 UTC (rev 143438)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2013-02-20 09:43:11 UTC (rev 143439)
@@ -707,7 +707,11 @@
RenderObject* renderer = targetNode->renderer();
if (!renderer) {
- renderer = targetNode->parentNode() ? targetNode->parentNode()->renderer() : 0;
+ Node* parent = EventPathWalker::parent(targetNode);
+ if (!parent)
+ return false;
+
+ renderer = parent->renderer();
if (!renderer || !renderer->isListBox())
return false;
}
@@ -1981,7 +1985,7 @@
// Drag events should never go to text nodes (following IE, and proper mouseover/out dispatch)
RefPtr<Node> newTarget = mev.targetNode();
if (newTarget && newTarget->isTextNode())
- newTarget = newTarget->parentNode();
+ newTarget = EventPathWalker::parent(newTarget.get());
m_autoscrollController->updateDragAndDrop(newTarget.get(), event.position(), event.timestamp());
@@ -2634,7 +2638,8 @@
static const Node* closestScrollableNodeCandidate(const Node* node)
{
- for (const Node* scrollableNode = node; scrollableNode; scrollableNode = scrollableNode->parentNode()) {
+ for (EventPathWalker walker(node); walker.node(); walker.moveToParent()) {
+ Node* scrollableNode = walker.node();
if (scrollableNode->isDocumentNode())
return scrollableNode;
RenderObject* renderer = scrollableNode->renderer();
@@ -3869,7 +3874,7 @@
// Touch events should not go to text nodes
if (node->isTextNode())
- node = node->parentNode();
+ node = EventPathWalker::parent(node);
if (InspectorInstrumentation::handleTouchEvent(m_frame->page(), node))
return true;