Diff
Modified: trunk/LayoutTests/ChangeLog (136917 => 136918)
--- trunk/LayoutTests/ChangeLog 2012-12-07 02:57:21 UTC (rev 136917)
+++ trunk/LayoutTests/ChangeLog 2012-12-07 03:03:26 UTC (rev 136918)
@@ -1,3 +1,15 @@
+2012-12-06 Hayato Ito <hay...@chromium.org>
+
+ Event's relatedTarget re-targeting does not occur for manually fired mouse events created by event.initMouseEvent().
+ https://bugs.webkit.org/show_bug.cgi?id=102681
+
+ Reviewed by Dimitri Glazkov.
+
+ * fast/dom/shadow/shadow-dom-event-dispatching-expected.txt:
+ * fast/dom/shadow/shadow-dom-event-dispatching.html:
+ * fast/events/dispatch-synthetic-mouseevent-expected.txt: Added.
+ * fast/events/dispatch-synthetic-mouseevent.html: Added.
+
2012-12-06 Kunihiko Sakamoto <ksakam...@chromium.org>
Disabled file input box stops a certain other div from being rendered
Modified: trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-expected.txt (136917 => 136918)
--- trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-expected.txt 2012-12-07 02:57:21 UTC (rev 136917)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-expected.txt 2012-12-07 03:03:26 UTC (rev 136918)
@@ -435,6 +435,35 @@
@shadow-root (target: non-used-fallback)
@A (target: A)
@top (target: A)
+
+
+Composed Shadow Tree will be:
+DIV id=sandbox
+ DIV id=top
+ DIV id=host
+ DIV id=div1
+ DIV id=div2
+
+
+ mouseout
+
+ mouseover
+ @div2 (target: div2) (related: div1)
+ @shadow-root (target: div2) (related: div1)
+
+
+Composed Shadow Tree will be:
+DIV id=sandbox
+ DIV id=top
+ DIV id=host
+ DIV id=div1
+
+
+ mouseout
+
+ mouseover
+ @div1 (target: div1) (related: div1)
+ @shadow-root (target: div1) (related: div1)
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching.html (136917 => 136918)
--- trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching.html 2012-12-07 02:57:21 UTC (rev 136917)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching.html 2012-12-07 03:03:26 UTC (rev 136918)
@@ -378,6 +378,58 @@
debugDispatchedEvent('click');
}
+function testEventsFiredManually()
+{
+ sandbox.innerHTML = '';
+ sandbox.appendChild(
+ createDOM('div', {'id': 'top'},
+ createDOM('div', {'id': 'host'},
+ createShadowRoot(
+ createDOM('div', {'id': 'div1'}),
+ createDOM('div', {'id': 'div2'})))));
+
+ addEventListeners(['top', 'host', 'host/', 'host/div1', 'host/div2']);
+ getNodeInShadowTreeStack('host/').id = 'shadow-root';
+ showSandboxTree();
+
+ var div1 = getNodeInShadowTreeStack('host/div1');
+ var div2 = getNodeInShadowTreeStack('host/div2');
+
+ clearEventRecords();
+ var event = document.createEvent("MouseEvents");
+ event.initMouseEvent("mouseover", true, false, window,
+ 0, 10, 10, 10, 10, false, false, false, false, 0, div1);
+ div2.dispatchEvent(event);
+
+ debugDispatchedEvent('mouseout');
+ debugDispatchedEvent('mouseover');
+}
+
+function testEventsFiredManuallyWithRelatedTargetSameToTarget()
+{
+ sandbox.innerHTML = '';
+ sandbox.appendChild(
+ createDOM('div', {'id': 'top'},
+ createDOM('div', {'id': 'host'},
+ createShadowRoot(
+ createDOM('div', {'id': 'div1'})))));
+
+ addEventListeners(['top', 'host', 'host/', 'host/div1']);
+ getNodeInShadowTreeStack('host/').id = 'shadow-root';
+ showSandboxTree();
+
+ var div1 = getNodeInShadowTreeStack('host/div1');
+
+ clearEventRecords();
+ var event = document.createEvent("MouseEvents");
+ event.initMouseEvent("mouseover", true, false, window,
+ 0, 10, 10, 10, 10, false, false, false, false, 0, div1);
+ div1.dispatchEvent(event);
+
+ debugDispatchedEvent('mouseout');
+ debugDispatchedEvent('mouseover');
+}
+
function test()
{
if (window.testRunner)
@@ -393,6 +445,8 @@
testEventsOnMultipleShadowRoots();
testEventsOnNonDistributedNodes();
testEventsOnFallbackElements();
+ testEventsFiredManually();
+ testEventsFiredManuallyWithRelatedTargetSameToTarget();
}
test();
Added: trunk/LayoutTests/fast/events/dispatch-synthetic-mouseevent-expected.txt (0 => 136918)
--- trunk/LayoutTests/fast/events/dispatch-synthetic-mouseevent-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/dispatch-synthetic-mouseevent-expected.txt 2012-12-07 03:03:26 UTC (rev 136918)
@@ -0,0 +1,10 @@
+Tests to ensure that dblclick event is not fired.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+click event is fired.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/events/dispatch-synthetic-mouseevent.html (0 => 136918)
--- trunk/LayoutTests/fast/events/dispatch-synthetic-mouseevent.html (rev 0)
+++ trunk/LayoutTests/fast/events/dispatch-synthetic-mouseevent.html 2012-12-07 03:03:26 UTC (rev 136918)
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id='top'>
+</div>
+<pre id="console"></pre>
+<script>
+description("Tests to ensure that dblclick event is not fired.");
+
+function clickHandler(event)
+{
+ debug('click event is fired.');
+}
+
+function dblclickHandler(event)
+{
+ testFailed('dblclick event should not be fired.');
+}
+
+function test()
+{
+ if (window.testRunner)
+ testRunner.dumpAsText();
+
+ var node = document.getElementById('top');
+ node.addEventListener('click', clickHandler, false);
+ node.addEventListener('dblclick', dblclickHandler, false);
+
+ var event = document.createEvent("MouseEvents");
+ var details = 2;
+ event.initMouseEvent("click", true, false, window,
+ details, 10, 10, 10, 10, false, false, false, false, 0, null);
+ node.dispatchEvent(event);
+}
+
+test();
+</script>
+<script src=""
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (136917 => 136918)
--- trunk/Source/WebCore/ChangeLog 2012-12-07 02:57:21 UTC (rev 136917)
+++ trunk/Source/WebCore/ChangeLog 2012-12-07 03:03:26 UTC (rev 136918)
@@ -1,3 +1,31 @@
+2012-12-06 Hayato Ito <hay...@chromium.org>
+
+ Event's relatedTarget re-targeting does not occur for manually fired mouse events created by event.initMouseEvent().
+ https://bugs.webkit.org/show_bug.cgi?id=102681
+
+ Reviewed by Dimitri Glazkov.
+
+ Make sure that event's relatedTarget re-targeting occurs for mouse
+ events created by event.initMouseEvent(). Since user-generated
+ mouse events can have a relatedTarget which is same to the target
+ node, the algorithm which calculates event's ancestors is also
+ updated so that ancestors are not shrunk wrongly.
+
+ Test: fast/events/dispatch-synthetic-mouseevent.html
+ fast/dom/shadow/shadow-dom-event-dispatching.html
+
+ * dom/EventDispatcher.cpp:
+ (WebCore::EventRelatedTargetAdjuster::adjust):
+ * dom/MouseEvent.cpp:
+ (WebCore::MouseEventDispatchMediator::create):
+ (WebCore::MouseEventDispatchMediator::MouseEventDispatchMediator):
+ (WebCore::MouseEventDispatchMediator::dispatchEvent):
+ * dom/MouseEvent.h:
+ (WebCore::MouseEventDispatchMediator::isSyntheticMouseEvent):
+ (MouseEventDispatchMediator):
+ * dom/Node.cpp:
+ (WebCore::Node::dispatchEvent):
+
2012-12-06 Kunihiko Sakamoto <ksakam...@chromium.org>
Disabled file input box stops a certain other div from being rendered
Modified: trunk/Source/WebCore/dom/EventDispatcher.cpp (136917 => 136918)
--- trunk/Source/WebCore/dom/EventDispatcher.cpp 2012-12-07 02:57:21 UTC (rev 136917)
+++ trunk/Source/WebCore/dom/EventDispatcher.cpp 2012-12-07 03:03:26 UTC (rev 136918)
@@ -62,6 +62,9 @@
void EventRelatedTargetAdjuster::adjust(Vector<EventContext>& ancestors)
{
+ // Synthetic mouse events can have a relatedTarget which is identical to the target.
+ bool targetIsIdenticalToToRelatedTarget = (m_node.get() == m_relatedTarget.get());
+
Vector<EventTarget*> relatedTargetStack;
TreeScope* lastTreeScope = 0;
for (AncestorChainWalker walker(m_relatedTarget.get()); walker.get(); walker.parent()) {
@@ -93,7 +96,12 @@
iter->setRelatedTarget(adjustedRelatedTarget);
}
lastTreeScope = scope;
- if (iter->target() == adjustedRelatedTarget) {
+ if (targetIsIdenticalToToRelatedTarget) {
+ if (m_node->treeScope()->rootNode() == iter->node()) {
+ ancestors.shrink(iter + 1 - ancestors.begin());
+ break;
+ }
+ } else if (iter->target() == adjustedRelatedTarget) {
// Event dispatching should be stopped here.
ancestors.shrink(iter - ancestors.begin());
break;
Modified: trunk/Source/WebCore/dom/MouseEvent.cpp (136917 => 136918)
--- trunk/Source/WebCore/dom/MouseEvent.cpp 2012-12-07 02:57:21 UTC (rev 136917)
+++ trunk/Source/WebCore/dom/MouseEvent.cpp 2012-12-07 03:03:26 UTC (rev 136918)
@@ -209,13 +209,13 @@
}
}
-PassRefPtr<MouseEventDispatchMediator> MouseEventDispatchMediator::create(PassRefPtr<MouseEvent> mouseEvent)
+PassRefPtr<MouseEventDispatchMediator> MouseEventDispatchMediator::create(PassRefPtr<MouseEvent> mouseEvent, MouseEventType mouseEventType)
{
- return adoptRef(new MouseEventDispatchMediator(mouseEvent));
+ return adoptRef(new MouseEventDispatchMediator(mouseEvent, mouseEventType));
}
-MouseEventDispatchMediator::MouseEventDispatchMediator(PassRefPtr<MouseEvent> mouseEvent)
- : EventDispatchMediator(mouseEvent)
+MouseEventDispatchMediator::MouseEventDispatchMediator(PassRefPtr<MouseEvent> mouseEvent, MouseEventType mouseEventType)
+ : EventDispatchMediator(mouseEvent), m_mouseEventType(mouseEventType)
{
}
@@ -226,12 +226,19 @@
bool MouseEventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) const
{
+ if (isSyntheticMouseEvent()) {
+ dispatcher->adjustRelatedTarget(event(), event()->relatedTarget());
+ return dispatcher->dispatchEvent(event());
+ }
+
if (dispatcher->node()->disabled()) // Don't even send DOM events for disabled controls..
return false;
if (event()->type().isEmpty())
return true; // Shouldn't happen.
+ ASSERT(!event()->target() || event()->target() != event()->relatedTarget());
+
EventTarget* relatedTarget = event()->relatedTarget();
dispatcher->adjustRelatedTarget(event(), relatedTarget);
@@ -240,6 +247,7 @@
if (event()->type() != eventNames().clickEvent || event()->detail() != 2)
return !swallowEvent;
+
// Special case: If it's a double click event, we also send the dblclick event. This is not part
// of the DOM specs, but is used for compatibility with the _ondblclick_="" attribute. This is treated
// as a separate event in other DOM-compliant browsers like Firefox, and so we do the same.
Modified: trunk/Source/WebCore/dom/MouseEvent.h (136917 => 136918)
--- trunk/Source/WebCore/dom/MouseEvent.h 2012-12-07 02:57:21 UTC (rev 136917)
+++ trunk/Source/WebCore/dom/MouseEvent.h 2012-12-07 03:03:26 UTC (rev 136918)
@@ -115,13 +115,16 @@
class MouseEventDispatchMediator : public EventDispatchMediator {
public:
- static PassRefPtr<MouseEventDispatchMediator> create(PassRefPtr<MouseEvent>);
+ enum MouseEventType { SyntheticMouseEvent, NonSyntheticMouseEvent};
+ static PassRefPtr<MouseEventDispatchMediator> create(PassRefPtr<MouseEvent>, MouseEventType = NonSyntheticMouseEvent);
private:
- explicit MouseEventDispatchMediator(PassRefPtr<MouseEvent>);
+ explicit MouseEventDispatchMediator(PassRefPtr<MouseEvent>, MouseEventType);
MouseEvent* event() const;
virtual bool dispatchEvent(EventDispatcher*) const;
+ bool isSyntheticMouseEvent() const { return m_mouseEventType == SyntheticMouseEvent; }
+ MouseEventType m_mouseEventType;
};
inline MouseEvent* toMouseEvent(Event* event)
Modified: trunk/Source/WebCore/dom/Node.cpp (136917 => 136918)
--- trunk/Source/WebCore/dom/Node.cpp 2012-12-07 02:57:21 UTC (rev 136917)
+++ trunk/Source/WebCore/dom/Node.cpp 2012-12-07 03:03:26 UTC (rev 136918)
@@ -2481,6 +2481,8 @@
bool Node::dispatchEvent(PassRefPtr<Event> event)
{
+ if (event->isMouseEvent())
+ return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator::create(adoptRef(toMouseEvent(event.leakRef())), MouseEventDispatchMediator::SyntheticMouseEvent));
return EventDispatcher::dispatchEvent(this, EventDispatchMediator::create(event));
}