Title: [151839] trunk
Revision
151839
Author
[email protected]
Date
2013-06-21 09:03:10 -0700 (Fri, 21 Jun 2013)

Log Message

Improve the reattaching process while applying the :hover style
https://bugs.webkit.org/show_bug.cgi?id=117590

Patch by Radu Stavila <[email protected]> on 2013-06-21
Reviewed by Andreas Kling.

Source/WebCore:

Changes made:
    - context is properly propagated to the element's children and to Shadow DOM elements.
    - context is properly set on the lazyReattach method.
    - another hit-testing is triggered when needed.
    - when a hovered element is detached, it's ancestors are also removed from the hovered state.

Tests: fast/css/hover-display-block-inline.html
       fast/css/hover-display-block-none.html

* dom/ContainerNode.cpp:
(WebCore::ContainerNode::attach):
(WebCore::ContainerNode::detach):
* dom/ContainerNode.h:
(WebCore::ContainerNode::attachChildren):
(WebCore::ContainerNode::detachChildrenIfNeeded):
(WebCore::ContainerNode::detachChildren):
* dom/Document.cpp:
(WebCore::Document::recalcStyle):
(WebCore::Document::updateHoverActiveState):
* dom/Element.cpp:
(WebCore::Element::attach):
(WebCore::Element::detach):
* dom/ElementShadow.cpp:
(WebCore::ElementShadow::attach):
(WebCore::ElementShadow::detach):
* dom/ElementShadow.h:
* dom/Node.h:
(WebCore::Node::lazyReattach):

LayoutTests:

Moved hover-display-block-inline.html and hover-display-block-none.html from fast/regions to fast/css.
Updated hover-display-block-none.html and hover-single-flow-into-other.html to ensure the outcome won't be affected by the machine's speed.
Updated input-file-re-render.html to stop it from failing on windows and linux machines (a more detailed description can be found inside the test itself).

* fast/css/hover-display-block-inline-expected.txt: Renamed from LayoutTests/fast/regions/hover-display-block-inline-expected.txt.
* fast/css/hover-display-block-inline.html: Renamed from LayoutTests/fast/regions/hover-display-block-inline.html.
* fast/css/hover-display-block-none-expected.txt: Renamed from LayoutTests/fast/regions/hover-display-block-none-expected.txt.
* fast/css/hover-display-block-none.html: Added.
* fast/css/hover-update-expected.txt:
* fast/css/hover-update.html:
* fast/forms/file/input-file-re-render.html:
* fast/regions/hover-display-block-none.html: Removed.
* fast/regions/hover-single-flow-into-other.html:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (151838 => 151839)


--- trunk/LayoutTests/ChangeLog	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/LayoutTests/ChangeLog	2013-06-21 16:03:10 UTC (rev 151839)
@@ -1,3 +1,24 @@
+2013-06-21  Radu Stavila  <[email protected]>
+
+        Improve the reattaching process while applying the :hover style
+        https://bugs.webkit.org/show_bug.cgi?id=117590
+
+        Reviewed by Andreas Kling.
+
+        Moved hover-display-block-inline.html and hover-display-block-none.html from fast/regions to fast/css.
+        Updated hover-display-block-none.html and hover-single-flow-into-other.html to ensure the outcome won't be affected by the machine's speed.
+        Updated input-file-re-render.html to stop it from failing on windows and linux machines (a more detailed description can be found inside the test itself).
+
+        * fast/css/hover-display-block-inline-expected.txt: Renamed from LayoutTests/fast/regions/hover-display-block-inline-expected.txt.
+        * fast/css/hover-display-block-inline.html: Renamed from LayoutTests/fast/regions/hover-display-block-inline.html.
+        * fast/css/hover-display-block-none-expected.txt: Renamed from LayoutTests/fast/regions/hover-display-block-none-expected.txt.
+        * fast/css/hover-display-block-none.html: Added.
+        * fast/css/hover-update-expected.txt:
+        * fast/css/hover-update.html:
+        * fast/forms/file/input-file-re-render.html:
+        * fast/regions/hover-display-block-none.html: Removed.
+        * fast/regions/hover-single-flow-into-other.html:
+
 2013-06-21  Zalan Bujtas  <[email protected]>
 
         Rollout r150602: Restoring text-overflow vs. floating rendering behaviour.

