Changeset 203976 in webkit


Ignore:
Timestamp:
Aug 1, 2016 11:00:48 AM (8 years ago)
Author:
Antti Koivisto
Message:

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.

Source/WebCore:

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.

LayoutTests:

  • fast/selectors/hover-invalidation-descendant-dynamic-expected.txt: Added.
  • fast/selectors/hover-invalidation-descendant-dynamic.html: Added.
Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r203961 r203976  
     12016-08-01  Antti Koivisto  <antti@apple.com>
     2
     3        REGRESSION (r196383): Drop down CSS menus not working on cnet.com, apmex.com
     4        https://bugs.webkit.org/show_bug.cgi?id=160390
     5
     6        Reviewed by Simon Fraser.
     7
     8        * fast/selectors/hover-invalidation-descendant-dynamic-expected.txt: Added.
     9        * fast/selectors/hover-invalidation-descendant-dynamic.html: Added.
     10
    1112016-07-31  Youenn Fablet  <youenn@apple.com>
    212
  • trunk/LayoutTests/platform/ios-simulator/TestExpectations

    r203927 r203976  
    289289fast/css/pseudo-active-with-programmatic-focus.html [ Skip ]
    290290http/tests/security/history-username-password.html [ Skip ]
     291fast/selectors/hover-invalidation-descendant-dynamic.html [ Skip ]
    291292
    292293webkit.org/b/148695 fast/shadow-dom [ Pass ]
  • trunk/Source/WebCore/ChangeLog

    r203974 r203976  
     12016-08-01  Antti Koivisto  <antti@apple.com>
     2
     3        REGRESSION (r196383): Drop down CSS menus not working on cnet.com, apmex.com
     4        https://bugs.webkit.org/show_bug.cgi?id=160390
     5
     6        Reviewed by Simon Fraser.
     7
     8        The case here is that we have a rule like
     9
     10            .enableHover:hover .child { ... }
     11
     12        and the "enableHover" class is added dynamically. The class change invalidation optimization code would figure out
     13        that nothing needs to be invalidated as the class change doesn't make the rule match (since :hover doesn't match).
     14
     15        However for event driven hover to actually work the hover element needs to have its childrenAffectedByHover bit set.
     16        This bits is set when the selector match is attempted, whether it actually matches or not. Since we optimized away
     17        the style invalidation we never set the bit either.
     18
     19        Fix by treating :hover as always matching (==ignored) when collecting rules for invalidation optimization purposes.
     20        Dynamic pseudo elements are already treated this way for similar reasons.
     21
     22        Test: fast/selectors/hover-invalidation-descendant-dynamic.html
     23
     24        * css/SelectorChecker.cpp:
     25        (WebCore::SelectorChecker::checkOne):
     26
     27            Match always in CollectingRulesIgnoringVirtualPseudoElements mode (now slightly misnamed).
     28
     29            This mode is used for optimization purposes in StyleInvalidationAnalysis (which we care about here) and
     30            StyleSharingResolver. The change is fine for both.
     31
     32        * cssjit/SelectorCompiler.cpp:
     33        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsHovered):
     34
     35            Same change for the slow path selector checker.
     36
    1372016-08-01  Darin Adler  <darin@apple.com>
    238
  • trunk/Source/WebCore/css/SelectorChecker.cpp

    r202358 r203976  
    951951            if (m_strictParsing || element.isLink() || canMatchHoverOrActiveInQuirksMode(context)) {
    952952                addStyleRelation(checkingContext, element, Style::Relation::AffectedByHover);
     953
     954                // See the comment in generateElementIsHovered() in SelectorCompiler.
     955                if (checkingContext.resolvingMode == SelectorChecker::Mode::CollectingRulesIgnoringVirtualPseudoElements && !context.isMatchElement)
     956                    return true;
    953957
    954958                if (element.hovered() || InspectorInstrumentation::forcePseudoState(element, CSSSelector::PseudoClassHover))
  • trunk/Source/WebCore/cssjit/SelectorCompiler.cpp

    r203211 r203976  
    32153215    generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectedByHover);
    32163216
     3217    Assembler::JumpList successCases;
     3218    if (m_selectorContext != SelectorContext::QuerySelector && fragment.relationToRightFragment != FragmentRelation::Rightmost) {
     3219        // :hover always matches when not in rightmost position when collecting rules for descendant style invalidation optimization.
     3220        // Resolving style for a matching descendant will set parent childrenAffectedByHover bit even when the element is not currently hovered.
     3221        // This bit has to be set for the event based :hover invalidation to work.
     3222        // FIXME: We should just collect style relation bits and apply them as needed when computing style invalidation optimization.
     3223        LocalRegister checkingContext(m_registerAllocator);
     3224        successCases.append(branchOnResolvingMode(Assembler::Equal, SelectorChecker::Mode::CollectingRulesIgnoringVirtualPseudoElements, checkingContext));
     3225    }
     3226
    32173227    FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls);
    32183228    functionCall.setFunctionAddress(elementIsHovered);
    32193229    functionCall.setOneArgument(elementAddressRegister);
    32203230    failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
     3231
     3232    successCases.link(&m_assembler);
    32213233}
    32223234
Note: See TracChangeset for help on using the changeset viewer.