Bug 1145910 - Cross ShadowRoot boundary when updating ancestor state in event state manager. r=smaug
authorWilliam Chen <wchen@mozilla.com>
Tue, 24 Mar 2015 03:55:52 -0700
changeset 265557 380fb64847762a27d7a240eb44d081bcdc247bd2
parent 265556 aaf374ba062f13185c09a044e419ee5b5438bba4
child 265558 5850aa2851fe3706a75327b1495f2d3decb6af37
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1145910
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1145910 - Cross ShadowRoot boundary when updating ancestor state in event state manager. r=smaug
dom/events/EventStateManager.cpp
dom/events/test/mochitest.ini
dom/events/test/test_bug1145910.html
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -4641,17 +4641,17 @@ EventStateManager::DoStateChange(nsICont
 /* static */
 void
 EventStateManager::UpdateAncestorState(nsIContent* aStartNode,
                                        nsIContent* aStopBefore,
                                        EventStates aState,
                                        bool aAddState)
 {
   for (; aStartNode && aStartNode != aStopBefore;
-       aStartNode = aStartNode->GetParent()) {
+       aStartNode = aStartNode->GetParentElementCrossingShadowRoot()) {
     // We might be starting with a non-element (e.g. a text node) and
     // if someone is doing something weird might be ending with a
     // non-element too (e.g. a document fragment)
     if (!aStartNode->IsElement()) {
       continue;
     }
     Element* element = aStartNode->AsElement();
     DoStateChange(element, aState, aAddState);
@@ -4669,17 +4669,17 @@ EventStateManager::UpdateAncestorState(n
     // same node, and while one is no longer hovered the other still
     // is.  In that situation, the label that's still hovered will be
     // aStopBefore or some ancestor of it, and the call we just made
     // to UpdateAncestorState with aAddState = false would have
     // removed the hover state from the node.  But the node should
     // still be in hover state.  To handle this situation we need to
     // keep walking up the tree and any time we find a label mark its
     // corresponding node as still in our state.
-    for ( ; aStartNode; aStartNode = aStartNode->GetParent()) {
+    for ( ; aStartNode; aStartNode = aStartNode->GetParentElementCrossingShadowRoot()) {
       if (!aStartNode->IsElement()) {
         continue;
       }
 
       Element* labelTarget = GetLabelTarget(aStartNode->AsElement());
       if (labelTarget && !labelTarget->State().HasState(aState)) {
         DoStateChange(labelTarget, aState, true);
       }
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -136,16 +136,17 @@ skip-if = buildapp == 'b2g'
 skip-if = toolkit == "gonk" || e10s
 [test_bug985988.html]
 [test_bug998809.html]
 [test_bug1017086_disable.html]
 support-files = bug1017086_inner.html
 [test_bug1017086_enable.html]
 support-files = bug1017086_inner.html
 [test_bug1079236.html]
+[test_bug1145910.html]
 [test_clickevent_on_input.html]
 skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
 [test_continuous_wheel_events.html]
 skip-if = buildapp == 'b2g' || e10s # b2g(5535 passed, 108 failed - more tests running than desktop) b2g-debug(5535 passed, 108 failed - more tests running than desktop) b2g-desktop(5535 passed, 108 failed - more tests running than desktop)
 [test_dblclick_explicit_original_target.html]
 [test_dom_keyboard_event.html]
 skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
 [test_dom_mouse_event.html]
new file mode 100644
--- /dev/null
+++ b/dom/events/test/test_bug1145910.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1145910
+-->
+<head>
+  <title>Test for Bug 1145910</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<style>
+div:active {
+  color: rgb(0, 255, 0);
+}
+</style>
+<div id="host">Foo</div>
+<script type="application/javascript">
+
+/** Test for Bug 1145910 **/
+SimpleTest.waitForExplicitFinish();
+
+SimpleTest.waitForFocus(function() {
+  var host = document.getElementById("host");
+  var shadow = host.createShadowRoot();
+  shadow.innerHTML = '<style>div:active { color: rgb(0, 255, 0); }</style><div id="inner">Bar</div>';
+  var inner = shadow.getElementById("inner");
+
+  is(window.getComputedStyle(host).color, "rgb(0, 0, 0)", "The host should not be active");
+  is(window.getComputedStyle(inner).color, "rgb(0, 0, 0)", "The div inside the shadow root should not be active.");
+
+  synthesizeMouseAtCenter(host, { type: "mousedown" });
+
+  is(window.getComputedStyle(inner).color, "rgb(0, 255, 0)", "Div inside shadow root should be active.");
+  is(window.getComputedStyle(host).color, "rgb(0, 255, 0)", "Host should be active when the inner div is made active.");
+
+  synthesizeMouseAtCenter(host, { type: "mouseup" });
+
+  is(window.getComputedStyle(inner).color, "rgb(0, 0, 0)", "Div inside shadow root should no longer be active.");
+  is(window.getComputedStyle(host).color, "rgb(0, 0, 0)", "Host should no longer be active.");
+
+  SimpleTest.finish();
+});
+
+</script>
+</body>
+</html>