Copied: trunk/LayoutTests/fast/css/hover-display-block-inline-expected.txt (from rev 151838, trunk/LayoutTests/fast/regions/hover-display-block-inline-expected.txt) (0 => 151839)


--- trunk/LayoutTests/fast/css/hover-display-block-inline-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/hover-display-block-inline-expected.txt	2013-06-21 16:03:10 UTC (rev 151839)
@@ -0,0 +1,2 @@
+PASS Setting display to inline on hover processed OK.
+

Copied: trunk/LayoutTests/fast/css/hover-display-block-inline.html (from rev 151838, trunk/LayoutTests/fast/regions/hover-display-block-inline.html) (0 => 151839)


--- trunk/LayoutTests/fast/css/hover-display-block-inline.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/hover-display-block-inline.html	2013-06-21 16:03:10 UTC (rev 151839)
@@ -0,0 +1,77 @@
+<!doctype html>
+<html lang="en">
+<head>
+	<title>Switch between display block and inline on :hover</title>
+	<style>
+		.box {
+			width: 100px;
+			height: 100px;
+		}
+		#dummy {
+			background-color: black;
+		}
+		#hoverTest {
+			border: 5px solid green;
+			border-left: 100px solid green;
+			color: black;
+			display: block;
+		}
+		#hoverTest:hover {
+			border-color: darkred;
+			display: inline;
+		}
+		#after_hoverTest {
+			background-color: blue;
+			color: white;
+			padding: 10px;
+		}
+	</style>
+
+	<script src=""
+</head>
+
+<script type="text/_javascript_">
+	if (window.testRunner)
+		testRunner.waitUntilDone();
+
+	function beginTest() {
+		if (window.eventSender) {
+			var hoverTest  = document.querySelector("#hoverTest");
+
+			// move mouse on the hover test object
+			eventSender.mouseMoveTo(hoverTest.offsetLeft + 50, hoverTest.offsetTop + 10);
+			eventSender.mouseDown(0);
+
+			setTimeout(release, 0);
+		}
+	}
+
+	function release() {
+		if (window.eventSender) {
+			var hoverTest  = document.querySelector("#hoverTest");
+			var displayMode = window.getComputedStyle(hoverTest).getPropertyValue("display");
+
+			if (displayMode == "inline")
+				testPassed("Setting display to inline on hover processed OK.");
+			else
+				testFailed("Setting display to inline on hover FAILED." + " (expected 'inline', got '" + displayMode + "')");
+
+			var elementsToHide = document.querySelectorAll(".box");
+			for (var i=0; i<elementsToHide.length; i++)
+				elementsToHide[i].style.visibility = "hidden";
+
+	        eventSender.mouseUp(0);
+
+	        if (window.testRunner)
+				setTimeout("testRunner.notifyDone()", 0);
+		}
+	}
+
+</script>
+
+<body _onload_="beginTest()">
+	<div id="dummy" class="box"></div>
+	<div id="hoverTest" class="box">When hovered, this box's display will switch from <b>block</b> to <b>inline</b></div>
+	<div id="after_hoverTest" class="box">This is here to show the layout being recomputed</div>
+</body>
+</html>
\ No newline at end of file

Copied: trunk/LayoutTests/fast/css/hover-display-block-none-expected.txt (from rev 151838, trunk/LayoutTests/fast/regions/hover-display-block-none-expected.txt) (0 => 151839)


--- trunk/LayoutTests/fast/css/hover-display-block-none-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/hover-display-block-none-expected.txt	2013-06-21 16:03:10 UTC (rev 151839)
@@ -0,0 +1,2 @@
+PASS Setting display to none on hover processed OK.
+

Added: trunk/LayoutTests/fast/css/hover-display-block-none.html (0 => 151839)


