Changeset 194762 in webkit


Ignore:
Timestamp:
Jan 8, 2016 1:06:10 AM (8 years ago)
Author:
Antti Koivisto
Message:

Enable selector filtering for shadow trees
https://bugs.webkit.org/show_bug.cgi?id=152831

Reviewed by Simon Fraser.

Selector filtering doesn't currently work in shadow trees making style resolve for them slow.
This is because SelectorFilter is not in "consistent" state.

This patch moves SelectorFilter ownership from StyleResolver to TreeResolver and guarantees
it is always upadated consistently. It eliminates a bunch of now unnecessary consistency checks
and special cases.

  • css/ElementRuleCollector.cpp:

(WebCore::ElementRuleCollector::ElementRuleCollector):

Assert for consistency instead of testing for it.

(WebCore::ElementRuleCollector::matchedResult):
(WebCore::ElementRuleCollector::collectMatchingRulesForList):

Selector filter can now be used if it exists.

  • css/ElementRuleCollector.h:

(WebCore::ElementRuleCollector::ElementRuleCollector): Deleted.

  • css/RuleSet.cpp:

(WebCore::RuleSet::addRule):

Disable selector filtering for custom shadow pseudo rules. They are resolved by shadow DOM resolver
but may contain components matching the normal DOM.

  • css/RuleSet.h:

(WebCore::RuleData::descendantSelectorIdentifierHashes):
(WebCore::RuleData::disableSelectorFiltering):
(WebCore::RuleData::compilationStatus):
(WebCore::RuleData::compiledSelectorCodeRef):

  • css/SelectorFilter.cpp:

(WebCore::collectElementIdentifierHashes):
(WebCore::SelectorFilter::parentStackIsConsistent):

New consistency conditions. This is now used for asserts only.

(WebCore::SelectorFilter::pushParentStackFrame):
(WebCore::SelectorFilter::popParentStackFrame):

Selector filter only filters the current tree context, replace parentOrShadowHostElement with parentElement.

(WebCore::SelectorFilter::setupParentStack): Deleted.

No longer needed.

(WebCore::SelectorFilter::pushParent):

Remove consistency check. These cases no longer happen.

  • css/SelectorFilter.h:

(WebCore::SelectorFilter::popParent):
(WebCore::SelectorFilter::parentStackIsEmpty):
(WebCore::SelectorFilter::fastRejectSelector):
(WebCore::SelectorFilter::parentStackIsConsistent): Deleted.

  • css/StyleInvalidationAnalysis.cpp:

(WebCore::StyleInvalidationAnalysis::invalidateIfNeeded):
(WebCore::StyleInvalidationAnalysis::invalidateStyle):

  • css/StyleResolver.cpp:

(WebCore::StyleResolver::appendAuthorStyleSheets):
(WebCore::StyleResolver::addKeyframeStyle):
(WebCore::StyleResolver::initElement):
(WebCore::StyleResolver::State::initForStyleResolve):

We no longer owner the selector filter. Move it to State.

(WebCore::StyleResolver::styleSharingCandidateMatchesRuleSet):
(WebCore::isAtShadowBoundary):
(WebCore::StyleResolver::styleForElement):
(WebCore::StyleResolver::pseudoStyleForElement):
(WebCore::StyleResolver::pseudoStyleRulesForElement):
(WebCore::StyleResolver::pushParentElement): Deleted.
(WebCore::StyleResolver::popParentElement): Deleted.

No need for this logic.

  • css/StyleResolver.h:

(WebCore::StyleResolver::ruleSets):
(WebCore::StyleResolver::mediaQueryEvaluator):
(WebCore::StyleResolver::State::document):
(WebCore::StyleResolver::State::setAuthorRollback):
(WebCore::StyleResolver::State::setUserRollback):
(WebCore::StyleResolver::State::selectorFilter):
(WebCore::StyleResolver::state):
(WebCore::checkRegionSelector):
(WebCore::StyleResolver::selectorFilter): Deleted.
(WebCore::StyleResolverParentPusher::StyleResolverParentPusher): Deleted.
(WebCore::StyleResolverParentPusher::push): Deleted.
(WebCore::StyleResolverParentPusher::~StyleResolverParentPusher): Deleted.

  • style/StyleTreeResolver.cpp:

This now owns the selector filter for a tree context.

(WebCore::Style::SelectorFilterPusher::SelectorFilterPusher):
(WebCore::Style::SelectorFilterPusher::push):
(WebCore::Style::SelectorFilterPusher::~SelectorFilterPusher):
(WebCore::Style::TreeResolver::TreeResolver):
(WebCore::Style::TreeResolver::styleForElement):
(WebCore::Style::TreeResolver::createRenderTreeForSlotAssignees):
(WebCore::Style::TreeResolver::createRenderTreeRecursively):
(WebCore::Style::TreeResolver::resolveChildren):
(WebCore::Style::TreeResolver::resolveRecursively):

Push the filter in a few more places to keep it consistent in shadow trees.

  • style/StyleTreeResolver.h:
Location:
trunk/Source/WebCore
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r194757 r194762  
     12016-01-07  Antti Koivisto  <antti@apple.com>
     2
     3        Enable selector filtering for shadow trees
     4        https://bugs.webkit.org/show_bug.cgi?id=152831
     5
     6        Reviewed by Simon Fraser.
     7
     8        Selector filtering doesn't currently work in shadow trees making style resolve for them slow.
     9        This is because SelectorFilter is not in "consistent" state.
     10
     11        This patch moves SelectorFilter ownership from StyleResolver to TreeResolver and guarantees
     12        it is always upadated consistently. It eliminates a bunch of now unnecessary consistency checks
     13        and special cases.
     14
     15        * css/ElementRuleCollector.cpp:
     16        (WebCore::ElementRuleCollector::ElementRuleCollector):
     17
     18            Assert for consistency instead of testing for it.
     19
     20        (WebCore::ElementRuleCollector::matchedResult):
     21        (WebCore::ElementRuleCollector::collectMatchingRulesForList):
     22
     23            Selector filter can now be used if it exists.
     24
     25        * css/ElementRuleCollector.h:
     26        (WebCore::ElementRuleCollector::ElementRuleCollector): Deleted.
     27        * css/RuleSet.cpp:
     28        (WebCore::RuleSet::addRule):
     29
     30            Disable selector filtering for custom shadow pseudo rules. They are resolved by shadow DOM resolver
     31            but may contain components matching the normal DOM.
     32
     33        * css/RuleSet.h:
     34        (WebCore::RuleData::descendantSelectorIdentifierHashes):
     35        (WebCore::RuleData::disableSelectorFiltering):
     36        (WebCore::RuleData::compilationStatus):
     37        (WebCore::RuleData::compiledSelectorCodeRef):
     38        * css/SelectorFilter.cpp:
     39        (WebCore::collectElementIdentifierHashes):
     40        (WebCore::SelectorFilter::parentStackIsConsistent):
     41
     42            New consistency conditions. This is now used for asserts only.
     43
     44        (WebCore::SelectorFilter::pushParentStackFrame):
     45        (WebCore::SelectorFilter::popParentStackFrame):
     46
     47            Selector filter only filters the current tree context, replace parentOrShadowHostElement with parentElement.
     48
     49        (WebCore::SelectorFilter::setupParentStack): Deleted.
     50
     51            No longer needed.
     52
     53        (WebCore::SelectorFilter::pushParent):
     54
     55            Remove consistency check. These cases no longer happen.
     56
     57        * css/SelectorFilter.h:
     58        (WebCore::SelectorFilter::popParent):
     59        (WebCore::SelectorFilter::parentStackIsEmpty):
     60        (WebCore::SelectorFilter::fastRejectSelector):
     61        (WebCore::SelectorFilter::parentStackIsConsistent): Deleted.
     62        * css/StyleInvalidationAnalysis.cpp:
     63        (WebCore::StyleInvalidationAnalysis::invalidateIfNeeded):
     64        (WebCore::StyleInvalidationAnalysis::invalidateStyle):
     65        * css/StyleResolver.cpp:
     66        (WebCore::StyleResolver::appendAuthorStyleSheets):
     67        (WebCore::StyleResolver::addKeyframeStyle):
     68        (WebCore::StyleResolver::initElement):
     69        (WebCore::StyleResolver::State::initForStyleResolve):
     70
     71            We no longer owner the selector filter. Move it to State.
     72
     73        (WebCore::StyleResolver::styleSharingCandidateMatchesRuleSet):
     74        (WebCore::isAtShadowBoundary):
     75        (WebCore::StyleResolver::styleForElement):
     76        (WebCore::StyleResolver::pseudoStyleForElement):
     77        (WebCore::StyleResolver::pseudoStyleRulesForElement):
     78        (WebCore::StyleResolver::pushParentElement): Deleted.
     79        (WebCore::StyleResolver::popParentElement): Deleted.
     80
     81            No need for this logic.
     82
     83        * css/StyleResolver.h:
     84        (WebCore::StyleResolver::ruleSets):
     85        (WebCore::StyleResolver::mediaQueryEvaluator):
     86        (WebCore::StyleResolver::State::document):
     87        (WebCore::StyleResolver::State::setAuthorRollback):
     88        (WebCore::StyleResolver::State::setUserRollback):
     89        (WebCore::StyleResolver::State::selectorFilter):
     90        (WebCore::StyleResolver::state):
     91        (WebCore::checkRegionSelector):
     92        (WebCore::StyleResolver::selectorFilter): Deleted.
     93        (WebCore::StyleResolverParentPusher::StyleResolverParentPusher): Deleted.
     94        (WebCore::StyleResolverParentPusher::push): Deleted.
     95        (WebCore::StyleResolverParentPusher::~StyleResolverParentPusher): Deleted.
     96        * style/StyleTreeResolver.cpp:
     97
     98            This now owns the selector filter for a tree context.
     99
     100        (WebCore::Style::SelectorFilterPusher::SelectorFilterPusher):
     101        (WebCore::Style::SelectorFilterPusher::push):
     102        (WebCore::Style::SelectorFilterPusher::~SelectorFilterPusher):
     103        (WebCore::Style::TreeResolver::TreeResolver):
     104        (WebCore::Style::TreeResolver::styleForElement):
     105        (WebCore::Style::TreeResolver::createRenderTreeForSlotAssignees):
     106        (WebCore::Style::TreeResolver::createRenderTreeRecursively):
     107        (WebCore::Style::TreeResolver::resolveChildren):
     108        (WebCore::Style::TreeResolver::resolveRecursively):
     109
     110            Push the filter in a few more places to keep it consistent in shadow trees.
     111
     112        * style/StyleTreeResolver.h:
     113
    11142016-01-07  Zalan Bujtas  <zalan@apple.com>
    2115
  • trunk/Source/WebCore/css/ElementRuleCollector.cpp

    r190842 r194762  
    4141#include "SVGElement.h"
    4242#include "SelectorCompiler.h"
     43#include "SelectorFilter.h"
    4344#include "ShadowRoot.h"
    4445#include "StyleProperties.h"
     
    7576    const bool includeEmptyRules;
    7677};
     78
     79ElementRuleCollector::ElementRuleCollector(Element& element, RenderStyle* style, const DocumentRuleSets& ruleSets, const SelectorFilter* selectorFilter)
     80    : m_element(element)
     81    , m_style(style)
     82    , m_ruleSets(ruleSets)
     83    , m_selectorFilter(selectorFilter)
     84{
     85    ASSERT(!m_selectorFilter || m_selectorFilter->parentStackIsConsistent(element.parentNode()));
     86}
    7787
    7888StyleResolver::MatchResult& ElementRuleCollector::matchedResult()
     
    353363            continue;
    354364
    355         if (m_canUseFastReject && m_selectorFilter.fastRejectSelector<RuleData::maximumIdentifierCount>(ruleData.descendantSelectorIdentifierHashes()))
     365        if (m_selectorFilter && m_selectorFilter->fastRejectSelector<RuleData::maximumIdentifierCount>(ruleData.descendantSelectorIdentifierHashes()))
    356366            continue;
    357367
  • trunk/Source/WebCore/css/ElementRuleCollector.h

    r190842 r194762  
    4646class ElementRuleCollector {
    4747public:
    48     ElementRuleCollector(Element& element, RenderStyle* style, const DocumentRuleSets& ruleSets, const SelectorFilter& selectorFilter)
    49         : m_element(element)
    50         , m_style(style)
    51         , m_ruleSets(ruleSets)
    52         , m_selectorFilter(selectorFilter)
    53         , m_canUseFastReject(m_selectorFilter.parentStackIsConsistent(element.parentNode()))
    54     {
    55     }
     48    ElementRuleCollector(Element&, RenderStyle*, const DocumentRuleSets&, const SelectorFilter*);
    5649
    5750    void matchAllRules(bool matchAuthorAndUserStyles, bool includeSMILProperties);
     
    9588    RenderStyle* m_style;
    9689    const DocumentRuleSets& m_ruleSets;
    97     const SelectorFilter& m_selectorFilter;
     90    const SelectorFilter* m_selectorFilter;
    9891
    9992    bool m_isPrintStyle { false };
     
    10295    bool m_sameOriginOnly { false };
    10396    SelectorChecker::Mode m_mode { SelectorChecker::Mode::ResolvingStyle };
    104     bool m_canUseFastReject;
    10597
    10698    Vector<MatchedRule, 64> m_matchedRules;
  • trunk/Source/WebCore/css/RuleSet.cpp

    r194496 r194762  
    226226
    227227        if (selector->isCustomPseudoElement()) {
     228            // FIXME: Custom pseudo elements are handled by the shadow tree's selector filter. It doesn't know about the main DOM.
     229            ruleData.disableSelectorFiltering();
    228230            addToRuleSet(selector->value().impl(), m_shadowPseudoElementRules, ruleData);
    229231            return;
  • trunk/Source/WebCore/css/RuleSet.h

    r194496 r194762  
    8484    static const unsigned maximumIdentifierCount = 4;
    8585    const unsigned* descendantSelectorIdentifierHashes() const { return m_descendantSelectorIdentifierHashes; }
     86
     87    void disableSelectorFiltering() { m_descendantSelectorIdentifierHashes[0] = 0; }
    8688
    8789#if ENABLE(CSS_SELECTOR_JIT)
  • trunk/Source/WebCore/css/SelectorFilter.cpp

    r182321 r194762  
    3131
    3232#include "CSSSelector.h"
     33#include "ShadowRoot.h"
    3334#include "StyledElement.h"
    3435
     
    5455}
    5556
     57bool SelectorFilter::parentStackIsConsistent(const ContainerNode* parentNode) const
     58{
     59    if (!parentNode || is<Document>(parentNode) || is<ShadowRoot>(parentNode))
     60        return m_parentStack.isEmpty();
     61
     62    return !m_parentStack.isEmpty() && m_parentStack.last().element == parentNode;
     63}
     64
    5665void SelectorFilter::pushParentStackFrame(Element* parent)
    5766{
    58     ASSERT(m_ancestorIdentifierFilter);
    59     ASSERT(m_parentStack.isEmpty() || m_parentStack.last().element == parent->parentOrShadowHostElement());
    60     ASSERT(!m_parentStack.isEmpty() || !parent->parentOrShadowHostElement());
     67    ASSERT(m_parentStack.isEmpty() || m_parentStack.last().element == parent->parentElement());
     68    ASSERT(!m_parentStack.isEmpty() || !parent->parentElement());
    6169    m_parentStack.append(ParentStackFrame(parent));
    6270    ParentStackFrame& parentFrame = m_parentStack.last();
     
    6674    size_t count = parentFrame.identifierHashes.size();
    6775    for (size_t i = 0; i < count; ++i)
    68         m_ancestorIdentifierFilter->add(parentFrame.identifierHashes[i]);
     76        m_ancestorIdentifierFilter.add(parentFrame.identifierHashes[i]);
    6977}
    7078
     
    7280{
    7381    ASSERT(!m_parentStack.isEmpty());
    74     ASSERT(m_ancestorIdentifierFilter);
    7582    const ParentStackFrame& parentFrame = m_parentStack.last();
    7683    size_t count = parentFrame.identifierHashes.size();
    7784    for (size_t i = 0; i < count; ++i)
    78         m_ancestorIdentifierFilter->remove(parentFrame.identifierHashes[i]);
     85        m_ancestorIdentifierFilter.remove(parentFrame.identifierHashes[i]);
    7986    m_parentStack.removeLast();
    8087    if (m_parentStack.isEmpty()) {
    81         ASSERT(m_ancestorIdentifierFilter->likelyEmpty());
    82         m_ancestorIdentifierFilter = nullptr;
     88        ASSERT(m_ancestorIdentifierFilter.likelyEmpty());
     89        m_ancestorIdentifierFilter.clear();
    8390    }
    84 }
    85 
    86 void SelectorFilter::setupParentStack(Element* parent)
    87 {
    88     ASSERT(m_parentStack.isEmpty() == !m_ancestorIdentifierFilter);
    89     // Kill whatever we stored before.
    90     m_parentStack.shrink(0);
    91     m_ancestorIdentifierFilter = std::make_unique<CountingBloomFilter<bloomFilterKeyBits>>();
    92     // Fast version if parent is a root element:
    93     if (!parent->parentNode() && !parent->isShadowRoot()) {
    94         pushParentStackFrame(parent);
    95         return;
    96     }
    97     // Otherwise climb up the tree.
    98     Vector<Element*, 30> ancestors;
    99     for (Element* ancestor = parent; ancestor; ancestor = ancestor->parentOrShadowHostElement())
    100         ancestors.append(ancestor);
    101     for (size_t n = ancestors.size(); n; --n)
    102         pushParentStackFrame(ancestors[n - 1]);
    10391}
    10492
    10593void SelectorFilter::pushParent(Element* parent)
    10694{
    107     ASSERT(m_ancestorIdentifierFilter);
    108     // We may get invoked for some random elements in some wacky cases during style resolve.
    109     // Pause maintaining the stack in this case.
    110     if (m_parentStack.last().element != parent->parentOrShadowHostElement())
    111         return;
    11295    pushParentStackFrame(parent);
    11396}
  • trunk/Source/WebCore/css/SelectorFilter.h

    r182321 r194762  
    4444    void popParentStackFrame();
    4545
    46     void setupParentStack(Element* parent);
    4746    void pushParent(Element* parent);
    4847    void popParent() { popParentStackFrame(); }
    4948    bool parentStackIsEmpty() const { return m_parentStack.isEmpty(); }
    50     bool parentStackIsConsistent(const ContainerNode* parentNode) const { return !m_parentStack.isEmpty() && m_parentStack.last().element == parentNode; }
     49    bool parentStackIsConsistent(const ContainerNode* parentNode) const;
    5150
    5251    template <unsigned maximumIdentifierCount>
     
    6564    // With 100 unique strings in the filter, 2^12 slot table has false positive rate of ~0.2%.
    6665    static const unsigned bloomFilterKeyBits = 12;
    67     std::unique_ptr<CountingBloomFilter<bloomFilterKeyBits>> m_ancestorIdentifierFilter;
     66    CountingBloomFilter<bloomFilterKeyBits> m_ancestorIdentifierFilter;
    6867};
    6968
     
    7170inline bool SelectorFilter::fastRejectSelector(const unsigned* identifierHashes) const
    7271{
    73     ASSERT(m_ancestorIdentifierFilter);
    7472    for (unsigned n = 0; n < maximumIdentifierCount && identifierHashes[n]; ++n) {
    75         if (!m_ancestorIdentifierFilter->mayContain(identifierHashes[n]))
     73        if (!m_ancestorIdentifierFilter.mayContain(identifierHashes[n]))
    7674            return true;
    7775    }
  • trunk/Source/WebCore/css/StyleInvalidationAnalysis.cpp

    r191871 r194762  
    9898    switch (element.styleChangeType()) {
    9999    case NoStyleChange: {
    100         ElementRuleCollector ruleCollector(element, nullptr, m_ruleSets, filter);
     100        ElementRuleCollector ruleCollector(element, nullptr, m_ruleSets, &filter);
    101101        ruleCollector.setMode(SelectorChecker::Mode::CollectingRulesIgnoringVirtualPseudoElements);
    102102        ruleCollector.matchAuthorRules(false);
     
    146146            it.traverseNextSkippingChildren();
    147147    }
    148 
    149     while (!parentStack.isEmpty()) {
    150         parentStack.removeLast();
    151         filter.popParent();
    152     }
    153148}
    154149
     
    164159
    165160    SelectorFilter filter;
    166     filter.setupParentStack(documentElement);
    167161    invalidateStyleForTree(*documentElement, filter);
    168162}
  • trunk/Source/WebCore/css/StyleResolver.cpp

    r194496 r194762  
    294294}
    295295
    296 void StyleResolver::pushParentElement(Element* parent)
    297 {
    298     const ContainerNode* parentsParent = parent->parentOrShadowHostElement();
    299 
    300     // We are not always invoked consistently. For example, script execution can cause us to enter
    301     // style recalc in the middle of tree building. We may also be invoked from somewhere within the tree.
    302     // Reset the stack in this case, or if we see a new root element.
    303     // Otherwise just push the new parent.
    304     if (!parentsParent || m_selectorFilter.parentStackIsEmpty())
    305         m_selectorFilter.setupParentStack(parent);
    306     else
    307         m_selectorFilter.pushParent(parent);
    308 }
    309 
    310 void StyleResolver::popParentElement(Element* parent)
    311 {
    312     // Note that we may get invoked for some random elements in some wacky cases during style resolve.
    313     // Pause maintaining the stack in this case.
    314     if (m_selectorFilter.parentStackIsConsistent(parent))
    315         m_selectorFilter.popParent();
    316 }
    317 
    318296// This is a simplified style setting function for keyframe styles
    319297void StyleResolver::addKeyframeStyle(PassRefPtr<StyleRuleKeyframes> rule)
     
    388366}
    389367
    390 inline void StyleResolver::State::initForStyleResolve(Document& document, Element* e, RenderStyle* parentStyle, const RenderRegion* regionForStyling)
     368inline void StyleResolver::State::initForStyleResolve(Document& document, Element* e, RenderStyle* parentStyle, const RenderRegion* regionForStyling, const SelectorFilter* selectorFilter)
    391369{
    392370    m_regionForStyling = regionForStyling;
     
    408386    m_authorRollback = nullptr;
    409387    m_userRollback = nullptr;
     388
     389    m_selectorFilter = selectorFilter;
    410390
    411391    updateConversionData();
     
    476456        return false;
    477457
    478     ElementRuleCollector collector(*m_state.element(), m_state.style(), m_ruleSets, m_selectorFilter);
     458    ElementRuleCollector collector(*m_state.element(), m_state.style(), m_ruleSets, m_state.selectorFilter());
    479459    return collector.hasAnyMatchingRules(ruleSet);
    480460}
     
    724704
    725705Ref<RenderStyle> StyleResolver::styleForElement(Element* element, RenderStyle* defaultParent,
    726     StyleSharingBehavior sharingBehavior, RuleMatchingBehavior matchingBehavior, const RenderRegion* regionForStyling)
     706    StyleSharingBehavior sharingBehavior, RuleMatchingBehavior matchingBehavior, const RenderRegion* regionForStyling, const SelectorFilter* selectorFilter)
    727707{
    728708    RELEASE_ASSERT(!m_inLoadPendingImages);
     
    742722    State& state = m_state;
    743723    initElement(element);
    744     state.initForStyleResolve(document(), element, defaultParent, regionForStyling);
     724    state.initForStyleResolve(document(), element, defaultParent, regionForStyling, selectorFilter);
     725
    745726    if (sharingBehavior == AllowStyleSharing) {
    746727        if (RenderStyle* sharedStyle = locateSharedStyle()) {
     
    774755        m_ruleSets.collectFeatures();
    775756
    776     ElementRuleCollector collector(*element, state.style(), m_ruleSets, m_selectorFilter);
     757    ElementRuleCollector collector(*element, state.style(), m_ruleSets, m_state.selectorFilter());
    777758    collector.setRegionForStyling(regionForStyling);
    778759    collector.setMedium(m_medium.get());
     
    940921
    941922    // Check UA, user and author rules.
    942     ElementRuleCollector collector(*element, m_state.style(), m_ruleSets, m_selectorFilter);
     923    ElementRuleCollector collector(*element, m_state.style(), m_ruleSets, m_state.selectorFilter());
    943924    collector.setPseudoStyleRequest(pseudoStyleRequest);
    944925    collector.setMedium(m_medium.get());
     
    14191400    m_state.initForStyleResolve(document(), element, nullptr);
    14201401
    1421     ElementRuleCollector collector(*element, m_state.style(), m_ruleSets, m_selectorFilter);
     1402    ElementRuleCollector collector(*element, m_state.style(), m_ruleSets, m_state.selectorFilter());
    14221403    collector.setMode(SelectorChecker::Mode::CollectingRules);
    14231404    collector.setPseudoStyleRequest(PseudoStyleRequest(pseudoId));
  • trunk/Source/WebCore/css/StyleResolver.h

    r194496 r194762  
    3636#include "ScrollTypes.h"
    3737#include "SelectorChecker.h"
    38 #include "SelectorFilter.h"
    3938#include "StyleInheritedData.h"
    4039#include "ViewportStyleResolver.h"
     
    7776class RuleData;
    7877class RuleSet;
     78class SelectorFilter;
    7979class Settings;
    8080class StyleImage;
     
    136136    ~StyleResolver();
    137137
    138     // Using these during tree walk will allow style selector to optimize child and descendant selector lookups.
    139     void pushParentElement(Element*);
    140     void popParentElement(Element*);
    141 
    142138    Ref<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle, StyleSharingBehavior = AllowStyleSharing,
    143         RuleMatchingBehavior = MatchAllRules, const RenderRegion* regionForStyling = nullptr);
     139        RuleMatchingBehavior = MatchAllRules, const RenderRegion* regionForStyling = nullptr, const SelectorFilter* = nullptr);
    144140
    145141    void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList&);
     
    161157    DocumentRuleSets& ruleSets() { return m_ruleSets; }
    162158    const DocumentRuleSets& ruleSets() const { return m_ruleSets; }
    163     SelectorFilter& selectorFilter() { return m_selectorFilter; }
    164159
    165160    const MediaQueryEvaluator& mediaQueryEvaluator() const { return *m_medium; }
     
    386381    public:
    387382        void initElement(Element*);
    388         void initForStyleResolve(Document&, Element*, RenderStyle* parentStyle, const RenderRegion* regionForStyling = nullptr);
     383        void initForStyleResolve(Document&, Element*, RenderStyle* parentStyle, const RenderRegion* regionForStyling = nullptr, const SelectorFilter* = nullptr);
    389384        void clear();
    390385
     
    444439        void setAuthorRollback(std::unique_ptr<CascadedProperties>& rollback) { m_authorRollback = WTFMove(rollback); }
    445440        void setUserRollback(std::unique_ptr<CascadedProperties>& rollback) { m_userRollback = WTFMove(rollback); }
     441
     442        const SelectorFilter* selectorFilter() const { return m_selectorFilter; }
    446443       
    447444    private:
     
    481478        std::unique_ptr<CascadedProperties> m_authorRollback;
    482479        std::unique_ptr<CascadedProperties> m_userRollback;
     480
     481        const SelectorFilter* m_selectorFilter { nullptr };
    483482    };
    484483
     
    560559
    561560    Document& m_document;
    562     SelectorFilter m_selectorFilter;
    563561
    564562    bool m_matchAuthorAndUserStyles;
     
    619617}
    620618
    621 class StyleResolverParentPusher {
    622 public:
    623     StyleResolverParentPusher(Element* parent)
    624         : m_parent(parent)
    625         , m_pushedStyleResolver(nullptr)
    626     { }
    627     void push()
    628     {
    629         if (m_pushedStyleResolver)
    630             return;
    631         m_pushedStyleResolver = &m_parent->styleResolver();
    632         m_pushedStyleResolver->pushParentElement(m_parent);
    633     }
    634     ~StyleResolverParentPusher()
    635     {
    636         if (!m_pushedStyleResolver)
    637             return;
    638         // This tells us that our pushed style selector is in a bad state,
    639         // so we should just bail out in that scenario.
    640         ASSERT(m_pushedStyleResolver == &m_parent->styleResolver());
    641         m_pushedStyleResolver->popParentElement(m_parent);
    642     }
    643    
    644 private:
    645     Element* m_parent;
    646     StyleResolver* m_pushedStyleResolver;
    647 };
    648 
    649619} // namespace WebCore
    650620
  • trunk/Source/WebCore/style/StyleTreeResolver.cpp

    r194691 r194762  
    6767static void resolveTextNode(Text&, RenderTreePosition&);
    6868
     69class SelectorFilterPusher {
     70public:
     71    enum PushMode { Push, NoPush };
     72    SelectorFilterPusher(SelectorFilter& selectorFilter, Element& parent, PushMode pushMode = Push)
     73        : m_selectorFilter(selectorFilter)
     74        , m_parent(parent)
     75    {
     76        if (pushMode == Push)
     77            push();
     78    }
     79    void push()
     80    {
     81        if (m_didPush)
     82            return;
     83        m_didPush = true;
     84        m_selectorFilter.pushParent(&m_parent);
     85    }
     86    ~SelectorFilterPusher()
     87    {
     88        if (!m_didPush)
     89            return;
     90        m_selectorFilter.popParent();
     91    }
     92   
     93private:
     94    SelectorFilter& m_selectorFilter;
     95    Element& m_parent;
     96    bool m_didPush { false };
     97};
     98
    6999TreeResolver::TreeResolver(Document& document)
    70100    : m_document(document)
     
    98128            return style.releaseNonNull();
    99129    }
    100     return m_styleResolver.styleForElement(&element, &inheritedStyle);
     130    return m_styleResolver.styleForElement(&element, &inheritedStyle, AllowStyleSharing, MatchAllRules, nullptr, &m_selectorFilter);
    101131}
    102132
     
    411441                m_shadowHostTreeResolver->createRenderTreeRecursively(downcast<Element>(*child), inheritedStyle, renderTreePosition, nullptr);
    412442        }
    413     } else
     443    } else {
     444        SelectorFilterPusher selectorFilterPusher(m_selectorFilter, slot);
    414445        createRenderTreeForChildren(slot, inheritedStyle, renderTreePosition);
     446    }
    415447
    416448    slot.clearNeedsStyleRecalc();
     
    437469
    438470    if (auto* renderer = current.renderer()) {
    439         StyleResolverParentPusher parentPusher(&current);
     471        SelectorFilterPusher selectorFilterPusher(m_selectorFilter, current, SelectorFilterPusher::NoPush);
    440472
    441473        RenderTreePosition childRenderTreePosition(*renderer);
     
    443475
    444476        auto* shadowRoot = current.shadowRoot();
    445         if (shadowRoot)
     477        if (shadowRoot) {
     478            selectorFilterPusher.push();
    446479            createRenderTreeForShadowRoot(*shadowRoot);
    447         else if (current.firstChild())
    448             parentPusher.push();
     480        } else if (current.firstChild())
     481            selectorFilterPusher.push();
    449482
    450483        bool skipChildren = shadowRoot;
     
    731764void TreeResolver::resolveChildren(Element& current, RenderStyle& inheritedStyle, Change change, RenderTreePosition& childRenderTreePosition)
    732765{
    733     StyleResolverParentPusher parentPusher(&current);
     766    SelectorFilterPusher selectorFilterPusher(m_selectorFilter, current, SelectorFilterPusher::NoPush);
    734767
    735768    bool elementNeedingStyleRecalcAffectsNextSiblingElementStyle = false;
     
    752785            elementNeedingStyleRecalcAffectsNextSiblingElementStyle = childElement.affectsNextSiblingElementStyle();
    753786        if (change >= Inherit || childElement.childNeedsStyleRecalc() || childElement.needsStyleRecalc()) {
    754             parentPusher.push();
     787            selectorFilterPusher.push();
    755788            resolveRecursively(childElement, inheritedStyle, childRenderTreePosition, change);
    756789        }
     
    804837        auto* shadowRoot = current.shadowRoot();
    805838        if (shadowRoot && (change >= Inherit || shadowRoot->childNeedsStyleRecalc() || shadowRoot->needsStyleRecalc())) {
     839            SelectorFilterPusher selectorFilterPusher(m_selectorFilter, current);
     840
    806841            TreeResolver shadowTreeResolver(*shadowRoot, *this);
    807842            shadowTreeResolver.resolveShadowTree(change, renderer->style());
  • trunk/Source/WebCore/style/StyleTreeResolver.h

    r194691 r194762  
    2828
    2929#include "RenderStyleConstants.h"
     30#include "SelectorFilter.h"
    3031#include "StyleChange.h"
    3132#include <functional>
     
    8384    ShadowRoot* m_shadowRoot { nullptr };
    8485    TreeResolver* m_shadowHostTreeResolver { nullptr };
     86
     87    SelectorFilter m_selectorFilter;
    8588};
    8689
Note: See TracChangeset for help on using the changeset viewer.