Title: [93122] trunk/Source/WebCore
Revision
93122
Author
pfeld...@chromium.org
Date
2011-08-16 10:15:06 -0700 (Tue, 16 Aug 2011)

Log Message

Web Inspector: force pseudo element state when checking it in the styles sidebar.
https://bugs.webkit.org/show_bug.cgi?id=66292

This reverts http://trac.webkit.org/changeset/89132 and introduces InspectorInstrumentation
calls from the CSSStyleSelector for pseudo state processing. These calls are very fast:
they are guarded with the inline checks for the front-end count.

Reviewed by David Hyatt.

* 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:
* inspector/InspectorCSSAgent.cpp:
(WebCore::computePseudoClassMask):
(WebCore::InspectorCSSAgent::InspectorCSSAgent):
(WebCore::InspectorCSSAgent::clearFrontend):
(WebCore::InspectorCSSAgent::forcePseudoState):
(WebCore::InspectorCSSAgent::getStylesForNode):
(WebCore::InspectorCSSAgent::didRemoveDocument):
(WebCore::InspectorCSSAgent::didRemoveDOMNode):
(WebCore::InspectorCSSAgent::clearPseudoState):
* inspector/InspectorCSSAgent.h:
* inspector/InspectorController.cpp:
(WebCore::InspectorController::disconnectFrontend):
* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::forcePseudoStateImpl):
* inspector/InspectorInstrumentation.h:
(WebCore::InspectorInstrumentation::forcePseudoState):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (93121 => 93122)


--- trunk/Source/WebCore/ChangeLog	2011-08-16 16:59:04 UTC (rev 93121)
+++ trunk/Source/WebCore/ChangeLog	2011-08-16 17:15:06 UTC (rev 93122)
@@ -1,3 +1,39 @@
+2011-08-16  Pavel Feldman  <pfeld...@google.com>
+
+        Web Inspector: force pseudo element state when checking it in the styles sidebar.
+        https://bugs.webkit.org/show_bug.cgi?id=66292
+
+        This reverts http://trac.webkit.org/changeset/89132 and introduces InspectorInstrumentation
+        calls from the CSSStyleSelector for pseudo state processing. These calls are very fast:
+        they are guarded with the inline checks for the front-end count.
+
+        Reviewed by David Hyatt.
+
+        * 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:
+        * inspector/InspectorCSSAgent.cpp:
+        (WebCore::computePseudoClassMask):
+        (WebCore::InspectorCSSAgent::InspectorCSSAgent):
+        (WebCore::InspectorCSSAgent::clearFrontend):
+        (WebCore::InspectorCSSAgent::forcePseudoState):
+        (WebCore::InspectorCSSAgent::getStylesForNode):
+        (WebCore::InspectorCSSAgent::didRemoveDocument):
+        (WebCore::InspectorCSSAgent::didRemoveDOMNode):
+        (WebCore::InspectorCSSAgent::clearPseudoState):
+        * inspector/InspectorCSSAgent.h:
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::disconnectFrontend):
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::forcePseudoStateImpl):
+        * inspector/InspectorInstrumentation.h:
+        (WebCore::InspectorInstrumentation::forcePseudoState):
+
 2011-08-16  Tony Chang  <t...@chromium.org>
 
         Unreviewed, rolling out r93114.

Modified: trunk/Source/WebCore/css/CSSStyleSelector.cpp (93121 => 93122)


--- trunk/Source/WebCore/css/CSSStyleSelector.cpp	2011-08-16 16:59:04 UTC (rev 93121)
+++ trunk/Source/WebCore/css/CSSStyleSelector.cpp	2011-08-16 17:15:06 UTC (rev 93122)
@@ -68,6 +68,7 @@
 #include "HTMLNames.h"
 #include "HTMLProgressElement.h"
 #include "HTMLTextAreaElement.h"
+#include "InspectorInstrumentation.h"
 #include "KeyframeList.h"
 #include "LinkHash.h"
 #include "LocaleToScriptMapping.h"
@@ -894,8 +895,6 @@
     m_ruleList = 0;
 
     m_fontDirty = false;
-
-    m_forcePseudoClassMask = DoNotForcePseudoClassMask;
 }
 
 static inline const AtomicString* linkAttribute(Node* node)