--- trunk/LayoutTests/fast/css/hover-display-block-none.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/hover-display-block-none.html	2013-06-21 16:03:10 UTC (rev 151839)
@@ -0,0 +1,83 @@
+<!doctype html>
+<html lang="en">
+<head>
+	<title>Switch between display block and none on :hover</title>
+	<style>
+		.box {
+			width: 100px;
+			height: 100px;
+		}
+		#dummy {
+			background-color: black;
+		}
+		#hoverTest {
+			border: 5px solid green;
+			border-left: 100px solid green;
+			color: black;
+			display: block;
+			width: 230px;
+		}
+		#hoverTest:hover {
+			border-color: darkred;
+			display: none;
+		}
+		#after_hoverTest {
+			background-color: blue;
+			color: white;
+			padding: 10px;
+		}
+	</style>
+
+	<script src=""
+</head>
+
+<script type="text/_javascript_">
+	function elementHovered() {
+		if (window.testRunner)
+			document.getElementById("hoverTest").style.display = "none";
+	}
+</script>
+
+<body>
+	<div id="dummy" class="box"></div>
+	<div id="hoverTest" class="box" _onmouseover_="elementHovered()">When hovered, this box's display will switch from <b>block</b> to <b>none</b> (click on it and keep the mouse button pushed to avoid flicker and get a more clear view)</div>
+	<div id="after_hoverTest" class="box">This is here to show the layout being recomputed</div>
+
+	<script type="text/_javascript_">
+		if (window.testRunner)
+			testRunner.waitUntilDone();
+
+		function beginTest() {
+			if (window.eventSender) {
+				var hoverTest  = document.getElementById("hoverTest");
+
+				// move mouse on the hover test object
+				eventSender.mouseMoveTo(hoverTest.offsetLeft + 50, hoverTest.offsetTop + 10);
+
+				release();
+			}
+		}
+
+		function release() {
+			if (window.eventSender) {
+				var hoverTest  = document.getElementById("hoverTest");
+				var displayMode = window.getComputedStyle(hoverTest).getPropertyValue("display");
+
+				if (displayMode == "none")
+					testPassed("Setting display to none on hover processed OK.");
+				else
+					testFailed("Setting display to none on hover FAILED." + " (expected 'none', got '" + displayMode + "')");
+
+				var elementsToHide = document.getElementsByClassName('box');
+				for (var element, i = 0; element = elementsToHide[i]; i++)
+				    element.style.visibility = "hidden";
+
+				if (window.testRunner)
+					testRunner.notifyDone();
+			}
+		}
+
+		beginTest();
+	</script>
+</body>
+</html>
\ No newline at end of file

Modified: trunk/LayoutTests/fast/css/hover-update-expected.txt (151838 => 151839)


--- trunk/LayoutTests/fast/css/hover-update-expected.txt	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/LayoutTests/fast/css/hover-update-expected.txt	2013-06-21 16:03:10 UTC (rev 151839)
@@ -5,4 +5,5 @@
 Only green now
 Hover color before test: rgb(255, 255, 0)
 PASS window.getComputedStyle(document.getElementById('b'), null).backgroundColor is "rgb(0, 128, 0)"
+PASS window.getComputedStyle(document.getElementById('a'), null).backgroundColor is "rgb(0, 128, 0)"
 

Modified: trunk/LayoutTests/fast/css/hover-update.html (151838 => 151839)


--- trunk/LayoutTests/fast/css/hover-update.html	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/LayoutTests/fast/css/hover-update.html	2013-06-21 16:03:10 UTC (rev 151839)
@@ -29,6 +29,7 @@
         return;
     }
     shouldBeEqualToString("window.getComputedStyle(document.getElementById('b'), null).backgroundColor", expectedBackgroundColor);
+    shouldBeEqualToString("window.getComputedStyle(document.getElementById('a'), null).backgroundColor", expectedBackgroundColor);
 
     if (window.testRunner)
         testRunner.notifyDone();

Modified: trunk/LayoutTests/fast/forms/file/input-file-re-render.html (151838 => 151839)


--- trunk/LayoutTests/fast/forms/file/input-file-re-render.html	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/LayoutTests/fast/forms/file/input-file-re-render.html	2013-06-21 16:03:10 UTC (rev 151839)
@@ -16,6 +16,13 @@
     eventSender.mouseMoveTo(10, 10);
     eventSender.mouseUp();
 
+    // Move the mouse away before moving on. This is done because landing the patch for bug 117590
+    // would cause this test to fail. That patch fixes a hover problem which causes this test
+    // to actually perform correctly (after switching back to display: inline-block, the style of 
+    // the file control would be 'hovered', since it's under the mouse). However, the 'expected'
+    // PNG files were created when this was not working properly, and the control is in its un-hovered state.
+    eventSender.mouseMoveTo(300, 300);
+
     // Delete the renderer.
     input.style.display = 'none';
     input.offsetWidth; // Force to do layout

