| Differences between
and this patch
- Source/WebCore/css/CSSGrammar.y.in +11 lines
Lines 365-370 static bool selectorListDoesNotMatchAnyP Source/WebCore/css/CSSGrammar.y.in_sec1
365
365
366
#endif
366
#endif
367
367
368
#if ENABLE_SHADOW_DOM
369
370
%token <string> SLOTTEDFUNCTION
371
372
#endif
373
368
%%
374
%%
369
375
370
stylesheet:
376
stylesheet:
Lines 1357-1362 pseudo: Source/WebCore/css/CSSGrammar.y.in_sec2
1357
        $$ = CSSParserSelector::parsePseudoElementCueFunctionSelector($3, $5);
1363
        $$ = CSSParserSelector::parsePseudoElementCueFunctionSelector($3, $5);
1358
    }
1364
    }
1359
#endif
1365
#endif
1366
#if ENABLE_SHADOW_DOM
1367
    | ':' ':' SLOTTEDFUNCTION maybe_space simple_selector_list maybe_space ')' {
1368
        $$ = CSSParserSelector::parsePseudoElementSlottedFunctionSelector($3, $5);
1369
    }
1370
#endif
1360
    // use by :-webkit-any.
1371
    // use by :-webkit-any.
1361
    // FIXME: should we support generic selectors here or just simple_selectors?
1372
    // FIXME: should we support generic selectors here or just simple_selectors?
1362
    // Use simple_selector_list for now to match -moz-any.
1373
    // Use simple_selector_list for now to match -moz-any.
- Source/WebCore/css/CSSParser.cpp -1 / +6 lines
Lines 11894-11901 inline bool CSSParser::detectFunctionTyp Source/WebCore/css/CSSParser.cpp_sec1
11894
            m_token = MATCHESFUNCTION;
11894
            m_token = MATCHESFUNCTION;
11895
            return true;
11895
            return true;
11896
        }
11896
        }
11897
#if ENABLE(SHADOW_DOM)
11898
        if (isEqualToCSSIdentifier(name, "slotted")) {
11899
            m_token = SLOTTEDFUNCTION;
11900
            return true;
11901
        }
11902
#endif
11897
        return false;
11903
        return false;
11898
11899
    case 9:
11904
    case 9:
11900
        if (isEqualToCSSIdentifier(name, "nth-child")) {
11905
        if (isEqualToCSSIdentifier(name, "nth-child")) {
11901
            m_token = NTHCHILDFUNCTIONS;
11906
            m_token = NTHCHILDFUNCTIONS;
- Source/WebCore/css/CSSParserValues.cpp +18 lines
Lines 231-236 CSSParserSelector* CSSParserSelector::pa Source/WebCore/css/CSSParserValues.cpp_sec1
231
}
231
}
232
#endif
232
#endif
233
233
234
#if ENABLE(SHADOW_DOM)
235
CSSParserSelector* CSSParserSelector::parsePseudoElementSlottedFunctionSelector(const CSSParserString& functionIdentifier, Vector<std::unique_ptr<CSSParserSelector>>* parsedSelectorVector)
236
{
237
    ASSERT_UNUSED(functionIdentifier, String(functionIdentifier) == "slotted(");
238
239
    std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>> selectorVector(parsedSelectorVector);
240
241
    if (!selectorVector)
242
        return nullptr;
243
244
    auto selector = std::make_unique<CSSParserSelector>();
245
    selector->m_selector->setMatch(CSSSelector::PseudoElement);
246
    selector->m_selector->setPseudoElementType(CSSSelector::PseudoElementSlotted);
247
    selector->adoptSelectorVector(*selectorVector);
248
    return selector.release();
249
}
250
#endif
251
234
CSSParserSelector* CSSParserSelector::parsePseudoClassAndCompatibilityElementSelector(CSSParserString& pseudoTypeString)
252
CSSParserSelector* CSSParserSelector::parsePseudoClassAndCompatibilityElementSelector(CSSParserString& pseudoTypeString)
235
{
253
{
236
    if (pseudoTypeString.length() && pseudoTypeString[pseudoTypeString.length() - 1] == '(')
254
    if (pseudoTypeString.length() && pseudoTypeString[pseudoTypeString.length() - 1] == '(')
- Source/WebCore/css/CSSParserValues.h -1 / +4 lines
Lines 203-209 class CSSParserSelector { Source/WebCore/css/CSSParserValues.h_sec1
203
public:
203
public:
204
    static CSSParserSelector* parsePagePseudoSelector(const CSSParserString& pseudoTypeString);
204
    static CSSParserSelector* parsePagePseudoSelector(const CSSParserString& pseudoTypeString);
205
    static CSSParserSelector* parsePseudoElementSelector(CSSParserString& pseudoTypeString);
205
    static CSSParserSelector* parsePseudoElementSelector(CSSParserString& pseudoTypeString);
206
    static CSSParserSelector* parsePseudoElementCueFunctionSelector(const CSSParserString& functionIdentifier, Vector<std::unique_ptr<CSSParserSelector>>* selectorVector);
206
    static CSSParserSelector* parsePseudoElementCueFunctionSelector(const CSSParserString& functionIdentifier, Vector<std::unique_ptr<CSSParserSelector>>*);
207
#if ENABLE(SHADOW_DOM)
208
    static CSSParserSelector* parsePseudoElementSlottedFunctionSelector(const CSSParserString& functionIdentifier, Vector<std::unique_ptr<CSSParserSelector>>*);
209
#endif
207
    static CSSParserSelector* parsePseudoClassAndCompatibilityElementSelector(CSSParserString& pseudoTypeString);
210
    static CSSParserSelector* parsePseudoClassAndCompatibilityElementSelector(CSSParserString& pseudoTypeString);
208
211
209
    CSSParserSelector();
212
    CSSParserSelector();
- Source/WebCore/css/CSSSelector.cpp +3 lines
Lines 299-304 PseudoId CSSSelector::pseudoId(PseudoEle Source/WebCore/css/CSSSelector.cpp_sec1
299
#if ENABLE(VIDEO_TRACK)
299
#if ENABLE(VIDEO_TRACK)
300
    case PseudoElementCue:
300
    case PseudoElementCue:
301
#endif
301
#endif
302
#if ENABLE(SHADOW_DOM)
303
    case PseudoElementSlotted:
304
#endif
302
    case PseudoElementUnknown:
305
    case PseudoElementUnknown:
303
    case PseudoElementUserAgentCustom:
306
    case PseudoElementUserAgentCustom:
304
    case PseudoElementWebKitCustom:
307
    case PseudoElementWebKitCustom:
- Source/WebCore/css/CSSSelector.h +3 lines
Lines 181-186 namespace WebCore { Source/WebCore/css/CSSSelector.h_sec1
181
            PseudoElementScrollbarTrack,
181
            PseudoElementScrollbarTrack,
182
            PseudoElementScrollbarTrackPiece,
182
            PseudoElementScrollbarTrackPiece,
183
            PseudoElementSelection,
183
            PseudoElementSelection,
184
#if ENABLE(SHADOW_DOM)
185
            PseudoElementSlotted,
186
#endif
184
            PseudoElementUserAgentCustom,
187
            PseudoElementUserAgentCustom,
185
            PseudoElementWebKitCustom,
188
            PseudoElementWebKitCustom,
186
        };
189
        };
- Source/WebCore/css/ElementRuleCollector.cpp -1 / +81 lines
Lines 36-41 Source/WebCore/css/ElementRuleCollector.cpp_sec1
36
#include "CSSSelectorList.h"
36
#include "CSSSelectorList.h"
37
#include "CSSValueKeywords.h"
37
#include "CSSValueKeywords.h"
38
#include "HTMLElement.h"
38
#include "HTMLElement.h"
39
#include "HTMLSlotElement.h"
39
#include "InspectorInstrumentation.h"
40
#include "InspectorInstrumentation.h"
40
#include "NodeRenderStyle.h"
41
#include "NodeRenderStyle.h"
41
#include "RenderRegion.h"
42
#include "RenderRegion.h"
Lines 206-211 void ElementRuleCollector::matchAuthorRu Source/WebCore/css/ElementRuleCollector.cpp_sec2
206
#if ENABLE(SHADOW_DOM)
207
#if ENABLE(SHADOW_DOM)
207
    if (m_element.shadowRoot())
208
    if (m_element.shadowRoot())
208
        matchHostPseudoClassRules(includeEmptyRules);
209
        matchHostPseudoClassRules(includeEmptyRules);
210
211
    if (m_element.parentNode()->shadowRoot())
212
        matchSlottedPseudoElementRules(includeEmptyRules);
209
#endif
213
#endif
210
214
211
    clearMatchedRules();
215
    clearMatchedRules();
Lines 241-246 void ElementRuleCollector::matchHostPseu Source/WebCore/css/ElementRuleCollector.cpp_sec3
241
    // FIXME: Match the spec when it is finalized.
245
    // FIXME: Match the spec when it is finalized.
242
    sortAndTransferMatchedRules();
246
    sortAndTransferMatchedRules();
243
}
247
}
248
249
void ElementRuleCollector::matchSlottedPseudoElementRules(bool includeEmptyRules)
250
{
251
    auto* hostShadowRoot = m_element.parentNode()->shadowRoot();
252
    ASSERT(hostShadowRoot);
253
    auto* slot = hostShadowRoot->findAssignedSlot(m_element);
254
    if (!slot)
255
        return;
256
    auto* shadowAuthorStyle = hostShadowRoot->styleResolver().ruleSets().authorStyle();
257
    if (!shadowAuthorStyle)
258
        return;
259
    // Find out if there are any ::slotted rules in the shadow tree matching the current slot.
260
    // FIXME: This is really part of the slot style and could be cached when resolving it.
261
    ElementRuleCollector collector(*slot, *shadowAuthorStyle, nullptr);
262
    auto slottedPseudoElementRules = collector.collectSlottedPseudoElementRulesForSlot(includeEmptyRules);
263
    if (slottedPseudoElementRules.isEmpty())
264
        return;
265
266
    TemporaryChange<bool> change(m_isMatchindSlottedPseudoElement, true);
267
268
    clearMatchedRules();
269
    m_result.ranges.lastAuthorRule = m_result.matchedProperties().size() - 1;
270
    auto ruleRange = m_result.ranges.authorRuleRange();
271
272
    // Match in the current scope.
273
    MatchRequest matchRequest(nullptr, includeEmptyRules);
274
    collectMatchingRulesForList(&slottedPseudoElementRules, matchRequest, ruleRange);
275
276
    // FIXME: What is the correct order?
277
    sortAndTransferMatchedRules();
278
}
279
280
RuleSet::RuleDataVector ElementRuleCollector::collectSlottedPseudoElementRulesForSlot(bool includeEmptyRules)
281
{
282
    ASSERT(is<HTMLSlotElement>(m_element));
283
284
    clearMatchedRules();
285
286
    m_mode = SelectorChecker::Mode::CollectingRules;
287
288
    // Match global author rules.
289
    MatchRequest matchRequest(&m_authorStyle, includeEmptyRules);
290
    StyleResolver::RuleRange ruleRange = m_result.ranges.authorRuleRange();
291
    collectMatchingRulesForList(&m_authorStyle.slottedPseudoElementRules(), matchRequest, ruleRange);
292
293
    if (m_matchedRules.isEmpty())
294
        return { };
295
296
    RuleSet::RuleDataVector ruleDataVector;
297
    for (auto& matchedRule : m_matchedRules)
298
        ruleDataVector.append(*matchedRule.ruleData);
299
    return ruleDataVector;
300
}
244
#endif
301
#endif
245
302
246
void ElementRuleCollector::matchUserRules(bool includeEmptyRules)
303
void ElementRuleCollector::matchUserRules(bool includeEmptyRules)
Lines 284-289 void ElementRuleCollector::matchUARules( Source/WebCore/css/ElementRuleCollector.cpp_sec4
284
    sortAndTransferMatchedRules();
341
    sortAndTransferMatchedRules();
285
}
342
}
286
343
344
#if ENABLE(SHADOW_DOM)
345
static const CSSSelector* findSlottedPseudoElementSelector(const CSSSelector* selector)
346
{
347
    for (; selector; selector = selector->tagHistory()) {
348
        if (selector->match() == CSSSelector::PseudoElement && selector->pseudoElementType() == CSSSelector::PseudoElementSlotted) {
349
            if (auto* list = selector->selectorList())
350
                return list->first();
351
            break;
352
        }
353
    };
354
    return nullptr;
355
}
356
#endif
357
287
inline bool ElementRuleCollector::ruleMatches(const RuleData& ruleData, unsigned& specificity)
358
inline bool ElementRuleCollector::ruleMatches(const RuleData& ruleData, unsigned& specificity)
288
{
359
{
289
    // We know a sufficiently simple single part selector matches simply because we found it from the rule hash when filtering the RuleSet.
360
    // We know a sufficiently simple single part selector matches simply because we found it from the rule hash when filtering the RuleSet.
Lines 356-364 inline bool ElementRuleCollector::ruleMa Source/WebCore/css/ElementRuleCollector.cpp_sec5
356
    } else
427
    } else