@@ -2031,12 +2030,12 @@
     }
 }
 
-PassRefPtr<CSSRuleList> CSSStyleSelector::styleRulesForElement(Element* e, unsigned rulesToInclude, unsigned forcePseudoClassMask)
+PassRefPtr<CSSRuleList> CSSStyleSelector::styleRulesForElement(Element* e, unsigned rulesToInclude)
 {
-    return pseudoStyleRulesForElement(e, NOPSEUDO, rulesToInclude, forcePseudoClassMask);
+    return pseudoStyleRulesForElement(e, NOPSEUDO, rulesToInclude);
 }
 
-PassRefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element* e, PseudoId pseudoId, unsigned rulesToInclude, unsigned forcePseudoClassMask)
+PassRefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element* e, PseudoId pseudoId, unsigned rulesToInclude)
 {
     if (!e || !e->document()->haveStylesheetsLoaded())
         return 0;
@@ -2045,7 +2044,6 @@
 
     initElement(e);
     initForStyleResolve(e, 0, pseudoId);
-    m_forcePseudoClassMask = forcePseudoClassMask;
 
     if (rulesToInclude & UAAndUserCSSRules) {
         int firstUARule = -1, lastUARule = -1;
@@ -2070,7 +2068,6 @@
     }
 
     m_checker.m_collectRulesOnly = false;
-    m_forcePseudoClassMask = DoNotForcePseudoClassMask;
    
     return m_ruleList.release();
 }
@@ -2093,7 +2090,7 @@
     }
 
     // Slow path.
-    SelectorMatch match = m_checker.checkSelector(ruleData.selector(), m_element, m_dynamicPseudo, false, false, m_forcePseudoClassMask, style(), m_parentNode ? m_parentNode->renderStyle() : 0);
+    SelectorMatch match = m_checker.checkSelector(ruleData.selector(), m_element, m_dynamicPseudo, false, false, style(), m_parentNode ? m_parentNode->renderStyle() : 0);
     if (match != SelectorMatches)
         return false;
     if (m_checker.m_pseudoStyle != NOPSEUDO && m_checker.m_pseudoStyle != m_dynamicPseudo)
@@ -2222,7 +2219,7 @@
 // * SelectorMatches         - the selector matches the element e
 // * SelectorFailsLocally    - the selector fails for the element e
 // * SelectorFailsCompletely - the selector fails for e and any sibling or ancestor of e
-CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, unsigned forcePseudoClassMask, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
+CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
 {
 #if ENABLE(SVG)
     // Spec: CSS2 selectors cannot be applied to the (conceptually) cloned DOM tree
@@ -2232,7 +2229,7 @@
 #endif
 
     // first selector has to match
-    if (!checkOneSelector(sel, e, dynamicPseudo, isSubSelector, encounteredLink, forcePseudoClassMask, elementStyle, elementParentStyle))
+    if (!checkOneSelector(sel, e, dynamicPseudo, isSubSelector, encounteredLink, elementStyle, elementParentStyle))
         return SelectorFailsLocally;
 
     // The rest of the selectors has to match
@@ -2266,7 +2263,7 @@
                 if (!n || !n->isElementNode())
                     return SelectorFailsCompletely;
                 e = static_cast<Element*>(n);
-                SelectorMatch match = checkSelector(sel, e, dynamicPseudo, false, encounteredLink, forcePseudoClassMask);
+                SelectorMatch match = checkSelector(sel, e, dynamicPseudo, false, encounteredLink);
                 if (match != SelectorFailsLocally)
                     return match;
             }
@@ -2277,7 +2274,7 @@
             if (!n || !n->isElementNode())
                 return SelectorFailsCompletely;
             e = static_cast<Element*>(n);
