Changeset 89132 in webkit


Ignore:
Timestamp:
Jun 17, 2011 3:13:52 AM (13 years ago)
Author:
apavlov@chromium.org
Message:

2011-06-17 Alexander Pavlov <apavlov@chromium.org>

Reviewed by David Hyatt.

Web Inspector: support for emulating element's pseudo class state in styleRulesForElement()
https://bugs.webkit.org/show_bug.cgi?id=61070

This patch is a slight rework of a solution by Alexander Udalov.
It is supposed to help implement a feature in Web Inspector to examine
style rules matched for different states of a given element.
Web Inspector is supposed to pass a mask of ForcePseudoClassFlags to
styleRulesForElement(), so that it will filter only the rules whose state
(a set of pseudo classes in their selectors) matches a given
mask, ignoring the state of the element itself.
DoNotForcePseudoClassMask is the default behaviour; it always examines
the state of a given element to make a match.

Tests will be provided in a subsequent Web Inspector change employing this functionality.

  • css/CSSStyleSelector.cpp: (WebCore::CSSStyleSelector::initForStyleResolve): (WebCore::CSSStyleSelector::styleRulesForElement): (WebCore::CSSStyleSelector::pseudoStyleRulesForElement): (WebCore::CSSStyleSelector::checkSelector): (WebCore::CSSStyleSelector::SelectorChecker::checkSelector): (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
  • css/CSSStyleSelector.h:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r89131 r89132  
     12011-06-17  Alexander Pavlov  <apavlov@chromium.org>
     2
     3        Reviewed by David Hyatt.
     4
     5        Web Inspector: support for emulating element's pseudo class state in styleRulesForElement()
     6        https://bugs.webkit.org/show_bug.cgi?id=61070
     7
     8        This patch is a slight rework of a solution by Alexander Udalov.
     9        It is supposed to help implement a feature in Web Inspector to examine
     10        style rules matched for different states of a given element.
     11        Web Inspector is supposed to pass a mask of ForcePseudoClassFlags to
     12        styleRulesForElement(), so that it will filter only the rules whose state
     13        (a set of pseudo classes in their selectors) matches a given
     14        mask, ignoring the state of the element itself.
     15        DoNotForcePseudoClassMask is the default behaviour; it always examines
     16        the state of a given element to make a match.
     17
     18        Tests will be provided in a subsequent Web Inspector change employing this functionality.
     19
     20        * css/CSSStyleSelector.cpp:
     21        (WebCore::CSSStyleSelector::initForStyleResolve):
     22        (WebCore::CSSStyleSelector::styleRulesForElement):
     23        (WebCore::CSSStyleSelector::pseudoStyleRulesForElement):
     24        (WebCore::CSSStyleSelector::checkSelector):
     25        (WebCore::CSSStyleSelector::SelectorChecker::checkSelector):
     26        (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
     27        * css/CSSStyleSelector.h:
     28
    1292011-06-17  Yury Semikhatsky  <yurys@chromium.org>
    230
  • trunk/Source/WebCore/css/CSSStyleSelector.cpp

    r88804 r89132  
    885885
    886886    m_fontDirty = false;
     887
     888    m_forcePseudoClassMask = DoNotForcePseudoClassMask;
    887889}
    888890
     
    20192021}
    20202022
    2021 PassRefPtr<CSSRuleList> CSSStyleSelector::styleRulesForElement(Element* e, unsigned rulesToInclude)
    2022 {
    2023     return pseudoStyleRulesForElement(e, NOPSEUDO, rulesToInclude);
    2024 }
    2025 
    2026 PassRefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element* e, PseudoId pseudoId, unsigned rulesToInclude)
     2023PassRefPtr<CSSRuleList> CSSStyleSelector::styleRulesForElement(Element* e, unsigned rulesToInclude, unsigned forcePseudoClassMask)
     2024{
     2025    return pseudoStyleRulesForElement(e, NOPSEUDO, rulesToInclude, forcePseudoClassMask);
     2026}
     2027
     2028PassRefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element* e, PseudoId pseudoId, unsigned rulesToInclude, unsigned forcePseudoClassMask)
    20272029{
    20282030    if (!e || !e->document()->haveStylesheetsLoaded())
     
    20332035    initElement(e);
    20342036    initForStyleResolve(e, 0, pseudoId);
     2037    m_forcePseudoClassMask = forcePseudoClassMask;
    20352038
    20362039    if (rulesToInclude & UAAndUserCSSRules) {
     
    20572060
    20582061    m_checker.m_collectRulesOnly = false;
     2062    m_forcePseudoClassMask = DoNotForcePseudoClassMask;
    20592063   
    20602064    return m_ruleList.release();
     
    20792083
    20802084    // Slow path.
    2081     SelectorMatch match = m_checker.checkSelector(ruleData.selector(), m_element, m_dynamicPseudo, false, false, style(), m_parentNode ? m_parentNode->renderStyle() : 0);
     2085    SelectorMatch match = m_checker.checkSelector(ruleData.selector(), m_element, m_dynamicPseudo, false, false, m_forcePseudoClassMask, style(), m_parentNode ? m_parentNode->renderStyle() : 0);
    20822086    if (match != SelectorMatches)
    20832087        return false;
     
    22082212// * SelectorFailsLocally    - the selector fails for the element e
    22092213// * SelectorFailsCompletely - the selector fails for e and any sibling or ancestor of e
    2210 CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
     2214CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, unsigned forcePseudoClassMask, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
    22112215{
    22122216#if ENABLE(SVG)
     
    22182222
    22192223    // first selector has to match
    2220     if (!checkOneSelector(sel, e, dynamicPseudo, isSubSelector, encounteredLink, elementStyle, elementParentStyle))
     2224    if (!checkOneSelector(sel, e, dynamicPseudo, isSubSelector, encounteredLink, forcePseudoClassMask, elementStyle, elementParentStyle))
    22212225        return SelectorFailsLocally;
    22222226
     
    22522256                    return SelectorFailsCompletely;
    22532257                e = static_cast<Element*>(n);
    2254                 SelectorMatch match = checkSelector(sel, e, dynamicPseudo, false, encounteredLink);
     2258                SelectorMatch match = checkSelector(sel, e, dynamicPseudo, false, encounteredLink, forcePseudoClassMask);
    22552259                if (match != SelectorFailsLocally)
    22562260                    return match;
     
    22632267                return SelectorFailsCompletely;
    22642268            e = static_cast<Element*>(n);
    2265             return checkSelector(sel, e, dynamicPseudo, false, encounteredLink);
     2269            return checkSelector(sel, e, dynamicPseudo, false, encounteredLink, forcePseudoClassMask);
    22662270        }
    22672271        case CSSSelector::DirectAdjacent:
     
    22792283            e = static_cast<Element*>(n);
    22802284            m_matchVisitedPseudoClass = false;
    2281             return checkSelector(sel, e, dynamicPseudo, false, encounteredLink);
     2285            return checkSelector(sel, e, dynamicPseudo, false, encounteredLink, forcePseudoClassMask);
    22822286        }
    22832287        case CSSSelector::IndirectAdjacent:
     
    22952299                e = static_cast<Element*>(n);
    22962300                m_matchVisitedPseudoClass = false;
    2297                 SelectorMatch match = checkSelector(sel, e, dynamicPseudo, false, encounteredLink);
     2301                SelectorMatch match = checkSelector(sel, e, dynamicPseudo, false, encounteredLink, forcePseudoClassMask);
    22982302                if (match != SelectorFailsLocally)
    22992303                    return match;
     
    23072311                !((RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER) && sel->m_match == CSSSelector::PseudoClass))
    23082312                return SelectorFailsCompletely;
    2309             return checkSelector(sel, e, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle);
     2313            return checkSelector(sel, e, dynamicPseudo, true, encounteredLink, forcePseudoClassMask, elementStyle, elementParentStyle);
    23102314        case CSSSelector::ShadowDescendant:
    23112315        {
     
    23142318                return SelectorFailsCompletely;
    23152319            e = static_cast<Element*>(shadowHostNode);
    2316             return checkSelector(sel, e, dynamicPseudo, false, encounteredLink);
     2320            return checkSelector(sel, e, dynamicPseudo, false, encounteredLink, forcePseudoClassMask);
    23172321        }
    23182322    }
     
    23882392}
    23892393
    2390 bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
     2394bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, unsigned forcePseudoClassMask, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
    23912395{
    23922396    ASSERT(e);
     
    24822486                ASSERT(subSel->pseudoType() != CSSSelector::PseudoNot);
    24832487
    2484                 if (!checkOneSelector(subSel, e, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle))
     2488                if (!checkOneSelector(subSel, e, dynamicPseudo, true, encounteredLink, forcePseudoClassMask, elementStyle, elementParentStyle))
    24852489                    return true;
    24862490            }
     
    24932497                return !m_document->page()->focusController()->isActive();
    24942498        }
    2495        
     2499
     2500        CSSSelector::PseudoType pseudoType = sel->pseudoType();
     2501
     2502        // Check forced pseudo class mask first.
     2503        if (forcePseudoClassMask != DoNotForcePseudoClassMask) {
     2504            switch (pseudoType) {
     2505            case CSSSelector::PseudoLink:
     2506                return forcePseudoClassMask & ForceLink;
     2507            case CSSSelector::PseudoVisited:
     2508                return forcePseudoClassMask & ForceVisited;
     2509            case CSSSelector::PseudoFocus:
     2510                return forcePseudoClassMask & ForceFocus;
     2511            case CSSSelector::PseudoHover:
     2512                return forcePseudoClassMask & ForceHover;
     2513            case CSSSelector::PseudoActive:
     2514                return forcePseudoClassMask & ForceActive;
     2515            default:
     2516                break;
     2517            }
     2518        }
     2519 
    24962520        // Normal element pseudo class checking.
    2497         switch (sel->pseudoType()) {
     2521        switch (pseudoType) {
    24982522            // Pseudo classes:
    24992523            case CSSSelector::PseudoNot:
     
    27912815            case CSSSelector::PseudoAny:
    27922816                for (CSSSelector* selector = sel->selectorList()->first(); selector; selector = CSSSelectorList::next(selector)) {
    2793                     if (checkSelector(selector, e, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle) == SelectorMatches)
     2817                    if (checkSelector(selector, e, dynamicPseudo, true, encounteredLink, forcePseudoClassMask, elementStyle, elementParentStyle) == SelectorMatches)
    27942818                        return true;
    27952819                }
  • trunk/Source/WebCore/css/CSSStyleSelector.h

    r88793 r89132  
    131131
    132132    public:
     133        enum ForcePseudoClassFlags {
     134            ForceNone = 0,
     135            DoNotForcePseudoClassMask = 1 << 0,
     136            ForceHover = 1 << 1,
     137            ForceFocus = 1 << 2,
     138            ForceActive = 1 << 3,
     139            ForceLink = 1 << 4,
     140            ForceVisited = 1 << 5
     141        };
     142
    133143        // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
    134144        enum CSSRuleFilter {
     
    140150            AllCSSRules         = AllButEmptyCSSRules | EmptyCSSRules,
    141151        };
    142         PassRefPtr<CSSRuleList> styleRulesForElement(Element*, unsigned rulesToInclude = AllButEmptyCSSRules);
    143         PassRefPtr<CSSRuleList> pseudoStyleRulesForElement(Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules);
     152        PassRefPtr<CSSRuleList> styleRulesForElement(Element*, unsigned rulesToInclude = AllButEmptyCSSRules, unsigned forcePseudoClassMask = DoNotForcePseudoClassMask);
     153        PassRefPtr<CSSRuleList> pseudoStyleRulesForElement(Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules, unsigned forcePseudoClassMask = DoNotForcePseudoClassMask);
    144154
    145155        // Given a CSS keyword in the range (xx-small to -webkit-xxx-large), this function will return
     
    266276
    267277            bool checkSelector(CSSSelector*, Element*) const;
    268             SelectorMatch checkSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
    269             bool checkOneSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle*, RenderStyle* elementParentStyle) const;
     278            SelectorMatch checkSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, unsigned forcePseudoClassMask = DoNotForcePseudoClassMask, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
     279            bool checkOneSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, unsigned forcePseudoClassMask, RenderStyle*, RenderStyle* elementParentStyle) const;
    270280            bool checkScrollbarPseudoClass(CSSSelector*, PseudoId& dynamicPseudo) const;
    271281            static bool fastCheckSelector(const CSSSelector*, const Element*);
     
    364374        bool m_fontDirty;
    365375        bool m_matchAuthorAndUserStyles;
     376        unsigned m_forcePseudoClassMask; // enum ForcePseudoClassFlags
    366377       
    367378        RefPtr<CSSFontSelector> m_fontSelector;
Note: See TracChangeset for help on using the changeset viewer.