357
#endif // ENABLE(CSS_SELECTOR_JIT)
428
#endif // ENABLE(CSS_SELECTOR_JIT)
358
    {
429
    {
430
        auto* selector = ruleData.selector();
431
#if ENABLE(SHADOW_DOM)
432
        if (m_isMatchindSlottedPseudoElement) {
433
            selector = findSlottedPseudoElementSelector(ruleData.selector());
434
            if (!selector)
435
                return false;
436
        }
437
438
#endif
359
        // Slow path.
439
        // Slow path.
360
        SelectorChecker selectorChecker(m_element.document());
440
        SelectorChecker selectorChecker(m_element.document());
361
        selectorMatches = selectorChecker.match(*ruleData.selector(), m_element, context, specificity);
441
        selectorMatches = selectorChecker.match(*selector, m_element, context, specificity);
362
    }
442
    }
363
443
364
    commitStyleRelations(context.styleRelations);
444
    commitStyleRelations(context.styleRelations);
- Source/WebCore/css/ElementRuleCollector.h +5 lines
Lines 73-78 private: Source/WebCore/css/ElementRuleCollector.h_sec1
73
    void matchUARules(RuleSet*);
73
    void matchUARules(RuleSet*);
74
#if ENABLE(SHADOW_DOM)
74
#if ENABLE(SHADOW_DOM)
75
    void matchHostPseudoClassRules(bool includeEmptyRules);