Deleted: trunk/LayoutTests/fast/regions/hover-display-block-inline-expected.txt (151838 => 151839)


--- trunk/LayoutTests/fast/regions/hover-display-block-inline-expected.txt	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/LayoutTests/fast/regions/hover-display-block-inline-expected.txt	2013-06-21 16:03:10 UTC (rev 151839)
@@ -1,2 +0,0 @@
-PASS Setting display to inline on hover processed OK.
-

Deleted: trunk/LayoutTests/fast/regions/hover-display-block-inline.html (151838 => 151839)


--- trunk/LayoutTests/fast/regions/hover-display-block-inline.html	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/LayoutTests/fast/regions/hover-display-block-inline.html	2013-06-21 16:03:10 UTC (rev 151839)
@@ -1,77 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
-	<title>Switch between display block and inline on :hover</title>
-	<style>
-		.box {
-			width: 100px;
-			height: 100px;
-		}
-		#dummy {
-			background-color: black;
-		}
-		#hoverTest {
-			border: 5px solid green;
-			border-left: 100px solid green;
-			color: black;
-			display: block;
-		}
-		#hoverTest:hover {
-			border-color: darkred;
-			display: inline;
-		}
-		#after_hoverTest {
-			background-color: blue;
-			color: white;
-			padding: 10px;
-		}
-	</style>
-
-	<script src=""
-</head>
-
-<script type="text/_javascript_">
-	if (window.testRunner)
-		testRunner.waitUntilDone();
-
-	function beginTest() {
-		if (window.eventSender) {
-			var hoverTest  = document.querySelector("#hoverTest");
-
-			// move mouse on the hover test object
-			eventSender.mouseMoveTo(hoverTest.offsetLeft + 50, hoverTest.offsetTop + 10);
-			eventSender.mouseDown(0);
-
-			setTimeout(release, 0);
-		}
-	}
-
-	function release() {
-		if (window.eventSender) {
-			var hoverTest  = document.querySelector("#hoverTest");
-			var displayMode = window.getComputedStyle(hoverTest).getPropertyValue("display");
-
-			if (displayMode == "inline")
-				testPassed("Setting display to inline on hover processed OK.");
-			else
-				testFailed("Setting display to inline on hover FAILED." + " (expected 'inline', got '" + displayMode + "')");
-
-			var elementsToHide = document.querySelectorAll(".box");
-			for (var i=0; i<elementsToHide.length; i++)
-				elementsToHide[i].style.visibility = "hidden";
-
-	        eventSender.mouseUp(0);
-
-	        if (window.testRunner)
-				setTimeout("testRunner.notifyDone()", 0);
-		}
-	}
-
-</script>
-
-<body _onload_="beginTest()">
-	<div id="dummy" class="box"></div>
-	<div id="hoverTest" class="box">When hovered, this box's display will switch from <b>block</b> to <b>inline</b></div>
-	<div id="after_hoverTest" class="box">This is here to show the layout being recomputed</div>
-</body>
-</html>
\ No newline at end of file

Deleted: trunk/LayoutTests/fast/regions/hover-display-block-none-expected.txt (151838 => 151839)


--- trunk/LayoutTests/fast/regions/hover-display-block-none-expected.txt	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/LayoutTests/fast/regions/hover-display-block-none-expected.txt	2013-06-21 16:03:10 UTC (rev 151839)
@@ -1,2 +0,0 @@
-PASS Setting display to none on hover processed OK.
-

Deleted: trunk/LayoutTests/fast/regions/hover-display-block-none.html (151838 => 151839)