-            return checkSelector(sel, e, dynamicPseudo, false, encounteredLink, forcePseudoClassMask);
+            return checkSelector(sel, e, dynamicPseudo, false, encounteredLink);
         }
         case CSSSelector::DirectAdjacent:
         {
@@ -2293,7 +2290,7 @@
                 return SelectorFailsLocally;
             e = static_cast<Element*>(n);
             m_matchVisitedPseudoClass = false;
-            return checkSelector(sel, e, dynamicPseudo, false, encounteredLink, forcePseudoClassMask);
+            return checkSelector(sel, e, dynamicPseudo, false, encounteredLink);
         }
         case CSSSelector::IndirectAdjacent:
             if (!m_collectRulesOnly && e->parentNode() && e->parentNode()->isElementNode()) {
@@ -2309,7 +2306,7 @@
                     return SelectorFailsLocally;
                 e = static_cast<Element*>(n);
                 m_matchVisitedPseudoClass = false;
-                SelectorMatch match = checkSelector(sel, e, dynamicPseudo, false, encounteredLink, forcePseudoClassMask);
+                SelectorMatch match = checkSelector(sel, e, dynamicPseudo, false, encounteredLink);
                 if (match != SelectorFailsLocally)
                     return match;
             };
@@ -2321,14 +2318,14 @@
             if ((elementStyle || m_collectRulesOnly) && dynamicPseudo != NOPSEUDO && dynamicPseudo != SELECTION &&
                 !((RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER) && sel->m_match == CSSSelector::PseudoClass))
                 return SelectorFailsCompletely;
-            return checkSelector(sel, e, dynamicPseudo, true, encounteredLink, forcePseudoClassMask, elementStyle, elementParentStyle);
+            return checkSelector(sel, e, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle);
         case CSSSelector::ShadowDescendant:
         {
             Node* shadowHostNode = e->shadowAncestorNode();
             if (shadowHostNode == e || !shadowHostNode->isElementNode())
                 return SelectorFailsCompletely;
             e = static_cast<Element*>(shadowHostNode);
-            return checkSelector(sel, e, dynamicPseudo, false, encounteredLink, forcePseudoClassMask);
+            return checkSelector(sel, e, dynamicPseudo, false, encounteredLink);
         }
     }
 
@@ -2487,7 +2484,7 @@
     return false;
 }
 
-bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, unsigned forcePseudoClassMask, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
+bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
 {
     ASSERT(e);
     if (!e)
@@ -2529,7 +2526,7 @@
                 // the parser enforces that this never occurs
                 ASSERT(subSel->pseudoType() != CSSSelector::PseudoNot);
 
-                if (!checkOneSelector(subSel, e, dynamicPseudo, true, encounteredLink, forcePseudoClassMask, elementStyle, elementParentStyle))
+                if (!checkOneSelector(subSel, e, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle))
                     return true;
             }
         } else if (dynamicPseudo != NOPSEUDO && (RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER)) {
@@ -2541,28 +2538,8 @@
                 return !m_document->page()->focusController()->isActive();
         }
 
-        CSSSelector::PseudoType pseudoType = sel->pseudoType();
-
-        // Check forced pseudo class mask first.
-        if (forcePseudoClassMask != DoNotForcePseudoClassMask) {
-            switch (pseudoType) {
-            case CSSSelector::PseudoLink:
-                return forcePseudoClassMask & ForceLink;
-            case CSSSelector::PseudoVisited:
-                return forcePseudoClassMask & ForceVisited;
-            case CSSSelector::PseudoFocus:
-                return forcePseudoClassMask & ForceFocus;
-            case CSSSelector::PseudoHover:
-                return forcePseudoClassMask & ForceHover;
-            case CSSSelector::PseudoActive:
-                return forcePseudoClassMask & ForceActive;
-            default:
-                break;
-            }
-        }
- 
         // Normal element pseudo class checking.