75
    void matchHostPseudoClassRules(bool includeEmptyRules);
76
    void matchSlottedPseudoElementRules(bool includeEmptyRules);
77
    RuleSet::RuleDataVector collectSlottedPseudoElementRulesForSlot(bool includeEmptyRules);
76
#endif
78
#endif
77
79
78
    void collectMatchingRules(const MatchRequest&, StyleResolver::RuleRange&);
80
    void collectMatchingRules(const MatchRequest&, StyleResolver::RuleRange&);
Lines 98-103 private: Source/WebCore/css/ElementRuleCollector.h_sec2
98
    PseudoStyleRequest m_pseudoStyleRequest { NOPSEUDO };
100
    PseudoStyleRequest m_pseudoStyleRequest { NOPSEUDO };
99
    bool m_sameOriginOnly { false };
101
    bool m_sameOriginOnly { false };
100
    SelectorChecker::Mode m_mode { SelectorChecker::Mode::ResolvingStyle };
102
    SelectorChecker::Mode m_mode { SelectorChecker::Mode::ResolvingStyle };
103
#if ENABLE(SHADOW_DOM)
104
    bool m_isMatchindSlottedPseudoElement { false };
105
#endif
101
106
102
    Vector<MatchedRule, 64> m_matchedRules;
107
    Vector<MatchedRule, 64> m_matchedRules;
103
108
- Source/WebCore/css/RuleSet.cpp +9 lines
Lines 266-271 void RuleSet::addRule(StyleRule* rule, u Source/WebCore/css/RuleSet.cpp_sec1
266
            m_hostPseudoClassRules.append(ruleData);
266
            m_hostPseudoClassRules.append(ruleData);
267
            return;
267
            return;
268
        }
268
        }
269
        if (selector->match() == CSSSelector::PseudoElement && selector->pseudoElementType() == CSSSelector::PseudoElementSlotted) {
270
            ruleData.disableSelectorFiltering();
271
            m_slottedPseudoElementRules.append(ruleData);
272
            return;
273
        }
269
#endif
274
#endif
270
        if (selector->relation() != CSSSelector::SubSelector)
275
        if (selector->relation() != CSSSelector::SubSelector)
271
            break;
276
            break;
Lines 422-427 void RuleSet::shrinkToFit() Source/WebCore/css/RuleSet.cpp_sec2
422
#if ENABLE(VIDEO_TRACK)
427
#if ENABLE(VIDEO_TRACK)
423
    m_cuePseudoRules.shrinkToFit();
428
    m_cuePseudoRules.shrinkToFit();
424
#endif
429
#endif
430
#if ENABLE(SHADOW_DOM)
431
    m_hostPseudoClassRules.shrinkToFit();