--- trunk/LayoutTests/fast/regions/hover-display-block-none.html	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/LayoutTests/fast/regions/hover-display-block-none.html	2013-06-21 16:03:10 UTC (rev 151839)
@@ -1,75 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
-	<title>Switch between display block and none on :hover</title>
-	<style>
-		.box {
-			width: 100px;
-			height: 100px;
-		}
-		#dummy {
-			background-color: black;
-		}
-		#hoverTest {
-			border: 5px solid green;
-			border-left: 100px solid green;
-			color: black;
-			display: block;
-			width: 230px;
-		}
-		#hoverTest:hover {
-			border-color: darkred;
-			display: none;
-		}
-		#after_hoverTest {
-			background-color: blue;
-			color: white;
-			padding: 10px;
-		}
-	</style>
-
-	<script src=""
-</head>
-
-<script type="text/_javascript_">
-	if (window.testRunner)
-		testRunner.waitUntilDone();
-
-	function beginTest() {
-		if (window.eventSender) {
-			var hoverTest  = document.querySelector("#hoverTest");
-
-			// move mouse on the hover test object
-			eventSender.mouseMoveTo(hoverTest.offsetLeft + 50, hoverTest.offsetTop + 10);
-
-			setTimeout(release, 0);
-		}
-	}
-
-	function release() {
-		if (window.eventSender) {
-			var hoverTest  = document.querySelector("#hoverTest");
-			var displayMode = window.getComputedStyle(hoverTest).getPropertyValue("display");
-
-			if (displayMode == "none")
-				testPassed("Setting display to none on hover processed OK.");
-			else
-				testFailed("Setting display to none on hover FAILED." + " (expected 'none', got '" + displayMode + "')");
-
-			var elementsToHide = document.querySelectorAll(".box");
-			for (var i=0; i<elementsToHide.length; i++)
-				elementsToHide[i].style.visibility = "hidden";
-
-			if (window.testRunner)
-				setTimeout("testRunner.notifyDone()", 0);
-		}
-	}
-
-</script>
-
-<body _onload_="beginTest()">
-	<div id="dummy" class="box"></div>
-	<div id="hoverTest" class="box">When hovered, this box's display will switch from <b>block</b> to <b>none</b> (click on it and keep the mouse button pushed to avoid flicker and get a more clear view)</div>
-	<div id="after_hoverTest" class="box">This is here to show the layout being recomputed</div>
-</body>
-</html>
\ No newline at end of file

Modified: trunk/LayoutTests/fast/regions/hover-single-flow-into-other.html (151838 => 151839)


--- trunk/LayoutTests/fast/regions/hover-single-flow-into-other.html	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/LayoutTests/fast/regions/hover-single-flow-into-other.html	2013-06-21 16:03:10 UTC (rev 151839)
@@ -59,10 +59,18 @@
 	}
 </script>
 
+<script type="text/_javascript_">
+	function elementHovered() {
+		if (window.testRunner)
+			document.getElementById("content").style.webkitFlowInto = "flow2";
+	}
+</script>
+
+
 <body _onload_="beginTest()">
 	<p>When hovering the <span style="color:blue"><b>blue box</b></span>, it should move to the <span style="color:darkred"><b>second region</b></span> (it's <b>flow-into</b> will change to the 2nd thread)</p>
 	<div id="region1"></div>
 	<div id="region2"></div>
-	<div id="content" class="box">This box is flowed into the <span style="color:green"><b>first region</b></span> when it is <b>not</b> hovered and into the <span style="color:darkred"><b>second region</b></span> when it <b>is</b></div>
+	<div id="content" class="box" _onmouseover_="elementHovered()">This box is flowed into the <span style="color:green"><b>first region</b></span> when it is <b>not</b> hovered and into the <span style="color:darkred"><b>second region</b></span> when it <b>is</b></div>
 </body>
 </html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (151838 => 151839)


--- trunk/Source/WebCore/ChangeLog	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/Source/WebCore/ChangeLog	2013-06-21 16:03:10 UTC (rev 151839)
@@ -1,3 +1,39 @@
+2013-06-21  Radu Stavila  <[email protected]>
+
+        Improve the reattaching process while applying the :hover style
+        https://bugs.webkit.org/show_bug.cgi?id=117590
+
+        Reviewed by Andreas Kling.
+
+        Changes made:
+            - context is properly propagated to the element's children and to Shadow DOM elements.
+            - context is properly set on the lazyReattach method.
+            - another hit-testing is triggered when needed.
+            - when a hovered element is detached, it's ancestors are also removed from the hovered state.
+
+        Tests: fast/css/hover-display-block-inline.html
+               fast/css/hover-display-block-none.html
+
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::attach):
+        (WebCore::ContainerNode::detach):
+        * dom/ContainerNode.h:
+        (WebCore::ContainerNode::attachChildren):
+        (WebCore::ContainerNode::detachChildrenIfNeeded):
+        (WebCore::ContainerNode::detachChildren):
+        * dom/Document.cpp:
+        (WebCore::Document::recalcStyle):
+        (WebCore::Document::updateHoverActiveState):
+        * dom/Element.cpp:
+        (WebCore::Element::attach):
+        (WebCore::Element::detach):
+        * dom/ElementShadow.cpp:
+        (WebCore::ElementShadow::attach):
+        (WebCore::ElementShadow::detach):
+        * dom/ElementShadow.h:
+        * dom/Node.h:
+        (WebCore::Node::lazyReattach):
+
 2013-06-21  Allan Sandfeld Jensen  <[email protected]>
 
         HTMLMediaElement should inherit from MediaPlayerClient privately

