Title: [140944] trunk
Revision
140944
Author
[email protected]
Date
2013-01-27 22:15:45 -0800 (Sun, 27 Jan 2013)

Log Message

[Shadow DOM] Selecting a node to another node in ShadowDOM fires 'click' event unexpectedly
https://bugs.webkit.org/show_bug.cgi?id=107233

Reviewed by Dimitri Glazkov.

Source/WebCore:

When selecting from a node to another node in ShadowDOM, 'click' event is unexpectedly fired.

The root cause of the bug is using shadow ancestor nodes for checking the node mouse is pressed on
and the node mouse is released on is the same. This was introduced to fire a click event for a slider
in <input> or etc.

However, we don't need to check shadow ancestor if we're in Author ShadowDOM.

Test: fast/dom/shadow/selecting-anchor.html

* page/EventHandler.cpp:
(WebCore::mouseIsReleasedOnPressedElement):
(WebCore):
(WebCore::EventHandler::handleMouseReleaseEvent):

LayoutTests:

* fast/dom/shadow/select-in-shadowdom-expected.txt: Added.
* fast/dom/shadow/select-in-shadowdom.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (140943 => 140944)


--- trunk/LayoutTests/ChangeLog	2013-01-28 05:24:44 UTC (rev 140943)
+++ trunk/LayoutTests/ChangeLog	2013-01-28 06:15:45 UTC (rev 140944)
@@ -1,3 +1,13 @@
+2013-01-27  Shinya Kawanaka  <[email protected]>
+
+        [Shadow DOM] Selecting a node to another node in ShadowDOM fires 'click' event unexpectedly
+        https://bugs.webkit.org/show_bug.cgi?id=107233
+
+        Reviewed by Dimitri Glazkov.
+
+        * fast/dom/shadow/select-in-shadowdom-expected.txt: Added.
+        * fast/dom/shadow/select-in-shadowdom.html: Added.
+
 2013-01-28  Keishi Hattori  <[email protected]>
 
         [Chromium] Marking storage/indexeddb tests as crashing.

Added: trunk/LayoutTests/fast/dom/shadow/select-in-shadowdom-expected.txt (0 => 140944)


--- trunk/LayoutTests/fast/dom/shadow/select-in-shadowdom-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/shadow/select-in-shadowdom-expected.txt	2013-01-28 06:15:45 UTC (rev 140944)
@@ -0,0 +1,11 @@
+When selecting from non-anchor Node to anchor node in ShadowDOM, client should not cause page jump.
+
+Selecting from a node to another node in ShadowDOM. This should not fire click event
+
+Clicking a node in ShadowDOM.
+PASS click should be fired.
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/shadow/select-in-shadowdom.html (0 => 140944)


--- trunk/LayoutTests/fast/dom/shadow/select-in-shadowdom.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/shadow/select-in-shadowdom.html	2013-01-28 06:15:45 UTC (rev 140944)
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html><body>
+<script src=""
+
+<p>When selecting from non-anchor Node to anchor node in ShadowDOM, client should not cause page jump.</p>
+
+<div id="host"></div>
+<pre id="console"></pre>
+
+<script>
+function mouseMoveTo(element)
+{
+    var x = element.offsetLeft + element.offsetWidth / 2;
+    var y = element.offsetTop + element.offsetHeight / 2;
+    eventSender.mouseMoveTo(x, y);
+}
+
+var shadowRoot = host.webkitCreateShadowRoot();
+shadowRoot.innerHTML = '<span>select form here</span><span>select to here</span>';
+
+var clickEventShouldNotBeFired = true;
+
+host.addEventListener('click', function(e) {
+    if (clickEventShouldNotBeFired)
+        debug('FAIL click should not be fired.');
+    else
+        debug('PASS click should be fired.');
+});
+
+debug('Selecting from a node to another node in ShadowDOM. This should not fire click event');
+mouseMoveTo(shadowRoot.firstChild);
+eventSender.mouseDown();
+mouseMoveTo(shadowRoot.firstChild.nextSibling);
+eventSender.mouseUp();
+debug('');
+
+debug('Clicking a node in ShadowDOM.');
+clickEventShouldNotBeFired = false;
+mouseMoveTo(shadowRoot.firstChild);
+eventSender.mouseDown();
+eventSender.mouseUp();
+debug('');
+
+</script>
+
+<script src=""
+</body></body>