-        switch (pseudoType) {
+        switch (sel->pseudoType()) {
             // Pseudo classes:
             case CSSSelector::PseudoNot:
                 break; // Already handled up above.
@@ -2858,7 +2835,7 @@
                 break;
             case CSSSelector::PseudoAny:
                 for (CSSSelector* selector = sel->selectorList()->first(); selector; selector = CSSSelectorList::next(selector)) {
-                    if (checkSelector(selector, e, dynamicPseudo, true, encounteredLink, forcePseudoClassMask, elementStyle, elementParentStyle) == SelectorMatches)
+                    if (checkSelector(selector, e, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle) == SelectorMatches)
                         return true;
                 }
                 break;
@@ -2879,7 +2856,7 @@
                 break;
             case CSSSelector::PseudoVisited:
                 if (e && e->isLink())
-                    return m_matchVisitedPseudoClass;
+                    return m_matchVisitedPseudoClass || InspectorInstrumentation::forcePseudoState(e, CSSSelector::PseudoVisited);
                 break;
             case CSSSelector::PseudoDrag: {
                 if (elementStyle)
@@ -2891,7 +2868,7 @@
                 break;
             }
             case CSSSelector::PseudoFocus:
-                if (e && e->focused() && e->document()->frame() && e->document()->frame()->selection()->isFocusedAndActive())
+                if (e && ((e->focused() && e->document()->frame() && e->document()->frame()->selection()->isFocusedAndActive()) || InspectorInstrumentation::forcePseudoState(e, CSSSelector::PseudoFocus)))
                     return true;
                 break;
             case CSSSelector::PseudoHover: {
@@ -2902,7 +2879,7 @@
                         elementStyle->setAffectedByHoverRules(true);
                     else if (e->renderStyle())
                         e->renderStyle()->setAffectedByHoverRules(true);
-                    if (e->hovered())
+                    if (e->hovered() || InspectorInstrumentation::forcePseudoState(e, CSSSelector::PseudoHover))
                         return true;
                 }
                 break;
@@ -2915,7 +2892,7 @@
                         elementStyle->setAffectedByActiveRules(true);
                     else if (e->renderStyle())
                         e->renderStyle()->setAffectedByActiveRules(true);
-                    if (e->active())
+                    if (e->active() || InspectorInstrumentation::forcePseudoState(e, CSSSelector::PseudoActive))
                         return true;
                 }
                 break;

Modified: trunk/Source/WebCore/css/CSSStyleSelector.h (93121 => 93122)


--- trunk/Source/WebCore/css/CSSStyleSelector.h	2011-08-16 16:59:04 UTC (rev 93121)
+++ trunk/Source/WebCore/css/CSSStyleSelector.h	2011-08-16 17:15:06 UTC (rev 93122)
@@ -134,16 +134,6 @@
         PassRefPtr<RenderStyle> styleForKeyframe(const RenderStyle*, const WebKitCSSKeyframeRule*, KeyframeValue&);
 
     public:
-        enum ForcePseudoClassFlags {
-            ForceNone = 0,
-            DoNotForcePseudoClassMask = 1 << 0,
-            ForceHover = 1 << 1,
-            ForceFocus = 1 << 2,
-            ForceActive = 1 << 3,
-            ForceLink = 1 << 4,
-            ForceVisited = 1 << 5
-        };
-
         // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
         enum CSSRuleFilter {
             UAAndUserCSSRules   = 1 << 1,
@@ -153,8 +143,8 @@
             AllButEmptyCSSRules = UAAndUserCSSRules | AuthorCSSRules | CrossOriginCSSRules,
             AllCSSRules         = AllButEmptyCSSRules | EmptyCSSRules,
         };
-        PassRefPtr<CSSRuleList> styleRulesForElement(Element*, unsigned rulesToInclude = AllButEmptyCSSRules, unsigned forcePseudoClassMask = DoNotForcePseudoClassMask);
-        PassRefPtr<CSSRuleList> pseudoStyleRulesForElement(Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules, unsigned forcePseudoClassMask = DoNotForcePseudoClassMask);
+        PassRefPtr<CSSRuleList> styleRulesForElement(Element*, unsigned rulesToInclude = AllButEmptyCSSRules);
+        PassRefPtr<CSSRuleList> pseudoStyleRulesForElement(Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules);
 
         // Given a CSS keyword in the range (xx-small to -webkit-xxx-large), this function will return
         // the correct font size scaled relative to the user's default (medium).
@@ -285,8 +275,8 @@
             SelectorChecker(Document*, bool strictParsing);
 
             bool checkSelector(CSSSelector*, Element*) const;
-            SelectorMatch checkSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, unsigned forcePseudoClassMask = DoNotForcePseudoClassMask, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
-            bool checkOneSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, unsigned forcePseudoClassMask, RenderStyle*, RenderStyle* elementParentStyle) const;
+            SelectorMatch checkSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
+            bool checkOneSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle*, RenderStyle* elementParentStyle) const;
             bool checkScrollbarPseudoClass(CSSSelector*, PseudoId& dynamicPseudo) const;
             static bool fastCheckSelector(const CSSSelector*, const Element*);
 