432
    m_slottedPseudoElementRules.shrinkToFit();
433
#endif
425
    m_focusPseudoClassRules.shrinkToFit();
434
    m_focusPseudoClassRules.shrinkToFit();
426
    m_universalRules.shrinkToFit();
435
    m_universalRules.shrinkToFit();
427
    m_pageRules.shrinkToFit();
436
    m_pageRules.shrinkToFit();
- Source/WebCore/css/RuleSet.h +2 lines
Lines 184-189 public: Source/WebCore/css/RuleSet.h_sec1
184
#endif
184
#endif
185
#if ENABLE(SHADOW_DOM)
185
#if ENABLE(SHADOW_DOM)
186
    const RuleDataVector& hostPseudoClassRules() const { return m_hostPseudoClassRules; }
186
    const RuleDataVector& hostPseudoClassRules() const { return m_hostPseudoClassRules; }
187
    const RuleDataVector& slottedPseudoElementRules() const { return m_slottedPseudoElementRules; }
187
#endif
188
#endif
188
    const RuleDataVector* focusPseudoClassRules() const { return &m_focusPseudoClassRules; }
189
    const RuleDataVector* focusPseudoClassRules() const { return &m_focusPseudoClassRules; }
189
    const RuleDataVector* universalRules() const { return &m_universalRules; }
190
    const RuleDataVector* universalRules() const { return &m_universalRules; }
Lines 210-215 private: Source/WebCore/css/RuleSet.h_sec2
210
#endif
211
#endif
211
#if ENABLE(SHADOW_DOM)
212
#if ENABLE(SHADOW_DOM)
212
    RuleDataVector m_hostPseudoClassRules;
213
    RuleDataVector m_hostPseudoClassRules;
214
    RuleDataVector m_slottedPseudoElementRules;
213
#endif
215
#endif
214
    RuleDataVector m_focusPseudoClassRules;
216
    RuleDataVector m_focusPseudoClassRules;
215
    RuleDataVector m_universalRules;
217
    RuleDataVector m_universalRules;
- Source/WebCore/css/SelectorChecker.cpp -1 / +8 lines
Lines 44-49 Source/WebCore/css/SelectorChecker.cpp_sec1
44
#include "HTMLOptionElement.h"
44
#include "HTMLOptionElement.h"
45
#include "HTMLParserIdioms.h"
45
#include "HTMLParserIdioms.h"
46
#include "HTMLProgressElement.h"
46
#include "HTMLProgressElement.h"
47
#include "HTMLSlotElement.h"
47
#include "HTMLStyleElement.h"
48
#include "HTMLStyleElement.h"
48
#include "InspectorInstrumentation.h"
49
#include "InspectorInstrumentation.h"
49
#include "Page.h"
50
#include "Page.h"
Lines 1038-1044 bool SelectorChecker::checkOne(CheckingC Source/WebCore/css/SelectorChecker.cpp_sec2
1038
        return false;
1039
        return false;
1039
    }
1040
    }
1040
#endif
1041
#endif
1041
    // ### add the rest of the checks...
1042
#if ENABLE(SHADOW_DOM)
1043
    if (selector.match() == CSSSelector::PseudoElement && selector.pseudoElementType() == CSSSelector::PseudoElementSlotted) {
1044
        // We see ::slotted() pseudo elements when collecting slotted rules from the slot shadow tree only.
1045
        ASSERT(checkingContext.resolvingMode == Mode::CollectingRules);
1046
        return is<HTMLSlotElement>(element);
1047
    }
1048
#endif
1042
    return true;
1049
    return true;
1043
}
1050
}
1044
1051
- Source/WebCore/style/StyleSharingResolver.cpp +2 lines
Lines 76-81 const Element* SharingResolver::resolve( Source/WebCore/style/StyleSharingResolver.cpp_sec1
76
    if (!element.parentElement())
76
    if (!element.parentElement())
77
        return nullptr;
77
        return nullptr;
78
    auto& parentElement = *element.parentElement();
78
    auto& parentElement = *element.parentElement();
79
    if (parentElement.shadowRoot())
80
        return nullptr;
79
    if (!parentElement.renderStyle())
81
    if (!parentElement.renderStyle())
80
        return nullptr;
82
        return nullptr;
81
    // If the element has inline style it is probably unique.
83
    // If the element has inline style it is probably unique.

Return to Bug 149441