Diff
Modified: trunk/LayoutTests/ChangeLog (118644 => 118645)
--- trunk/LayoutTests/ChangeLog 2012-05-28 04:22:47 UTC (rev 118644)
+++ trunk/LayoutTests/ChangeLog 2012-05-28 04:39:30 UTC (rev 118645)
@@ -1,3 +1,13 @@
+2012-05-27 Hayato Ito <[email protected]>
+
+ Support multiple shadow roots in event dispatching.
+ https://bugs.webkit.org/show_bug.cgi?id=87470
+
+ Reviewed by Dimitri Glazkov.
+
+ * fast/dom/shadow/shadow-dom-event-dispatching-expected.txt:
+ * fast/dom/shadow/shadow-dom-event-dispatching.html:
+
2012-05-27 Takashi Sakamoto <[email protected]>
fast/dom/shadow/content-element-in-media.html is wrong.
Modified: trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-expected.txt (118644 => 118645)
--- trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-expected.txt 2012-05-28 04:22:47 UTC (rev 118644)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-expected.txt 2012-05-28 04:39:30 UTC (rev 118645)
@@ -321,6 +321,60 @@
@shadow-root-B (target: active-content) (related: A)
@B (target: child-of-inactive-content) (related: A)
@top (target: child-of-inactive-content) (related: A)
+
+
+Composed Shadow Tree will be:
+DIV id=sandbox
+ DIV id=top
+ DIV id=A
+ DIV id=B
+ DIV id=D
+ DIV id=F
+
+
+Moving mouse from B to A
+
+ mouseout
+ @B (target: B) (related: A)
+ @C (target: C) (related: A)
+ @older-shadow-root (target: C) (related: A)
+ @E (target: E) (related: A)
+ @younger-shadow-root (target: E) (related: A)
+ @A (target: B) (related: A)
+ @top (target: B) (related: A)
+
+ mouseover
+ @A (target: A) (related: B)
+ @top (target: A) (related: B)
+
+Moving mouse from A/D to A//F
+
+ mouseout
+ @D (target: D) (related: A)
+ @older-shadow-root (target: D) (related: A)
+ @E (target: E) (related: F)
+ @younger-shadow-root (target: E) (related: F)
+
+ mouseover
+ @F (target: F) (related: E)
+ @younger-shadow-root (target: F) (related: E)
+
+Moving mouse from B to A//F
+
+ mouseout
+ @B (target: B) (related: A)
+ @C (target: C) (related: A)
+ @older-shadow-root (target: C) (related: A)
+ @E (target: E) (related: F)
+ @younger-shadow-root (target: E) (related: F)
+ @A (target: B) (related: A)
+ @top (target: B) (related: A)
+
+ mouseover
+ @F (target: F) (related: E)
+ @younger-shadow-root (target: F) (related: E)
+ @A (target: A) (related: B)
+ @top (target: A) (related: B)
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching.html (118644 => 118645)
--- trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching.html 2012-05-28 04:22:47 UTC (rev 118644)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching.html 2012-05-28 04:39:30 UTC (rev 118645)
@@ -225,6 +225,27 @@
debug('\n\nComposed Shadow Tree will be:\n' + dumpComposedShadowTree(parent));
}
+// Hosting multiple shadow roots
+function prepareDOMTree8(parent)
+{
+ parent.appendChild(
+ createDOM('div', {'id': 'top'},
+ createDOM('div', {'id': 'A'},
+ createShadowRoot(
+ createDOM('content', {'id': 'C'}),
+ createDOM('div', {'id': 'D'})),
+ createShadowRoot(
+ createDOM('shadow', {'id': 'E'}),
+ createDOM('div', {'id': 'F'})),
+ createDOM('div', {'id': 'B'}))));
+
+ addEventListeners(['top', 'A', 'B', 'A/', 'A/C', 'A/D', 'A//', 'A//E', 'A//F']);
+ getNodeInShadowTreeStack('A/').id = 'older-shadow-root';
+ getNodeInShadowTreeStack('A//').id = 'younger-shadow-root';
+ parent.offsetLeft;
+ debug('\n\nComposed Shadow Tree will be:\n' + dumpComposedShadowTree(parent));
+}
+
function debugDispatchedEvent(eventType)
{
debug('\n ' + eventType);
@@ -317,6 +338,11 @@
moveMouse('A', 'child-of-inactive-content');
sandbox.innerHTML = '';
+ prepareDOMTree8(sandbox);
+
+ moveMouse('B', 'A');
+ moveMouse('A/D', 'A//F');
+ moveMouse('B', 'A//F');
}
test();
Modified: trunk/Source/WebCore/ChangeLog (118644 => 118645)
--- trunk/Source/WebCore/ChangeLog 2012-05-28 04:22:47 UTC (rev 118644)
+++ trunk/Source/WebCore/ChangeLog 2012-05-28 04:39:30 UTC (rev 118645)
@@ -1,3 +1,22 @@
+2012-05-27 Hayato Ito <[email protected]>
+
+ Support multiple shadow roots in event dispatching.
+ https://bugs.webkit.org/show_bug.cgi?id=87470
+
+ Reviewed by Dimitri Glazkov.
+
+ The current implementation does not set event's target correctly
+ if an event happens on DOM tree with multiple shadow roots. So
+ this patch updates an event re-targeting algorithm so that it
+ works even if it is applied to multiple shadow roots.
+
+ Tests: fast/dom/shadow/shadow-dom-event-dispatching.html
+
+ * dom/ComposedShadowTreeWalker.cpp:
+ (WebCore::ComposedShadowTreeWalker::traverseParentIncludingInsertionPointAndShadowRoot):
+ * dom/EventDispatcher.cpp:
+ (WebCore::EventDispatcher::ensureEventAncestors):
+
2012-05-27 Benjamin Poulain <[email protected]>
Minor code cleaning for the interface of MainResourceLoader
Modified: trunk/Source/WebCore/dom/EventDispatcher.cpp (118644 => 118645)
--- trunk/Source/WebCore/dom/EventDispatcher.cpp 2012-05-28 04:22:47 UTC (rev 118644)
+++ trunk/Source/WebCore/dom/EventDispatcher.cpp 2012-05-28 04:39:30 UTC (rev 118645)
@@ -199,37 +199,23 @@
{
if (m_ancestorsInitialized)
return;
-
- ComposedShadowTreeWalker ancestorWalker(m_node.get());
- EventTarget* originalTarget = eventTargetRespectingSVGTargetRules(ancestorWalker.get());
- m_ancestors.append(EventContext(m_node.get(), originalTarget, originalTarget));
m_ancestorsInitialized = true;
-
- if (!m_node->inDocument())
- return;
-
+ bool inDocument = m_node->inDocument();
+ bool isSVGElement = m_node->isSVGElement();
Vector<EventTarget*> targetStack;
- targetStack.append(originalTarget);
- while (true) {
- if (ancestorWalker.get()->isShadowRoot()) {
- if (determineDispatchBehavior(event, toShadowRoot(ancestorWalker.get())) == StayInsideShadowDOM)
- return;
- ancestorWalker.parentIncludingInsertionPointAndShadowRoot();
- if (!ancestorWalker.get())
- return;
- if (!m_node->isSVGElement()) {
- targetStack.removeLast();
- if (targetStack.isEmpty())
- targetStack.append(ancestorWalker.get());
- }
- } else {
- ancestorWalker.parentIncludingInsertionPointAndShadowRoot();
- if (!ancestorWalker.get())
- return;
- if (isInsertionPoint(ancestorWalker.get()) && toInsertionPoint(ancestorWalker.get())->isActive())
- targetStack.append(ancestorWalker.get());
- }
- m_ancestors.append(EventContext(ancestorWalker.get(), eventTargetRespectingSVGTargetRules(ancestorWalker.get()), targetStack.last()));
+ for (ComposedShadowTreeWalker walker(m_node.get()); walker.get(); walker.parentIncludingInsertionPointAndShadowRoot()) {
+ Node* node = walker.get();
+ if (isActiveInsertionPoint(node) || targetStack.isEmpty())
+ targetStack.append(eventTargetRespectingSVGTargetRules(node));
+ m_ancestors.append(EventContext(node, eventTargetRespectingSVGTargetRules(node), targetStack.last()));
+ if (!inDocument)
+ return;
+ if (!node->isShadowRoot())
+ continue;
+ if (determineDispatchBehavior(event, toShadowRoot(node)) == StayInsideShadowDOM)
+ return;
+ if (!isSVGElement && !targetStack.isEmpty())
+ targetStack.removeLast();
}
}