@@ -383,7 +373,6 @@
         CSSValue* m_lineHeightValue;
         bool m_fontDirty;
         bool m_matchAuthorAndUserStyles;
-        unsigned m_forcePseudoClassMask; // enum ForcePseudoClassFlags
         
         RefPtr<CSSFontSelector> m_fontSelector;
         Vector<CSSMutableStyleDeclaration*> m_additionalAttributeStyleDecls;

Modified: trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp (93121 => 93122)


--- trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp	2011-08-16 16:59:04 UTC (rev 93121)
+++ trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp	2011-08-16 17:15:06 UTC (rev 93122)
@@ -130,6 +130,14 @@
 
 namespace WebCore {
 
+enum ForcePseudoClassFlags {
+    PseudoNone = 0,
+    PseudoHover = 1 << 0,
+    PseudoFocus = 1 << 1,
+    PseudoActive = 1 << 2,
+    PseudoVisited = 1 << 3
+};
+
 static unsigned computePseudoClassMask(InspectorArray* pseudoClassArray)
 {
     DEFINE_STATIC_LOCAL(String, active, ("active"));
@@ -137,9 +145,9 @@
     DEFINE_STATIC_LOCAL(String, focus, ("focus"));
     DEFINE_STATIC_LOCAL(String, visited, ("visited"));
     if (!pseudoClassArray || !pseudoClassArray->length())
-        return CSSStyleSelector::DoNotForcePseudoClassMask;
+        return PseudoNone;
 
-    unsigned result = CSSStyleSelector::ForceNone;
+    unsigned result = PseudoNone;
     for (size_t i = 0; i < pseudoClassArray->length(); ++i) {
         RefPtr<InspectorValue> pseudoClassValue = pseudoClassArray->get(i);
         String pseudoClass;
@@ -147,13 +155,13 @@
         if (!success)
             continue;
         if (pseudoClass == active)
-            result |= CSSStyleSelector::ForceActive;
+            result |= PseudoActive;
         else if (pseudoClass == hover)
-            result |= CSSStyleSelector::ForceHover;
+            result |= PseudoHover;
         else if (pseudoClass == focus)
-            result |= CSSStyleSelector::ForceFocus;
+            result |= PseudoFocus;
         else if (pseudoClass == visited)
-            result |= CSSStyleSelector::ForceVisited;
+            result |= PseudoVisited;
     }
 
     return result;
@@ -186,6 +194,7 @@
 InspectorCSSAgent::InspectorCSSAgent(InstrumentingAgents* instrumentingAgents, InspectorDOMAgent* domAgent)
     : m_instrumentingAgents(instrumentingAgents)
     , m_domAgent(domAgent)
+    , m_lastPseudoState(0)
     , m_lastStyleSheetId(1)
     , m_lastRuleId(1)
     , m_lastStyleId(1)
@@ -203,6 +212,11 @@
     reset();
 }
 
+void InspectorCSSAgent::clearFrontend()
+{
+    clearPseudoState(true);
+}
+
 void InspectorCSSAgent::reset()
 {
     m_idToInspectorStyleSheet.clear();
@@ -211,6 +225,25 @@
     m_documentToInspectorStyleSheet.clear();
 }
 
+bool InspectorCSSAgent::forcePseudoState(Element* element, CSSSelector::PseudoType pseudoType)
+{
+    if (m_lastElementWithPseudoState != element)
+        return false;
+
+    switch (pseudoType) {
+    case CSSSelector::PseudoActive:
+        return m_lastPseudoState & PseudoActive;
+    case CSSSelector::PseudoFocus:
+        return m_lastPseudoState & PseudoFocus;
+    case CSSSelector::PseudoHover:
+        return m_lastPseudoState & PseudoHover;
+    case CSSSelector::PseudoVisited:
+        return m_lastPseudoState & PseudoVisited;
+    default:
+        return false;
+    }
+}
+
 void InspectorCSSAgent::getStylesForNode(ErrorString* errorString, int nodeId, const RefPtr<InspectorArray>* forcedPseudoClasses, RefPtr<InspectorObject>* result)
 {
     Element* element = elementForId(errorString, nodeId);
@@ -227,16 +260,22 @@
     RefPtr<InspectorStyle> computedInspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, 0);
     resultObject->setObject("computedStyle", computedInspectorStyle->buildObjectForStyle());
 
-    unsigned forcePseudoClassMask = computePseudoClassMask(forcedPseudoClasses ? forcedPseudoClasses->get() : 0);
+    unsigned forcePseudoState = computePseudoClassMask(forcedPseudoClasses ? forcedPseudoClasses->get() : 0);
+    bool needStyleRecalc = element != m_lastElementWithPseudoState || forcePseudoState != m_lastPseudoState;
+    m_lastPseudoState = forcePseudoState;
+    m_lastElementWithPseudoState = element;
+    if (needStyleRecalc)
+        element->ownerDocument()->styleSelectorChanged(RecalcStyleImmediately);
+
     CSSStyleSelector* selector = element->ownerDocument()->styleSelector();
-    RefPtr<CSSRuleList> matchedRules = selector->styleRulesForElement(element, CSSStyleSelector::AllCSSRules, forcePseudoClassMask);
+    RefPtr<CSSRuleList> matchedRules = selector->styleRulesForElement(element, CSSStyleSelector::AllCSSRules);
     resultObject->setArray("matchedCSSRules", buildArrayForRuleList(matchedRules.get()));
 
     resultObject->setArray("styleAttributes", buildArrayForAttributeStyles(element));
 
     RefPtr<InspectorArray> pseudoElements = InspectorArray::create();
     for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_INTERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) {
-        RefPtr<CSSRuleList> matchedRules = selector->pseudoStyleRulesForElement(element, pseudoId, CSSStyleSelector::AllCSSRules, forcePseudoClassMask);
+        RefPtr<CSSRuleList> matchedRules = selector->pseudoStyleRulesForElement(element, pseudoId, CSSStyleSelector::AllCSSRules);
         if (matchedRules && matchedRules->length()) {
             RefPtr<InspectorObject> pseudoStyles = InspectorObject::create();
             pseudoStyles->setNumber("pseudoId", static_cast<int>(pseudoId));
@@ -583,6 +622,7 @@
 {
     if (document)
         m_documentToInspectorStyleSheet.remove(document);
+    clearPseudoState(false);
 }
 
 void InspectorCSSAgent::didRemoveDOMNode(Node* node)
@@ -590,6 +630,11 @@
     if (!node)
         return;
 
+    if (m_lastElementWithPseudoState.get() == node) {
+        clearPseudoState(false);
+        return;
+    }
+
     NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(node);
     if (it == m_nodeToInspectorStyleSheet.end())
         return;
@@ -610,6 +655,18 @@
     it->second->didModifyElementAttribute();
 }
 
+void InspectorCSSAgent::clearPseudoState(bool recalcStyles)
+{
+    Element* element = m_lastElementWithPseudoState.get();
+    m_lastElementWithPseudoState = 0;
+    m_lastPseudoState = 0;
+    if (recalcStyles && element) {
+        Document* document = element->ownerDocument();
+        if (document)
+            document->styleSelectorChanged(RecalcStyleImmediately);
+    }
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(INSPECTOR)

Modified: trunk/Source/WebCore/inspector/InspectorCSSAgent.h (93121 => 93122)


--- trunk/Source/WebCore/inspector/InspectorCSSAgent.h	2011-08-16 16:59:04 UTC (rev 93121)
+++ trunk/Source/WebCore/inspector/InspectorCSSAgent.h	2011-08-16 17:15:06 UTC (rev 93122)
@@ -25,6 +25,7 @@
 #ifndef InspectorCSSAgent_h
 #define InspectorCSSAgent_h
 
+#include "CSSSelector.h"
 #include "InspectorDOMAgent.h"
 #include "InspectorStyleSheet.h"
 #include "InspectorValues.h"
@@ -60,7 +61,10 @@
     InspectorCSSAgent(InstrumentingAgents*, InspectorDOMAgent*);
     ~InspectorCSSAgent();
 
+    bool forcePseudoState(Element*, CSSSelector::PseudoType);
+    void clearFrontend();
     void reset();
+
     void getStylesForNode(ErrorString*, int nodeId, const RefPtr<InspectorArray>* forcedPseudoClasses, RefPtr<InspectorObject>* result);
     void getInlineStyleForNode(ErrorString*, int nodeId, RefPtr<InspectorObject>* style);
     void getComputedStyleForNode(ErrorString*, int nodeId, RefPtr<InspectorObject>* style);
@@ -99,8 +103,12 @@
     virtual void didRemoveDOMNode(Node*);
     virtual void didModifyDOMAttr(Element*);
 
+    void clearPseudoState(bool recalcStyles);
+
     InstrumentingAgents* m_instrumentingAgents;
     InspectorDOMAgent* m_domAgent;
+    RefPtr<Element> m_lastElementWithPseudoState;
+    unsigned m_lastPseudoState;
 
     IdToInspectorStyleSheet m_idToInspectorStyleSheet;
     CSSStyleSheetToInspectorStyleSheet m_cssStyleSheetToInspectorStyleSheet;

Modified: trunk/Source/WebCore/inspector/InspectorController.cpp (93121 => 93122)


--- trunk/Source/WebCore/inspector/InspectorController.cpp	2011-08-16 16:59:04 UTC (rev 93121)
+++ trunk/Source/WebCore/inspector/InspectorController.cpp	2011-08-16 17:15:06 UTC (rev 93122)
@@ -290,6 +290,7 @@
 #endif
     m_consoleAgent->clearFrontend();
     m_domAgent->clearFrontend();
+    m_cssAgent->clearFrontend();
     m_timelineAgent->clearFrontend();
     m_resourceAgent->clearFrontend();
 #if ENABLE(DATABASE)

Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp (93121 => 93122)


--- trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp	2011-08-16 16:59:04 UTC (rev 93121)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp	2011-08-16 17:15:06 UTC (rev 93122)
@@ -181,6 +181,13 @@
     return false;
 }
 
+bool InspectorInstrumentation::forcePseudoStateImpl(InstrumentingAgents* instrumentingAgents, Element* element, CSSSelector::PseudoType pseudoState)
+{
+    if (InspectorCSSAgent* cssAgent = instrumentingAgents->inspectorCSSAgent())
+        return cssAgent->forcePseudoState(element, pseudoState);
+    return false;
+}
+
 void InspectorInstrumentation::characterDataModifiedImpl(InstrumentingAgents* instrumentingAgents, CharacterData* characterData)
 {
     if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent())

Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.h (93121 => 93122)


--- trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2011-08-16 16:59:04 UTC (rev 93121)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2011-08-16 17:15:06 UTC (rev 93122)
@@ -31,8 +31,10 @@
 #ifndef InspectorInstrumentation_h
 #define InspectorInstrumentation_h
 
+#include "CSSSelector.h"
 #include "ConsoleTypes.h"
 #include "Document.h"
+#include "Element.h"
 #include "Frame.h"
 #include "Page.h"
 #include "ScriptExecutionContext.h"
@@ -86,6 +88,7 @@
 
     static void mouseDidMoveOverElement(Page*, const HitTestResult&, unsigned modifierFlags);
     static bool handleMousePress(Page*);
+    static bool forcePseudoState(Element*, CSSSelector::PseudoType);
 
     static void willSendXMLHttpRequest(ScriptExecutionContext*, const String& url);
     static void didScheduleResourceRequest(Document*, const String& url);
@@ -214,6 +217,7 @@
 
     static void mouseDidMoveOverElementImpl(InstrumentingAgents*, const HitTestResult&, unsigned modifierFlags);
     static bool handleMousePressImpl(InstrumentingAgents*);
+    static bool forcePseudoStateImpl(InstrumentingAgents*, Element*, CSSSelector::PseudoType);
 
     static void willSendXMLHttpRequestImpl(InstrumentingAgents*, const String& url);
     static void didScheduleResourceRequestImpl(InstrumentingAgents*, const String& url);
@@ -428,6 +432,16 @@
     return false;
 }
 
+inline bool InspectorInstrumentation::forcePseudoState(Element* element, CSSSelector::PseudoType pseudoState)
+{
+#if ENABLE(INSPECTOR)
+    FAST_RETURN_IF_NO_FRONTENDS(false);
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(element->document()))
+        return forcePseudoStateImpl(instrumentingAgents, element, pseudoState);
+#endif
+    return false;
+}
+
 inline void InspectorInstrumentation::characterDataModified(Document* document, CharacterData* characterData)
 {
 #if ENABLE(INSPECTOR)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to