2 * Copyright (C) 2010, Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #include "InspectorCSSAgent.h"
30 #include "CSSComputedStyleDeclaration.h"
31 #include "CSSImportRule.h"
32 #include "CSSMutableStyleDeclaration.h"
33 #include "CSSPropertyNames.h"
34 #include "CSSPropertySourceData.h"
36 #include "CSSRuleList.h"
37 #include "CSSStyleRule.h"
38 #include "CSSStyleSelector.h"
39 #include "CSSStyleSheet.h"
40 #include "DOMWindow.h"
41 #include "HTMLHeadElement.h"
42 #include "InspectorDOMAgent.h"
43 #include "InspectorValues.h"
44 #include "InstrumentingAgents.h"
47 #include "StyleSheetList.h"
49 #include <wtf/HashSet.h>
50 #include <wtf/Vector.h>
51 #include <wtf/text/CString.h>
53 // Currently implemented model:
58 // priority : <string>, // "" for non-parsedOk properties
59 // implicit : <boolean>,
60 // parsedOk : <boolean>, // whether property is understood by WebCore
61 // status : <string>, // "disabled" | "active" | "inactive" | "style"
62 // shorthandName : <string>,
63 // startOffset : <number>, // Optional - property text start offset in enclosing style declaration. Absent for computed styles and such.
64 // endOffset : <number>, // Optional - property text end offset in enclosing style declaration. Absent for computed styles and such.
67 // name + value + priority : present when the property is enabled
68 // text : present when the property is disabled
70 // For disabled properties, startOffset === endOffset === insertion point for the property.
73 // "disabled" == property disabled by user
74 // "active" == property participates in the computed style calculation
75 // "inactive" == property does no participate in the computed style calculation (i.e. overridden by a subsequent property with the same name)
76 // "style" == property is active and originates from the WebCore CSSStyleDeclaration rather than CSS source code (e.g. implicit longhand properties)
79 // styleId : <string>, // Optional
85 // shorthandEntries : [
90 // cssText : <string>, // Optional - declaration text
94 // startOffset, // Optional - for source-based styles only
95 // endOffset, // Optional - for source-based styles only
105 // ruleId : <string>, // Optional
106 // selectorText : <string>,
107 // sourceURL : <string>,
108 // sourceLine : <string>,
109 // origin : <string>, // "" || "user-agent" || "user" || "inspector"
110 // style : #cssStyle,
111 // selectorRange: { start: <number>, end: <number> } // Optional - for source-based rules only
114 // cssStyleSheetInfo = {
115 // styleSheetId : <number>
116 // sourceURL : <string>
118 // disabled : <boolean>
122 // styleSheetId : <number>
128 // text : <string> // Optional - whenever the text is available for a text-based stylesheet
133 enum ForcePseudoClassFlags {
135 PseudoHover = 1 << 0,
136 PseudoFocus = 1 << 1,
137 PseudoActive = 1 << 2,
138 PseudoVisited = 1 << 3
141 static unsigned computePseudoClassMask(InspectorArray* pseudoClassArray)
143 DEFINE_STATIC_LOCAL(String, active, ("active"));
144 DEFINE_STATIC_LOCAL(String, hover, ("hover"));
145 DEFINE_STATIC_LOCAL(String, focus, ("focus"));
146 DEFINE_STATIC_LOCAL(String, visited, ("visited"));
147 if (!pseudoClassArray || !pseudoClassArray->length())
150 unsigned result = PseudoNone;
151 for (size_t i = 0; i < pseudoClassArray->length(); ++i) {
152 RefPtr<InspectorValue> pseudoClassValue = pseudoClassArray->get(i);
154 bool success = pseudoClassValue->asString(&pseudoClass);
157 if (pseudoClass == active)
158 result |= PseudoActive;
159 else if (pseudoClass == hover)
160 result |= PseudoHover;
161 else if (pseudoClass == focus)
162 result |= PseudoFocus;
163 else if (pseudoClass == visited)
164 result |= PseudoVisited;
171 CSSStyleSheet* InspectorCSSAgent::parentStyleSheet(StyleBase* styleBase)
176 StyleSheet* styleSheet = styleBase->stylesheet();
177 if (styleSheet && styleSheet->isCSSStyleSheet())
178 return static_cast<CSSStyleSheet*>(styleSheet);
184 CSSStyleRule* InspectorCSSAgent::asCSSStyleRule(StyleBase* styleBase)
186 if (!styleBase->isStyleRule())
188 CSSRule* rule = static_cast<CSSRule*>(styleBase);
189 if (rule->type() != CSSRule::STYLE_RULE)
191 return static_cast<CSSStyleRule*>(rule);
194 InspectorCSSAgent::InspectorCSSAgent(InstrumentingAgents* instrumentingAgents, InspectorDOMAgent* domAgent)
195 : m_instrumentingAgents(instrumentingAgents)
196 , m_domAgent(domAgent)
197 , m_lastPseudoState(0)
198 , m_lastStyleSheetId(1)
202 m_domAgent->setDOMListener(this);
203 m_instrumentingAgents->setInspectorCSSAgent(this);
206 InspectorCSSAgent::~InspectorCSSAgent()
208 m_instrumentingAgents->setInspectorCSSAgent(0);
209 // DOM agent should be destroyed after CSS agent.
210 m_domAgent->setDOMListener(0);
215 void InspectorCSSAgent::clearFrontend()
217 clearPseudoState(true);
220 void InspectorCSSAgent::reset()
222 m_idToInspectorStyleSheet.clear();
223 m_cssStyleSheetToInspectorStyleSheet.clear();
224 m_nodeToInspectorStyleSheet.clear();
225 m_documentToInspectorStyleSheet.clear();
228 bool InspectorCSSAgent::forcePseudoState(Element* element, CSSSelector::PseudoType pseudoType)
230 if (m_lastElementWithPseudoState != element)
233 switch (pseudoType) {
234 case CSSSelector::PseudoActive:
235 return m_lastPseudoState & PseudoActive;
236 case CSSSelector::PseudoFocus:
237 return m_lastPseudoState & PseudoFocus;
238 case CSSSelector::PseudoHover:
239 return m_lastPseudoState & PseudoHover;
240 case CSSSelector::PseudoVisited:
241 return m_lastPseudoState & PseudoVisited;
247 void InspectorCSSAgent::getStylesForNode(ErrorString* errorString, int nodeId, const RefPtr<InspectorArray>* forcedPseudoClasses, RefPtr<InspectorObject>* result)
249 Element* element = elementForId(errorString, nodeId);
253 RefPtr<InspectorObject> resultObject = InspectorObject::create();
255 InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyleSheet(element);
257 resultObject->setObject("inlineStyle", styleSheet->buildObjectForStyle(element->style()));
259 RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = computedStyle(element, true); // Support the viewing of :visited information in computed style.
260 RefPtr<InspectorStyle> computedInspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, 0);
261 resultObject->setObject("computedStyle", computedInspectorStyle->buildObjectForStyle());
263 unsigned forcePseudoState = computePseudoClassMask(forcedPseudoClasses ? forcedPseudoClasses->get() : 0);
264 bool needStyleRecalc = element != m_lastElementWithPseudoState || forcePseudoState != m_lastPseudoState;
265 m_lastPseudoState = forcePseudoState;
266 m_lastElementWithPseudoState = element;
268 element->ownerDocument()->styleSelectorChanged(RecalcStyleImmediately);
270 CSSStyleSelector* selector = element->ownerDocument()->styleSelector();
271 RefPtr<CSSRuleList> matchedRules = selector->styleRulesForElement(element, CSSStyleSelector::AllCSSRules);
272 resultObject->setArray("matchedCSSRules", buildArrayForRuleList(matchedRules.get()));
274 resultObject->setArray("styleAttributes", buildArrayForAttributeStyles(element));
276 RefPtr<InspectorArray> pseudoElements = InspectorArray::create();
277 for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_INTERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) {
278 RefPtr<CSSRuleList> matchedRules = selector->pseudoStyleRulesForElement(element, pseudoId, CSSStyleSelector::AllCSSRules);
279 if (matchedRules && matchedRules->length()) {
280 RefPtr<InspectorObject> pseudoStyles = InspectorObject::create();
281 pseudoStyles->setNumber("pseudoId", static_cast<int>(pseudoId));
282 pseudoStyles->setArray("rules", buildArrayForRuleList(matchedRules.get()));
283 pseudoElements->pushObject(pseudoStyles.release());
286 resultObject->setArray("pseudoElements", pseudoElements.release());
288 RefPtr<InspectorArray> inheritedStyles = InspectorArray::create();
289 Element* parentElement = element->parentElement();
290 while (parentElement) {
291 RefPtr<InspectorObject> parentStyle = InspectorObject::create();
292 if (parentElement->style() && parentElement->style()->length()) {
293 InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyleSheet(parentElement);
295 parentStyle->setObject("inlineStyle", styleSheet->buildObjectForStyle(styleSheet->styleForId(InspectorCSSId(styleSheet->id(), 0))));
298 CSSStyleSelector* parentSelector = parentElement->ownerDocument()->styleSelector();
299 RefPtr<CSSRuleList> parentMatchedRules = parentSelector->styleRulesForElement(parentElement, CSSStyleSelector::AllCSSRules);
300 parentStyle->setArray("matchedCSSRules", buildArrayForRuleList(parentMatchedRules.get()));
301 inheritedStyles->pushObject(parentStyle.release());
302 parentElement = parentElement->parentElement();
304 resultObject->setArray("inherited", inheritedStyles.release());
306 *result = resultObject.release();
309 void InspectorCSSAgent::getInlineStyleForNode(ErrorString* errorString, int nodeId, RefPtr<InspectorObject>* style)
311 Element* element = elementForId(errorString, nodeId);
315 InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyleSheet(element);
319 *style = styleSheet->buildObjectForStyle(element->style());
322 void InspectorCSSAgent::getComputedStyleForNode(ErrorString* errorString, int nodeId, RefPtr<InspectorObject>* style)
324 Element* element = elementForId(errorString, nodeId);
328 RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = computedStyle(element, true);
329 RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, 0);
330 *style = inspectorStyle->buildObjectForStyle();
333 void InspectorCSSAgent::getAllStyleSheets(ErrorString*, RefPtr<InspectorArray>* styleInfos)
335 Vector<Document*> documents = m_domAgent->documents();
336 for (Vector<Document*>::iterator it = documents.begin(); it != documents.end(); ++it) {
337 StyleSheetList* list = (*it)->styleSheets();
338 for (unsigned i = 0; i < list->length(); ++i) {
339 StyleSheet* styleSheet = list->item(i);
340 if (styleSheet->isCSSStyleSheet())
341 collectStyleSheets(static_cast<CSSStyleSheet*>(styleSheet), styleInfos->get());
346 void InspectorCSSAgent::getStyleSheet(ErrorString* errorString, const String& styleSheetId, RefPtr<InspectorObject>* styleSheetObject)
348 InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
349 if (!inspectorStyleSheet)
352 *styleSheetObject = inspectorStyleSheet->buildObjectForStyleSheet();
355 void InspectorCSSAgent::getStyleSheetText(ErrorString* errorString, const String& styleSheetId, String* result)
357 InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
358 if (!inspectorStyleSheet)
361 inspectorStyleSheet->text(result);
364 void InspectorCSSAgent::setStyleSheetText(ErrorString* errorString, const String& styleSheetId, const String& text)
366 InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
367 if (!inspectorStyleSheet)
370 if (inspectorStyleSheet->setText(text))
371 inspectorStyleSheet->reparseStyleSheet(text);
373 *errorString = "Internal error setting style sheet text";
376 void InspectorCSSAgent::setPropertyText(ErrorString* errorString, const RefPtr<InspectorObject>& fullStyleId, int propertyIndex, const String& text, bool overwrite, RefPtr<InspectorObject>* result)
378 InspectorCSSId compoundId(fullStyleId);
379 ASSERT(!compoundId.isEmpty());
381 InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
382 if (!inspectorStyleSheet)
385 bool success = inspectorStyleSheet->setPropertyText(errorString, compoundId, propertyIndex, text, overwrite);
387 *result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
390 void InspectorCSSAgent::toggleProperty(ErrorString* errorString, const RefPtr<InspectorObject>& fullStyleId, int propertyIndex, bool disable, RefPtr<InspectorObject>* result)
392 InspectorCSSId compoundId(fullStyleId);
393 ASSERT(!compoundId.isEmpty());
395 InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
396 if (!inspectorStyleSheet)
399 bool success = inspectorStyleSheet->toggleProperty(errorString, compoundId, propertyIndex, disable);
401 *result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
404 void InspectorCSSAgent::setRuleSelector(ErrorString* errorString, const RefPtr<InspectorObject>& fullRuleId, const String& selector, RefPtr<InspectorObject>* result)
406 InspectorCSSId compoundId(fullRuleId);
407 ASSERT(!compoundId.isEmpty());
409 InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
410 if (!inspectorStyleSheet)
413 bool success = inspectorStyleSheet->setRuleSelector(compoundId, selector);
417 *result = inspectorStyleSheet->buildObjectForRule(inspectorStyleSheet->ruleForId(compoundId));
420 void InspectorCSSAgent::addRule(ErrorString*, const int contextNodeId, const String& selector, RefPtr<InspectorObject>* result)
422 Node* node = m_domAgent->nodeForId(contextNodeId);
426 InspectorStyleSheet* inspectorStyleSheet = viaInspectorStyleSheet(node->document(), true);
427 if (!inspectorStyleSheet)
429 CSSStyleRule* newRule = inspectorStyleSheet->addRule(selector);
433 *result = inspectorStyleSheet->buildObjectForRule(newRule);
436 void InspectorCSSAgent::getSupportedCSSProperties(ErrorString*, RefPtr<InspectorArray>* cssProperties)
438 RefPtr<InspectorArray> properties = InspectorArray::create();
439 for (int i = 0; i < numCSSProperties; ++i)
440 properties->pushString(propertyNameStrings[i]);
442 *cssProperties = properties.release();
446 Element* InspectorCSSAgent::inlineStyleElement(CSSStyleDeclaration* style)
448 if (!style || !style->isMutableStyleDeclaration())
450 Node* node = static_cast<CSSMutableStyleDeclaration*>(style)->node();
451 if (!node || !node->isStyledElement() || static_cast<StyledElement*>(node)->getInlineStyleDecl() != style)
453 return static_cast<Element*>(node);
456 InspectorStyleSheetForInlineStyle* InspectorCSSAgent::asInspectorStyleSheet(Element* element)
458 NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(element);
459 if (it == m_nodeToInspectorStyleSheet.end()) {
460 CSSStyleDeclaration* style = element->isStyledElement() ? element->style() : 0;
464 String newStyleSheetId = String::number(m_lastStyleSheetId++);
465 RefPtr<InspectorStyleSheetForInlineStyle> inspectorStyleSheet = InspectorStyleSheetForInlineStyle::create(newStyleSheetId, element, "");
466 m_idToInspectorStyleSheet.set(newStyleSheetId, inspectorStyleSheet);
467 m_nodeToInspectorStyleSheet.set(element, inspectorStyleSheet);
468 return inspectorStyleSheet.get();
471 return it->second.get();
474 Element* InspectorCSSAgent::elementForId(ErrorString* errorString, int nodeId)
476 Node* node = m_domAgent->nodeForId(nodeId);
478 *errorString = "No node with given id found";
481 if (node->nodeType() != Node::ELEMENT_NODE) {
482 *errorString = "Not an element node";
485 return static_cast<Element*>(node);
488 void InspectorCSSAgent::collectStyleSheets(CSSStyleSheet* styleSheet, InspectorArray* result)
490 InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(static_cast<CSSStyleSheet*>(styleSheet));
491 result->pushObject(inspectorStyleSheet->buildObjectForStyleSheetInfo());
492 for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) {
493 StyleBase* styleBase = styleSheet->item(i);
494 if (styleBase->isImportRule()) {
495 StyleBase* importedStyleSheet = static_cast<CSSImportRule*>(styleBase)->styleSheet();
496 if (importedStyleSheet && importedStyleSheet->isCSSStyleSheet())
497 collectStyleSheets(static_cast<CSSStyleSheet*>(importedStyleSheet), result);
502 InspectorStyleSheet* InspectorCSSAgent::bindStyleSheet(CSSStyleSheet* styleSheet)
504 RefPtr<InspectorStyleSheet> inspectorStyleSheet = m_cssStyleSheetToInspectorStyleSheet.get(styleSheet);
505 if (!inspectorStyleSheet) {
506 String id = String::number(m_lastStyleSheetId++);
507 inspectorStyleSheet = InspectorStyleSheet::create(id, styleSheet, detectOrigin(styleSheet, styleSheet->document()), m_domAgent->documentURLString(styleSheet->document()));
508 m_idToInspectorStyleSheet.set(id, inspectorStyleSheet);
509 m_cssStyleSheetToInspectorStyleSheet.set(styleSheet, inspectorStyleSheet);
511 return inspectorStyleSheet.get();
514 InspectorStyleSheet* InspectorCSSAgent::viaInspectorStyleSheet(Document* document, bool createIfAbsent)
517 ASSERT(!createIfAbsent);
521 RefPtr<InspectorStyleSheet> inspectorStyleSheet = m_documentToInspectorStyleSheet.get(document);
522 if (inspectorStyleSheet || !createIfAbsent)
523 return inspectorStyleSheet.get();
525 ExceptionCode ec = 0;
526 RefPtr<Element> styleElement = document->createElement("style", ec);
528 styleElement->setAttribute("type", "text/css", ec);
530 ContainerNode* targetNode;
531 // HEAD is absent in ImageDocuments, for example.
532 if (document->head())
533 targetNode = document->head();
534 else if (document->body())
535 targetNode = document->body();
538 targetNode->appendChild(styleElement, ec);
542 StyleSheetList* styleSheets = document->styleSheets();
543 StyleSheet* styleSheet = styleSheets->item(styleSheets->length() - 1);
544 if (!styleSheet->isCSSStyleSheet())
546 CSSStyleSheet* cssStyleSheet = static_cast<CSSStyleSheet*>(styleSheet);
547 String id = String::number(m_lastStyleSheetId++);
548 inspectorStyleSheet = InspectorStyleSheet::create(id, cssStyleSheet, "inspector", m_domAgent->documentURLString(document));
549 m_idToInspectorStyleSheet.set(id, inspectorStyleSheet);
550 m_cssStyleSheetToInspectorStyleSheet.set(cssStyleSheet, inspectorStyleSheet);
551 m_documentToInspectorStyleSheet.set(document, inspectorStyleSheet);
552 return inspectorStyleSheet.get();
555 InspectorStyleSheet* InspectorCSSAgent::assertStyleSheetForId(ErrorString* errorString, const String& styleSheetId)
557 IdToInspectorStyleSheet::iterator it = m_idToInspectorStyleSheet.find(styleSheetId);
558 if (it == m_idToInspectorStyleSheet.end()) {
559 *errorString = "No style sheet with given id found";
562 return it->second.get();
565 String InspectorCSSAgent::detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument)
567 DEFINE_STATIC_LOCAL(String, userAgent, ("user-agent"));
568 DEFINE_STATIC_LOCAL(String, user, ("user"));
569 DEFINE_STATIC_LOCAL(String, inspector, ("inspector"));
572 if (pageStyleSheet && !pageStyleSheet->ownerNode() && pageStyleSheet->href().isEmpty())
574 else if (pageStyleSheet && pageStyleSheet->ownerNode() && pageStyleSheet->ownerNode()->nodeName() == "#document")
577 InspectorStyleSheet* viaInspectorStyleSheetForOwner = viaInspectorStyleSheet(ownerDocument, false);
578 if (viaInspectorStyleSheetForOwner && pageStyleSheet == viaInspectorStyleSheetForOwner->pageStyleSheet())
584 PassRefPtr<InspectorArray> InspectorCSSAgent::buildArrayForRuleList(CSSRuleList* ruleList)
586 RefPtr<InspectorArray> result = InspectorArray::create();
588 return result.release();
590 for (unsigned i = 0, size = ruleList->length(); i < size; ++i) {
591 CSSStyleRule* rule = asCSSStyleRule(ruleList->item(i));
595 InspectorStyleSheet* styleSheet = bindStyleSheet(parentStyleSheet(rule));
597 result->pushObject(styleSheet->buildObjectForRule(rule));
599 return result.release();
602 PassRefPtr<InspectorArray> InspectorCSSAgent::buildArrayForAttributeStyles(Element* element)
604 RefPtr<InspectorArray> attrStyles = InspectorArray::create();
605 NamedNodeMap* attributes = element->attributes();
606 for (unsigned i = 0; attributes && i < attributes->length(); ++i) {
607 Attribute* attribute = attributes->attributeItem(i);
608 if (attribute->style()) {
609 RefPtr<InspectorObject> attrStyleObject = InspectorObject::create();
610 String attributeName = attribute->localName();
611 RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), attribute->style(), 0);
612 attrStyleObject->setString("name", attributeName.utf8().data());
613 attrStyleObject->setObject("style", inspectorStyle->buildObjectForStyle());
614 attrStyles->pushObject(attrStyleObject.release());
618 return attrStyles.release();
621 void InspectorCSSAgent::didRemoveDocument(Document* document)
624 m_documentToInspectorStyleSheet.remove(document);
625 clearPseudoState(false);
628 void InspectorCSSAgent::didRemoveDOMNode(Node* node)
633 if (m_lastElementWithPseudoState.get() == node) {
634 clearPseudoState(false);
638 NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(node);
639 if (it == m_nodeToInspectorStyleSheet.end())
642 m_idToInspectorStyleSheet.remove(it->second->id());
643 m_nodeToInspectorStyleSheet.remove(node);
646 void InspectorCSSAgent::didModifyDOMAttr(Element* element)
651 NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(element);
652 if (it == m_nodeToInspectorStyleSheet.end())
655 it->second->didModifyElementAttribute();
658 void InspectorCSSAgent::clearPseudoState(bool recalcStyles)
660 RefPtr<Element> element = m_lastElementWithPseudoState;
661 m_lastElementWithPseudoState = 0;
662 m_lastPseudoState = 0;
663 if (recalcStyles && element) {
664 Document* document = element->ownerDocument();
666 document->styleSelectorChanged(RecalcStyleImmediately);
670 } // namespace WebCore
672 #endif // ENABLE(INSPECTOR)