Modified: trunk/Source/WebCore/dom/ContainerNode.cpp (151838 => 151839)


--- trunk/Source/WebCore/dom/ContainerNode.cpp	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/Source/WebCore/dom/ContainerNode.cpp	2013-06-21 16:03:10 UTC (rev 151839)
@@ -789,13 +789,13 @@
 
 void ContainerNode::attach(const AttachContext& context)
 {
-    attachChildren();
+    attachChildren(context);
     Node::attach(context);
 }
 
 void ContainerNode::detach(const AttachContext& context)
 {
-    detachChildren();
+    detachChildren(context);
     clearChildNeedsStyleRecalc();
     Node::detach(context);
 }

Modified: trunk/Source/WebCore/dom/ContainerNode.h (151838 => 151839)


--- trunk/Source/WebCore/dom/ContainerNode.h	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/Source/WebCore/dom/ContainerNode.h	2013-06-21 16:03:10 UTC (rev 151839)
@@ -118,10 +118,10 @@
     // node that is of the type CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value.
     virtual void childrenChanged(bool createdByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
 
-    void attachChildren();
+    void attachChildren(const AttachContext& = AttachContext());
     void attachChildrenLazily();
-    void detachChildren();
-    void detachChildrenIfNeeded();
+    void detachChildren(const AttachContext& = AttachContext());
+    void detachChildrenIfNeeded(const AttachContext& = AttachContext());
 
     void disconnectDescendantFrames();
 
@@ -184,12 +184,15 @@
 {
 }
 
-inline void ContainerNode::attachChildren()
+inline void ContainerNode::attachChildren(const AttachContext& context)
 {
+    AttachContext childrenContext(context);
+    childrenContext.resolvedStyle = 0;
+
     for (Node* child = firstChild(); child; child = child->nextSibling()) {
         ASSERT(!child->attached() || childAttachedAllowedWhenAttachingChildren(this));
         if (!child->attached())
-            child->attach();
+            child->attach(childrenContext);
     }
 }
 
@@ -200,18 +203,24 @@
             child->lazyAttach();
 }
 
-inline void ContainerNode::detachChildrenIfNeeded()
+inline void ContainerNode::detachChildrenIfNeeded(const AttachContext& context)
 {
+    AttachContext childrenContext(context);
+    childrenContext.resolvedStyle = 0;
+
     for (Node* child = firstChild(); child; child = child->nextSibling()) {
         if (child->attached())
-            child->detach();
+            child->detach(childrenContext);
     }
 }
 
-inline void ContainerNode::detachChildren()
+inline void ContainerNode::detachChildren(const AttachContext& context)
 {
+    AttachContext childrenContext(context);
+    childrenContext.resolvedStyle = 0;
+
     for (Node* child = firstChild(); child; child = child->nextSibling())
-        child->detach();
+        child->detach(childrenContext);
 }
 
 inline unsigned Node::childNodeCount() const

Modified: trunk/Source/WebCore/dom/Document.cpp (151838 => 151839)


--- trunk/Source/WebCore/dom/Document.cpp	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/Source/WebCore/dom/Document.cpp	2013-06-21 16:03:10 UTC (rev 151839)
@@ -1834,6 +1834,12 @@
     }
 
     InspectorInstrumentation::didRecalculateStyle(cookie);
+
+    // As a result of the style recalculation, the currently hovered element might have been
+    // detached (for example, by setting display:none in the :hover style), schedule another mouseMove event
+    // to check if any other elements ended up under the mouse pointer due to re-layout.
+    if (m_hoveredElement && !m_hoveredElement->renderer() && frame())
+        frame()->eventHandler()->dispatchFakeMouseMoveEventSoon();
 }
 
 void Document::updateStyleIfNeeded()
