Changeset 208390 in webkit


Ignore:
Timestamp:
Nov 4, 2016 11:32:45 AM (8 years ago)
Author:
Antti Koivisto
Message:

slotted() pseudo does not work with ID selector
https://bugs.webkit.org/show_bug.cgi?id=160538
<rdar://problem/28534529>

Reviewed by Andreas Kling.

Source/WebCore:

When we saw an id selector while addin rules we immediately threw it into the m_idRules
optimization bucket and bailed out. However selectors containing ::slotted must always end
up in m_slottedPseudoElementRules list no matter what else is there.

Fix by treating id like other selectors and only choosing the bucket after analysing all
the selector components.

Test: fast/shadow-dom/css-scoping-slot-with-id.html

  • css/RuleSet.cpp:

(WebCore::RuleSet::addRule): Also made this use switch instead of a series of ifs.

LayoutTests:

  • fast/shadow-dom/css-scoping-slot-with-id-expected.html: Added.
  • fast/shadow-dom/css-scoping-slot-with-id.html: Added.
Location:
trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r208386 r208390  
     12016-11-04  Antti Koivisto  <antti@apple.com>
     2
     3        slotted() pseudo does not work with ID selector
     4        https://bugs.webkit.org/show_bug.cgi?id=160538
     5        <rdar://problem/28534529>
     6
     7        Reviewed by Andreas Kling.
     8
     9        * fast/shadow-dom/css-scoping-slot-with-id-expected.html: Added.
     10        * fast/shadow-dom/css-scoping-slot-with-id.html: Added.
     11
    1122016-11-04  Brady Eidson  <beidson@apple.com>
    213
  • trunk/Source/WebCore/ChangeLog

    r208389 r208390  
     12016-11-04  Antti Koivisto  <antti@apple.com>
     2
     3        slotted() pseudo does not work with ID selector
     4        https://bugs.webkit.org/show_bug.cgi?id=160538
     5        <rdar://problem/28534529>
     6
     7        Reviewed by Andreas Kling.
     8
     9        When we saw an id selector while addin rules we immediately threw it into the m_idRules
     10        optimization bucket and bailed out. However selectors containing ::slotted must always end
     11        up in m_slottedPseudoElementRules list no matter what else is there.
     12
     13        Fix by treating id like other selectors and only choosing the bucket after analysing all
     14        the selector components.
     15
     16        Test: fast/shadow-dom/css-scoping-slot-with-id.html
     17
     18        * css/RuleSet.cpp:
     19        (WebCore::RuleSet::addRule): Also made this use switch instead of a series of ifs.
     20
    1212016-11-04  Brady Eidson  <beidson@apple.com>
    222
  • trunk/Source/WebCore/css/RuleSet.cpp

    r207536 r208390  
    201201
    202202    unsigned classBucketSize = 0;
     203    const CSSSelector* idSelector = nullptr;
    203204    const CSSSelector* tagSelector = nullptr;
    204205    const CSSSelector* classSelector = nullptr;
    205206    const CSSSelector* linkSelector = nullptr;
    206207    const CSSSelector* focusSelector = nullptr;
     208    const CSSSelector* customPseudoElementSelector = nullptr;
     209    const CSSSelector* slottedPseudoElementSelector = nullptr;
     210    const CSSSelector* cuePseudoElementSelector = nullptr;
    207211    const CSSSelector* selector = ruleData.selector();
    208212    do {
    209         if (selector->match() == CSSSelector::Id) {
    210             addToRuleSet(selector->value().impl(), m_idRules, ruleData);
    211             return;
    212         }
    213 
    214 #if ENABLE(VIDEO_TRACK)
    215         if (selector->match() == CSSSelector::PseudoElement && selector->pseudoElementType() == CSSSelector::PseudoElementCue) {
    216             m_cuePseudoRules.append(ruleData);
    217             return;
    218         }
    219 #endif
    220 
    221         if (selector->isCustomPseudoElement()) {
    222             // FIXME: Custom pseudo elements are handled by the shadow tree's selector filter. It doesn't know about the main DOM.
    223             ruleData.disableSelectorFiltering();
    224             addToRuleSet(selector->value().impl(), m_shadowPseudoElementRules, ruleData);
    225             return;
    226         }
    227 
    228         if (selector->match() == CSSSelector::Class) {
    229             AtomicStringImpl* className = selector->value().impl();
     213        switch (selector->match()) {
     214        case CSSSelector::Id:
     215            idSelector = selector;
     216            break;
     217        case CSSSelector::Class: {
     218            auto* className = selector->value().impl();
    230219            if (!classSelector) {
    231220                classSelector = selector;
     
    238227                }
    239228            }
    240         }
    241 
    242         if (selector->match() == CSSSelector::Tag && selector->tagQName().localName() != starAtom)
    243             tagSelector = selector;
    244 
    245         if (SelectorChecker::isCommonPseudoClassSelector(selector)) {
     229            break;
     230        }
     231        case CSSSelector::Tag:
     232            if (selector->tagQName().localName() != starAtom)
     233                tagSelector = selector;
     234            break;
     235        case CSSSelector::PseudoElement:
     236            switch (selector->pseudoElementType()) {
     237            case CSSSelector::PseudoElementUserAgentCustom:
     238            case CSSSelector::PseudoElementWebKitCustom:
     239            case CSSSelector::PseudoElementWebKitCustomLegacyPrefixed:
     240                customPseudoElementSelector = selector;
     241                break;
     242            case CSSSelector::PseudoElementSlotted:
     243                slottedPseudoElementSelector = selector;
     244                break;
     245#if ENABLE(VIDEO_TRACK)
     246            case CSSSelector::PseudoElementCue:
     247                cuePseudoElementSelector = selector;
     248                break;
     249#endif
     250            default:
     251                break;
     252            }
     253            break;
     254        case CSSSelector::PseudoClass:
    246255            switch (selector->pseudoClassType()) {
    247256            case CSSSelector::PseudoClassLink:
     
    254263                focusSelector = selector;
    255264                break;
     265            case CSSSelector::PseudoClassHost:
     266                m_hostPseudoClassRules.append(ruleData);
     267                return;
    256268            default:
    257                 ASSERT_NOT_REACHED();
     269                break;
    258270            }
    259         }
    260 
    261         if (selector->match() == CSSSelector::PseudoClass && selector->pseudoClassType() == CSSSelector::PseudoClassHost) {
    262             m_hostPseudoClassRules.append(ruleData);
    263             return;
    264         }
    265         if (selector->match() == CSSSelector::PseudoElement && selector->pseudoElementType() == CSSSelector::PseudoElementSlotted) {
    266             // ::slotted pseudo elements work accross shadow boundary making filtering difficult.
    267             ruleData.disableSelectorFiltering();
    268             m_slottedPseudoElementRules.append(ruleData);
    269             return;
     271            break;
     272        case CSSSelector::Unknown:
     273        case CSSSelector::Exact:
     274        case CSSSelector::Set:
     275        case CSSSelector::List:
     276        case CSSSelector::Hyphen:
     277        case CSSSelector::Contain:
     278        case CSSSelector::Begin:
     279        case CSSSelector::End:
     280        case CSSSelector::PagePseudoClass:
     281            break;
    270282        }
    271283        if (selector->relation() != CSSSelector::Subselector)
     
    273285        selector = selector->tagHistory();
    274286    } while (selector);
     287
     288    if (cuePseudoElementSelector) {
     289        m_cuePseudoRules.append(ruleData);
     290        return;
     291    }
     292
     293    if (slottedPseudoElementSelector) {
     294        // ::slotted pseudo elements work accross shadow boundary making filtering difficult.
     295        ruleData.disableSelectorFiltering();
     296        m_slottedPseudoElementRules.append(ruleData);
     297        return;
     298    }
     299
     300    if (customPseudoElementSelector) {
     301        // FIXME: Custom pseudo elements are handled by the shadow tree's selector filter. It doesn't know about the main DOM.
     302        ruleData.disableSelectorFiltering();
     303        addToRuleSet(customPseudoElementSelector->value().impl(), m_shadowPseudoElementRules, ruleData);
     304        return;
     305    }
     306
     307    if (idSelector) {
     308        addToRuleSet(idSelector->value().impl(), m_idRules, ruleData);
     309        return;
     310    }
    275311
    276312    if (classSelector) {
Note: See TracChangeset for help on using the changeset viewer.