Modified: trunk/Source/WebCore/ChangeLog (140943 => 140944)


--- trunk/Source/WebCore/ChangeLog	2013-01-28 05:24:44 UTC (rev 140943)
+++ trunk/Source/WebCore/ChangeLog	2013-01-28 06:15:45 UTC (rev 140944)
@@ -1,3 +1,25 @@
+2013-01-27  Shinya Kawanaka  <[email protected]>
+
+        [Shadow DOM] Selecting a node to another node in ShadowDOM fires 'click' event unexpectedly
+        https://bugs.webkit.org/show_bug.cgi?id=107233
+
+        Reviewed by Dimitri Glazkov.
+
+        When selecting from a node to another node in ShadowDOM, 'click' event is unexpectedly fired.
+
+        The root cause of the bug is using shadow ancestor nodes for checking the node mouse is pressed on
+        and the node mouse is released on is the same. This was introduced to fire a click event for a slider
+        in <input> or etc.
+
+        However, we don't need to check shadow ancestor if we're in Author ShadowDOM.
+
+        Test: fast/dom/shadow/selecting-anchor.html
+
+        * page/EventHandler.cpp:
+        (WebCore::mouseIsReleasedOnPressedElement):
+        (WebCore):
+        (WebCore::EventHandler::handleMouseReleaseEvent):
+
 2013-01-27  Kentaro Hara  <[email protected]>
 
         An [ActiveDOMObject] IDL attribute should be inherited

Modified: trunk/Source/WebCore/page/EventHandler.cpp (140943 => 140944)


--- trunk/Source/WebCore/page/EventHandler.cpp	2013-01-28 05:24:44 UTC (rev 140943)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2013-01-28 06:15:45 UTC (rev 140944)
@@ -1763,6 +1763,30 @@
     m_clickNode = 0;
 }
 
+inline static bool mouseIsReleasedOnPressedElement(Node* targetNode, Node* clickNode)
+{
+    if (targetNode == clickNode)
+        return true;
+
+    if (!targetNode)
+        return false;
+
+    ShadowRoot* containingShadowRoot = targetNode->containingShadowRoot();
+    if (!containingShadowRoot)
+        return false;
+
+    // FIXME: When an element in UA ShadowDOM (e.g. inner element in <input>) is clicked,
+    // we assume that the host element is clicked. This is necessary for implementing <input type="range"> etc.
+    // However, we should not check ShadowRoot type basically.
+    // https://bugs.webkit.org/show_bug.cgi?id=108047
+    if (containingShadowRoot->type() != ShadowRoot::UserAgentShadowRoot)
+        return false;
+
+    Node* adjustedTargetNode = targetNode->shadowHost();
+    Node* adjustedClickNode = clickNode ? clickNode->shadowHost() : 0;
+    return adjustedTargetNode == adjustedClickNode;
+}
+
 bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
 {
     RefPtr<FrameView> protector(m_frame->view());
@@ -1815,19 +1839,15 @@
 
     bool swallowMouseUpEvent = !dispatchMouseEvent(eventNames().mouseupEvent, mev.targetNode(), true, m_clickCount, mouseEvent, false);
 
-    Node* clickTarget = mev.targetNode();
-    if (clickTarget)
-        clickTarget = clickTarget->deprecatedShadowAncestorNode();
-    Node* adjustedClickNode = m_clickNode ? m_clickNode->deprecatedShadowAncestorNode() : 0;
-
     bool contextMenuEvent = mouseEvent.button() == RightButton;
 #if PLATFORM(CHROMIUM) && OS(DARWIN)
     // FIXME: The Mac port achieves the same behavior by checking whether the context menu is currently open in WebPage::mouseEvent(). Consider merging the implementations.
     if (mouseEvent.button() == LeftButton && mouseEvent.modifiers() & PlatformEvent::CtrlKey)
         contextMenuEvent = true;
 #endif
-    bool swallowClickEvent = m_clickCount > 0 && !contextMenuEvent && clickTarget == adjustedClickNode && !dispatchMouseEvent(eventNames().clickEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
 
+    bool swallowClickEvent = m_clickCount > 0 && !contextMenuEvent && mouseIsReleasedOnPressedElement(mev.targetNode(), m_clickNode.get()) && !dispatchMouseEvent(eventNames().clickEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
+
     if (m_resizeLayer) {
         m_resizeLayer->setInResizeMode(false);
         m_resizeLayer = 0;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to