@@ -5859,11 +5865,13 @@
 
     if (oldHoverObj != newHoverObj) {
         // If the old hovered element is not nil but it's renderer is, it was probably detached as part of the :hover style
-        // (for instance by setting display:none in the :hover pseudo-class). In this case, the old hovered element
+        // (for instance by setting display:none in the :hover pseudo-class). In this case, the old hovered element (and its ancestors)
         // must be updated, to ensure it's normal style is re-applied.
         if (oldHoveredElement && !oldHoverObj) {
-            if (!mustBeInActiveChain || (oldHoveredElement->isElementNode() && oldHoveredElement->inActiveChain()))
-                nodesToRemoveFromChain.append(oldHoveredElement);
+            for (Node* node = oldHoveredElement.get(); node; node = node->parentNode()) {
+                if (!mustBeInActiveChain || (node->isElementNode() && toElement(node)->inActiveChain()))
+                    nodesToRemoveFromChain.append(node);
+            }
         }
 
         // The old hover path only needs to be cleared up to (and not including) the common ancestor;

Modified: trunk/Source/WebCore/dom/Element.cpp (151838 => 151839)


--- trunk/Source/WebCore/dom/Element.cpp	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/Source/WebCore/dom/Element.cpp	2013-06-21 16:03:10 UTC (rev 151839)
@@ -1440,7 +1440,7 @@
     // When a shadow root exists, it does the work of attaching the children.
     if (ElementShadow* shadow = this->shadow()) {
         parentPusher.push();
-        shadow->attach();
+        shadow->attach(context);
     } else if (firstChild())
         parentPusher.push();
 
@@ -1479,8 +1479,8 @@
     }
 
     if (ElementShadow* shadow = this->shadow()) {
-        detachChildrenIfNeeded();
-        shadow->detach();
+        detachChildrenIfNeeded(context);
+        shadow->detach(context);
     }
 
     // Do not remove the element's hovered and active status

Modified: trunk/Source/WebCore/dom/ElementShadow.cpp (151838 => 151839)


--- trunk/Source/WebCore/dom/ElementShadow.cpp	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/Source/WebCore/dom/ElementShadow.cpp	2013-06-21 16:03:10 UTC (rev 151839)
@@ -77,21 +77,27 @@
     m_distributor.invalidateDistribution(shadowHost);
 }
 
-void ElementShadow::attach()
+void ElementShadow::attach(const Node::AttachContext& context)
 {
     ContentDistributor::ensureDistribution(shadowRoot());
 
+    Node::AttachContext childrenContext(context);
+    childrenContext.resolvedStyle = 0;
+
     if (ShadowRoot* root = shadowRoot()) {
         if (!root->attached())
-            root->attach();
+            root->attach(childrenContext);
     }
 }
 
-void ElementShadow::detach()
+void ElementShadow::detach(const Node::AttachContext& context)
 {
+    Node::AttachContext childrenContext(context);
+    childrenContext.resolvedStyle = 0;
+
     if (ShadowRoot* root = shadowRoot()) {
         if (root->attached())
-            root->detach();
+            root->detach(childrenContext);
     }
 }
 

Modified: trunk/Source/WebCore/dom/ElementShadow.h (151838 => 151839)


--- trunk/Source/WebCore/dom/ElementShadow.h	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/Source/WebCore/dom/ElementShadow.h	2013-06-21 16:03:10 UTC (rev 151839)
@@ -56,8 +56,8 @@
 
     ShadowRoot* addShadowRoot(Element* shadowHost, ShadowRoot::ShadowRootType);
 
-    void attach();
-    void detach();
+    void attach(const Node::AttachContext&);
+    void detach(const Node::AttachContext&);
 
     bool childNeedsStyleRecalc() const;
     bool needsStyleRecalc() const;

Modified: trunk/Source/WebCore/dom/Node.h (151838 => 151839)


--- trunk/Source/WebCore/dom/Node.h	2013-06-21 16:01:52 UTC (rev 151838)
+++ trunk/Source/WebCore/dom/Node.h	2013-06-21 16:03:10 UTC (rev 151839)
@@ -838,8 +838,11 @@
 
 inline void Node::lazyReattach(ShouldSetAttached shouldSetAttached)
 {
+    AttachContext context;
+    context.performingReattach = true;
+
     if (attached())
-        detach();
+        detach(context);
     lazyAttach(shouldSetAttached);
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to