Diff
Modified: branches/safari-602-branch/LayoutTests/ChangeLog (203979 => 203980)
--- branches/safari-602-branch/LayoutTests/ChangeLog 2016-08-01 18:48:14 UTC (rev 203979)
+++ branches/safari-602-branch/LayoutTests/ChangeLog 2016-08-01 18:51:56 UTC (rev 203980)
@@ -1,3 +1,17 @@
+2016-08-01 Babak Shafiei <[email protected]>
+
+ Merge r203976. rdar://problem/27580049
+
+ 2016-08-01 Antti Koivisto <[email protected]>
+
+ REGRESSION (r196383): Drop down CSS menus not working on cnet.com, apmex.com
+ https://bugs.webkit.org/show_bug.cgi?id=160390
+
+ Reviewed by Simon Fraser.
+
+ * fast/selectors/hover-invalidation-descendant-dynamic-expected.txt: Added.
+ * fast/selectors/hover-invalidation-descendant-dynamic.html: Added.
+
2016-07-31 Babak Shafiei <[email protected]>
Merge r203931. rdar://problem/27317407
Added: branches/safari-602-branch/LayoutTests/fast/selectors/hover-invalidation-descendant-dynamic-expected.txt (0 => 203980)
--- branches/safari-602-branch/LayoutTests/fast/selectors/hover-invalidation-descendant-dynamic-expected.txt (rev 0)
+++ branches/safari-602-branch/LayoutTests/fast/selectors/hover-invalidation-descendant-dynamic-expected.txt 2016-08-01 18:51:56 UTC (rev 203980)
@@ -0,0 +1,5 @@
+Test that dynamically activated :hover rule affecting descendants works.
+Hover to see a green box below.
+Hover to see a green box below.
+Selector compiler: PASS
+Selector checker: PASS
Added: branches/safari-602-branch/LayoutTests/fast/selectors/hover-invalidation-descendant-dynamic.html (0 => 203980)
--- branches/safari-602-branch/LayoutTests/fast/selectors/hover-invalidation-descendant-dynamic.html (rev 0)
+++ branches/safari-602-branch/LayoutTests/fast/selectors/hover-invalidation-descendant-dynamic.html 2016-08-01 18:51:56 UTC (rev 203980)
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.parent {
+ position: relative;
+ padding: 10px;
+ background-color: silver;
+}
+
+.child {
+ position: absolute;
+ width: 200px;
+ height: 200px;
+ top: 0px;
+ background-color: green;
+ display: none;
+}
+
+#target.enableHover:hover .child {
+ display: block;
+}
+
+/* :matches() is here to disable the selector compiler */
+#target2:matches(:root, :nth-of-type(n), :not(#specificity-trick), :nth-last-of-type(n)).enableHover:hover .child {
+ display: block;
+}
+
+</style>
+<script>
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+}
+
+function runTest(targetSelector) {
+ var target = document.querySelector(targetSelector);
+ var child = target.querySelector('.child');
+
+ target.classList.add('enableHover');
+
+ if (window.eventSender) {
+ var x = target.offsetLeft + target.offsetWidth / 2;
+ var y = target.offsetTop + target.offsetHeight / 2;
+ eventSender.mouseMoveTo(x, y);
+ }
+
+ return child.offsetWidth != 0;
+}
+
+function log(text, pass) {
+ var log = document.querySelector("#log");
+ var line = document.createElement("div");
+ line.innerHTML = text + ": " + (pass ? "PASS" : "FAIL");
+ log.appendChild(line);
+}
+
+function runTests() {
+ var compilerPass = runTest("#target");
+ var checkerPass = runTest("#target2");
+ if (!window.testRunner)
+ return;
+ log("Selector compiler", compilerPass);
+ log("Selector checker", checkerPass);
+
+ testRunner.notifyDone();
+}
+
+</script>
+</head>
+<body _onload_="runTests()">
+<div>
+Test that dynamically activated :hover rule affecting descendants works.
+</div>
+<div id="target" class="parent">
+ Hover to see a green box below.
+ <div class="child"></div>
+</div>
+<div id="target2" class="parent">
+ Hover to see a green box below.
+ <div class="child"></div>
+</div>
+<div id=log></div>
+</body>
+</html>
Modified: branches/safari-602-branch/LayoutTests/platform/ios-simulator/TestExpectations (203979 => 203980)
--- branches/safari-602-branch/LayoutTests/platform/ios-simulator/TestExpectations 2016-08-01 18:48:14 UTC (rev 203979)
+++ branches/safari-602-branch/LayoutTests/platform/ios-simulator/TestExpectations 2016-08-01 18:51:56 UTC (rev 203980)
@@ -267,6 +267,7 @@
fast/css/pseudo-active-style-sharing-6.html [ Skip ]
fast/css/pseudo-active-with-programmatic-focus.html [ Skip ]
http/tests/security/history-username-password.html [ Skip ]
+fast/selectors/hover-invalidation-descendant-dynamic.html [ Skip ]
webkit.org/b/148695 fast/shadow-dom [ Pass ]
Modified: branches/safari-602-branch/Source/WebCore/ChangeLog (203979 => 203980)
--- branches/safari-602-branch/Source/WebCore/ChangeLog 2016-08-01 18:48:14 UTC (rev 203979)
+++ branches/safari-602-branch/Source/WebCore/ChangeLog 2016-08-01 18:51:56 UTC (rev 203980)
@@ -1,3 +1,43 @@
+2016-08-01 Babak Shafiei <[email protected]>
+
+ Merge r203976. rdar://problem/27580049
+
+ 2016-08-01 Antti Koivisto <[email protected]>
+
+ REGRESSION (r196383): Drop down CSS menus not working on cnet.com, apmex.com
+ https://bugs.webkit.org/show_bug.cgi?id=160390
+
+ Reviewed by Simon Fraser.
+
+ The case here is that we have a rule like
+
+ .enableHover:hover .child { ... }
+
+ and the "enableHover" class is added dynamically. The class change invalidation optimization code would figure out
+ that nothing needs to be invalidated as the class change doesn't make the rule match (since :hover doesn't match).
+
+ However for event driven hover to actually work the hover element needs to have its childrenAffectedByHover bit set.
+ This bits is set when the selector match is attempted, whether it actually matches or not. Since we optimized away
+ the style invalidation we never set the bit either.
+
+ Fix by treating :hover as always matching (==ignored) when collecting rules for invalidation optimization purposes.
+ Dynamic pseudo elements are already treated this way for similar reasons.
+
+ Test: fast/selectors/hover-invalidation-descendant-dynamic.html
+
+ * css/SelectorChecker.cpp:
+ (WebCore::SelectorChecker::checkOne):
+
+ Match always in CollectingRulesIgnoringVirtualPseudoElements mode (now slightly misnamed).
+
+ This mode is used for optimization purposes in StyleInvalidationAnalysis (which we care about here) and
+ StyleSharingResolver. The change is fine for both.
+
+ * cssjit/SelectorCompiler.cpp:
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsHovered):
+
+ Same change for the slow path selector checker.
+
2016-07-31 Babak Shafiei <[email protected]>
Merge r203931. rdar://problem/27317407
Modified: branches/safari-602-branch/Source/WebCore/css/SelectorChecker.cpp (203979 => 203980)
--- branches/safari-602-branch/Source/WebCore/css/SelectorChecker.cpp 2016-08-01 18:48:14 UTC (rev 203979)
+++ branches/safari-602-branch/Source/WebCore/css/SelectorChecker.cpp 2016-08-01 18:51:56 UTC (rev 203980)
@@ -951,6 +951,10 @@
if (m_strictParsing || element.isLink() || canMatchHoverOrActiveInQuirksMode(context)) {
addStyleRelation(checkingContext, element, Style::Relation::AffectedByHover);
+ // See the comment in generateElementIsHovered() in SelectorCompiler.
+ if (checkingContext.resolvingMode == SelectorChecker::Mode::CollectingRulesIgnoringVirtualPseudoElements && !context.isMatchElement)
+ return true;
+
if (element.hovered() || InspectorInstrumentation::forcePseudoState(element, CSSSelector::PseudoClassHover))
return true;
}
Modified: branches/safari-602-branch/Source/WebCore/cssjit/SelectorCompiler.cpp (203979 => 203980)
--- branches/safari-602-branch/Source/WebCore/cssjit/SelectorCompiler.cpp 2016-08-01 18:48:14 UTC (rev 203979)
+++ branches/safari-602-branch/Source/WebCore/cssjit/SelectorCompiler.cpp 2016-08-01 18:51:56 UTC (rev 203980)
@@ -3214,10 +3214,22 @@
generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectedByHover);
+ Assembler::JumpList successCases;
+ if (m_selectorContext != SelectorContext::QuerySelector && fragment.relationToRightFragment != FragmentRelation::Rightmost) {
+ // :hover always matches when not in rightmost position when collecting rules for descendant style invalidation optimization.
+ // Resolving style for a matching descendant will set parent childrenAffectedByHover bit even when the element is not currently hovered.
+ // This bit has to be set for the event based :hover invalidation to work.
+ // FIXME: We should just collect style relation bits and apply them as needed when computing style invalidation optimization.
+ LocalRegister checkingContext(m_registerAllocator);
+ successCases.append(branchOnResolvingMode(Assembler::Equal, SelectorChecker::Mode::CollectingRulesIgnoringVirtualPseudoElements, checkingContext));
+ }
+
FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls);
functionCall.setFunctionAddress(elementIsHovered);
functionCall.setOneArgument(elementAddressRegister);
failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
+
+ successCases.link(&m_assembler);
}
void SelectorCodeGenerator::generateElementIsInLanguage(Assembler::JumpList& failureCases, const SelectorFragment& fragment)