Home | History | Annotate | Download | only in inspector
      1 /*
      2  * Copyright (C) 2010, Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      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.
     12  *
     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.
     23  */
     24 
     25 #include "config.h"
     26 #include "core/inspector/InspectorCSSAgent.h"
     27 
     28 #include "bindings/core/v8/ExceptionState.h"
     29 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
     30 #include "core/CSSPropertyNames.h"
     31 #include "core/InspectorTypeBuilder.h"
     32 #include "core/StylePropertyShorthand.h"
     33 #include "core/css/CSSComputedStyleDeclaration.h"
     34 #include "core/css/CSSDefaultStyleSheets.h"
     35 #include "core/css/CSSImportRule.h"
     36 #include "core/css/CSSMediaRule.h"
     37 #include "core/css/CSSRule.h"
     38 #include "core/css/CSSRuleList.h"
     39 #include "core/css/CSSStyleRule.h"
     40 #include "core/css/CSSStyleSheet.h"
     41 #include "core/css/MediaList.h"
     42 #include "core/css/MediaQuery.h"
     43 #include "core/css/MediaValues.h"
     44 #include "core/css/StylePropertySet.h"
     45 #include "core/css/StyleRule.h"
     46 #include "core/css/StyleSheet.h"
     47 #include "core/css/StyleSheetContents.h"
     48 #include "core/css/StyleSheetList.h"
     49 #include "core/css/resolver/StyleResolver.h"
     50 #include "core/dom/Node.h"
     51 #include "core/dom/StyleEngine.h"
     52 #include "core/dom/Text.h"
     53 #include "core/frame/LocalFrame.h"
     54 #include "core/html/HTMLHeadElement.h"
     55 #include "core/html/VoidCallback.h"
     56 #include "core/inspector/InspectorHistory.h"
     57 #include "core/inspector/InspectorPageAgent.h"
     58 #include "core/inspector/InspectorResourceAgent.h"
     59 #include "core/inspector/InspectorResourceContentLoader.h"
     60 #include "core/inspector/InspectorState.h"
     61 #include "core/inspector/InstrumentingAgents.h"
     62 #include "core/loader/DocumentLoader.h"
     63 #include "core/page/Page.h"
     64 #include "core/rendering/InlineTextBox.h"
     65 #include "core/rendering/RenderObject.h"
     66 #include "core/rendering/RenderObjectInlines.h"
     67 #include "core/rendering/RenderText.h"
     68 #include "core/rendering/RenderTextFragment.h"
     69 #include "platform/fonts/Font.h"
     70 #include "platform/fonts/GlyphBuffer.h"
     71 #include "platform/fonts/WidthIterator.h"
     72 #include "platform/text/TextRun.h"
     73 #include "wtf/CurrentTime.h"
     74 #include "wtf/text/CString.h"
     75 #include "wtf/text/StringConcatenate.h"
     76 
     77 namespace CSSAgentState {
     78 static const char cssAgentEnabled[] = "cssAgentEnabled";
     79 }
     80 
     81 typedef blink::InspectorBackendDispatcher::CSSCommandHandler::EnableCallback EnableCallback;
     82 
     83 namespace blink {
     84 
     85 enum ForcePseudoClassFlags {
     86     PseudoNone = 0,
     87     PseudoHover = 1 << 0,
     88     PseudoFocus = 1 << 1,
     89     PseudoActive = 1 << 2,
     90     PseudoVisited = 1 << 3
     91 };
     92 
     93 static unsigned computePseudoClassMask(JSONArray* pseudoClassArray)
     94 {
     95     DEFINE_STATIC_LOCAL(String, active, ("active"));
     96     DEFINE_STATIC_LOCAL(String, hover, ("hover"));
     97     DEFINE_STATIC_LOCAL(String, focus, ("focus"));
     98     DEFINE_STATIC_LOCAL(String, visited, ("visited"));
     99     if (!pseudoClassArray || !pseudoClassArray->length())
    100         return PseudoNone;
    101 
    102     unsigned result = PseudoNone;
    103     for (size_t i = 0; i < pseudoClassArray->length(); ++i) {
    104         RefPtr<JSONValue> pseudoClassValue = pseudoClassArray->get(i);
    105         String pseudoClass;
    106         bool success = pseudoClassValue->asString(&pseudoClass);
    107         if (!success)
    108             continue;
    109         if (pseudoClass == active)
    110             result |= PseudoActive;
    111         else if (pseudoClass == hover)
    112             result |= PseudoHover;
    113         else if (pseudoClass == focus)
    114             result |= PseudoFocus;
    115         else if (pseudoClass == visited)
    116             result |= PseudoVisited;
    117     }
    118 
    119     return result;
    120 }
    121 
    122 class InspectorCSSAgent::StyleSheetAction : public InspectorHistory::Action {
    123     WTF_MAKE_NONCOPYABLE(StyleSheetAction);
    124 public:
    125     StyleSheetAction(const String& name)
    126         : InspectorHistory::Action(name)
    127     {
    128     }
    129 };
    130 
    131 class InspectorCSSAgent::InspectorResourceContentLoaderCallback FINAL : public VoidCallback {
    132 public:
    133     InspectorResourceContentLoaderCallback(InspectorCSSAgent*, PassRefPtrWillBeRawPtr<EnableCallback>);
    134     virtual void trace(Visitor*) OVERRIDE;
    135     virtual void handleEvent() OVERRIDE;
    136 
    137 private:
    138     RawPtrWillBeMember<InspectorCSSAgent> m_cssAgent;
    139     RefPtrWillBeMember<EnableCallback> m_callback;
    140 };
    141 
    142 InspectorCSSAgent::InspectorResourceContentLoaderCallback::InspectorResourceContentLoaderCallback(InspectorCSSAgent* cssAgent, PassRefPtrWillBeRawPtr<EnableCallback> callback)
    143     : m_cssAgent(cssAgent)
    144     , m_callback(callback)
    145 {
    146 }
    147 
    148 void InspectorCSSAgent::InspectorResourceContentLoaderCallback::trace(Visitor* visitor)
    149 {
    150     visitor->trace(m_cssAgent);
    151     visitor->trace(m_callback);
    152     VoidCallback::trace(visitor);
    153 }
    154 
    155 void InspectorCSSAgent::InspectorResourceContentLoaderCallback::handleEvent()
    156 {
    157     // enable always succeeds.
    158     if (!m_callback->isActive())
    159         return;
    160 
    161     m_cssAgent->wasEnabled();
    162     m_callback->sendSuccess();
    163 }
    164 
    165 class InspectorCSSAgent::SetStyleSheetTextAction FINAL : public InspectorCSSAgent::StyleSheetAction {
    166     WTF_MAKE_NONCOPYABLE(SetStyleSheetTextAction);
    167 public:
    168     SetStyleSheetTextAction(InspectorStyleSheetBase* styleSheet, const String& text)
    169         : InspectorCSSAgent::StyleSheetAction("SetStyleSheetText")
    170         , m_styleSheet(styleSheet)
    171         , m_text(text)
    172     {
    173     }
    174 
    175     virtual bool perform(ExceptionState& exceptionState) OVERRIDE
    176     {
    177         if (!m_styleSheet->getText(&m_oldText))
    178             return false;
    179         return redo(exceptionState);
    180     }
    181 
    182     virtual bool undo(ExceptionState& exceptionState) OVERRIDE
    183     {
    184         return m_styleSheet->setText(m_oldText, exceptionState);
    185     }
    186 
    187     virtual bool redo(ExceptionState& exceptionState) OVERRIDE
    188     {
    189         return m_styleSheet->setText(m_text, exceptionState);
    190     }
    191 
    192     virtual String mergeId() OVERRIDE
    193     {
    194         return String::format("SetStyleSheetText %s", m_styleSheet->id().utf8().data());
    195     }
    196 
    197     virtual void merge(PassRefPtrWillBeRawPtr<Action> action) OVERRIDE
    198     {
    199         ASSERT(action->mergeId() == mergeId());
    200 
    201         SetStyleSheetTextAction* other = static_cast<SetStyleSheetTextAction*>(action.get());
    202         m_text = other->m_text;
    203     }
    204 
    205     virtual void trace(Visitor* visitor) OVERRIDE
    206     {
    207         visitor->trace(m_styleSheet);
    208         InspectorCSSAgent::StyleSheetAction::trace(visitor);
    209     }
    210 
    211 private:
    212     RefPtrWillBeMember<InspectorStyleSheetBase> m_styleSheet;
    213     String m_text;
    214     String m_oldText;
    215 };
    216 
    217 class InspectorCSSAgent::SetPropertyTextAction FINAL : public InspectorCSSAgent::StyleSheetAction {
    218     WTF_MAKE_NONCOPYABLE(SetPropertyTextAction);
    219 public:
    220     SetPropertyTextAction(InspectorStyleSheetBase* styleSheet, const InspectorCSSId& cssId, unsigned propertyIndex, const String& text, bool overwrite)
    221         : InspectorCSSAgent::StyleSheetAction("SetPropertyText")
    222         , m_styleSheet(styleSheet)
    223         , m_cssId(cssId)
    224         , m_propertyIndex(propertyIndex)
    225         , m_text(text)
    226         , m_overwrite(overwrite)
    227     {
    228     }
    229 
    230     virtual String toString() OVERRIDE
    231     {
    232         return mergeId() + ": " + m_oldStyleText + " -> " + m_text;
    233     }
    234 
    235     virtual bool perform(ExceptionState& exceptionState) OVERRIDE
    236     {
    237         return redo(exceptionState);
    238     }
    239 
    240     virtual bool undo(ExceptionState& exceptionState) OVERRIDE
    241     {
    242         String placeholder;
    243         return m_styleSheet->setStyleText(m_cssId, m_oldStyleText);
    244     }
    245 
    246     virtual bool redo(ExceptionState& exceptionState) OVERRIDE
    247     {
    248         if (!m_styleSheet->getStyleText(m_cssId, &m_oldStyleText))
    249             return false;
    250         bool result = m_styleSheet->setPropertyText(m_cssId, m_propertyIndex, m_text, m_overwrite, exceptionState);
    251         return result;
    252     }
    253 
    254     virtual String mergeId() OVERRIDE
    255     {
    256         return String::format("SetPropertyText %s:%u:%s", m_styleSheet->id().utf8().data(), m_propertyIndex, m_overwrite ? "true" : "false");
    257     }
    258 
    259     virtual void merge(PassRefPtrWillBeRawPtr<Action> action) OVERRIDE
    260     {
    261         ASSERT(action->mergeId() == mergeId());
    262 
    263         SetPropertyTextAction* other = static_cast<SetPropertyTextAction*>(action.get());
    264         m_text = other->m_text;
    265     }
    266 
    267     virtual void trace(Visitor* visitor) OVERRIDE
    268     {
    269         visitor->trace(m_styleSheet);
    270         InspectorCSSAgent::StyleSheetAction::trace(visitor);
    271     }
    272 
    273 private:
    274     RefPtrWillBeMember<InspectorStyleSheetBase> m_styleSheet;
    275     InspectorCSSId m_cssId;
    276     unsigned m_propertyIndex;
    277     String m_text;
    278     String m_oldStyleText;
    279     bool m_overwrite;
    280 };
    281 
    282 class InspectorCSSAgent::SetRuleSelectorAction FINAL : public InspectorCSSAgent::StyleSheetAction {
    283     WTF_MAKE_NONCOPYABLE(SetRuleSelectorAction);
    284 public:
    285     SetRuleSelectorAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, const String& selector)
    286         : InspectorCSSAgent::StyleSheetAction("SetRuleSelector")
    287         , m_styleSheet(styleSheet)
    288         , m_cssId(cssId)
    289         , m_selector(selector)
    290     {
    291     }
    292 
    293     virtual bool perform(ExceptionState& exceptionState) OVERRIDE
    294     {
    295         m_oldSelector = m_styleSheet->ruleSelector(m_cssId, exceptionState);
    296         if (exceptionState.hadException())
    297             return false;
    298         return redo(exceptionState);
    299     }
    300 
    301     virtual bool undo(ExceptionState& exceptionState) OVERRIDE
    302     {
    303         return m_styleSheet->setRuleSelector(m_cssId, m_oldSelector, exceptionState);
    304     }
    305 
    306     virtual bool redo(ExceptionState& exceptionState) OVERRIDE
    307     {
    308         return m_styleSheet->setRuleSelector(m_cssId, m_selector, exceptionState);
    309     }
    310 
    311     virtual void trace(Visitor* visitor) OVERRIDE
    312     {
    313         visitor->trace(m_styleSheet);
    314         InspectorCSSAgent::StyleSheetAction::trace(visitor);
    315     }
    316 
    317 private:
    318     RefPtrWillBeMember<InspectorStyleSheet> m_styleSheet;
    319     InspectorCSSId m_cssId;
    320     String m_selector;
    321     String m_oldSelector;
    322 };
    323 
    324 class InspectorCSSAgent::AddRuleAction FINAL : public InspectorCSSAgent::StyleSheetAction {
    325     WTF_MAKE_NONCOPYABLE(AddRuleAction);
    326 public:
    327     AddRuleAction(InspectorStyleSheet* styleSheet, const String& ruleText, const SourceRange& location)
    328         : InspectorCSSAgent::StyleSheetAction("AddRule")
    329         , m_styleSheet(styleSheet)
    330         , m_ruleText(ruleText)
    331         , m_location(location)
    332     {
    333     }
    334 
    335     virtual bool perform(ExceptionState& exceptionState) OVERRIDE
    336     {
    337         return redo(exceptionState);
    338     }
    339 
    340     virtual bool undo(ExceptionState& exceptionState) OVERRIDE
    341     {
    342         return m_styleSheet->deleteRule(m_newId, m_oldText, exceptionState);
    343     }
    344 
    345     virtual bool redo(ExceptionState& exceptionState) OVERRIDE
    346     {
    347         if (!m_styleSheet->getText(&m_oldText))
    348             return false;
    349         CSSStyleRule* cssStyleRule = m_styleSheet->addRule(m_ruleText, m_location, exceptionState);
    350         if (exceptionState.hadException())
    351             return false;
    352         m_newId = m_styleSheet->ruleId(cssStyleRule);
    353         return true;
    354     }
    355 
    356     InspectorCSSId newRuleId() { return m_newId; }
    357 
    358     virtual void trace(Visitor* visitor) OVERRIDE
    359     {
    360         visitor->trace(m_styleSheet);
    361         InspectorCSSAgent::StyleSheetAction::trace(visitor);
    362     }
    363 
    364 private:
    365     RefPtrWillBeMember<InspectorStyleSheet> m_styleSheet;
    366     InspectorCSSId m_newId;
    367     String m_ruleText;
    368     String m_oldText;
    369     SourceRange m_location;
    370 };
    371 
    372 // static
    373 CSSStyleRule* InspectorCSSAgent::asCSSStyleRule(CSSRule* rule)
    374 {
    375     if (!rule || rule->type() != CSSRule::STYLE_RULE)
    376         return 0;
    377     return toCSSStyleRule(rule);
    378 }
    379 
    380 InspectorCSSAgent::InspectorCSSAgent(InspectorDOMAgent* domAgent, InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent)
    381     : InspectorBaseAgent<InspectorCSSAgent>("CSS")
    382     , m_frontend(0)
    383     , m_domAgent(domAgent)
    384     , m_pageAgent(pageAgent)
    385     , m_resourceAgent(resourceAgent)
    386     , m_lastStyleSheetId(1)
    387     , m_styleSheetsPendingMutation(0)
    388     , m_styleDeclarationPendingMutation(false)
    389     , m_creatingViaInspectorStyleSheet(false)
    390     , m_isSettingStyleSheetText(false)
    391 {
    392     m_domAgent->setDOMListener(this);
    393 }
    394 
    395 InspectorCSSAgent::~InspectorCSSAgent()
    396 {
    397 #if !ENABLE(OILPAN)
    398     ASSERT(!m_domAgent);
    399     reset();
    400 #endif
    401 }
    402 
    403 void InspectorCSSAgent::setFrontend(InspectorFrontend* frontend)
    404 {
    405     ASSERT(!m_frontend);
    406     m_frontend = frontend->css();
    407 }
    408 
    409 void InspectorCSSAgent::clearFrontend()
    410 {
    411     ASSERT(m_frontend);
    412     ErrorString error;
    413     disable(&error);
    414     m_frontend = 0;
    415 }
    416 
    417 void InspectorCSSAgent::discardAgent()
    418 {
    419     m_domAgent->setDOMListener(0);
    420     m_domAgent = nullptr;
    421 }
    422 
    423 void InspectorCSSAgent::restore()
    424 {
    425     if (m_state->getBoolean(CSSAgentState::cssAgentEnabled))
    426         wasEnabled();
    427 }
    428 
    429 void InspectorCSSAgent::flushPendingFrontendMessages()
    430 {
    431     if (!m_invalidatedDocuments.size())
    432         return;
    433     WillBeHeapHashSet<RawPtrWillBeMember<Document> > invalidatedDocuments;
    434     m_invalidatedDocuments.swap(&invalidatedDocuments);
    435     for (WillBeHeapHashSet<RawPtrWillBeMember<Document> >::iterator it = invalidatedDocuments.begin(); it != invalidatedDocuments.end(); ++it)
    436         updateActiveStyleSheets(*it, ExistingFrontendRefresh);
    437 }
    438 
    439 void InspectorCSSAgent::reset()
    440 {
    441     m_idToInspectorStyleSheet.clear();
    442     m_idToInspectorStyleSheetForInlineStyle.clear();
    443     m_cssStyleSheetToInspectorStyleSheet.clear();
    444     m_documentToCSSStyleSheets.clear();
    445     m_invalidatedDocuments.clear();
    446     m_nodeToInspectorStyleSheet.clear();
    447     m_documentToViaInspectorStyleSheet.clear();
    448     resetNonPersistentData();
    449 }
    450 
    451 void InspectorCSSAgent::resetNonPersistentData()
    452 {
    453     resetPseudoStates();
    454 }
    455 
    456 void InspectorCSSAgent::enable(ErrorString*, PassRefPtrWillBeRawPtr<EnableCallback> prpCallback)
    457 {
    458     m_state->setBoolean(CSSAgentState::cssAgentEnabled, true);
    459     if (!m_pageAgent->resourceContentLoader()) {
    460         wasEnabled();
    461         prpCallback->sendSuccess();
    462         return;
    463     }
    464     m_pageAgent->resourceContentLoader()->ensureResourcesContentLoaded(new InspectorCSSAgent::InspectorResourceContentLoaderCallback(this, prpCallback));
    465 }
    466 
    467 void InspectorCSSAgent::wasEnabled()
    468 {
    469     if (!m_state->getBoolean(CSSAgentState::cssAgentEnabled)) {
    470         // We were disabled while fetching resources.
    471         return;
    472     }
    473 
    474     m_instrumentingAgents->setInspectorCSSAgent(this);
    475     WillBeHeapVector<RawPtrWillBeMember<Document> > documents = m_domAgent->documents();
    476     for (WillBeHeapVector<RawPtrWillBeMember<Document> >::iterator it = documents.begin(); it != documents.end(); ++it)
    477         updateActiveStyleSheets(*it, InitialFrontendLoad);
    478 }
    479 
    480 void InspectorCSSAgent::disable(ErrorString*)
    481 {
    482     reset();
    483     m_instrumentingAgents->setInspectorCSSAgent(0);
    484     m_state->setBoolean(CSSAgentState::cssAgentEnabled, false);
    485 }
    486 
    487 void InspectorCSSAgent::didCommitLoadForMainFrame()
    488 {
    489     reset();
    490     m_pageAgent->clearEditedResourcesContent();
    491 }
    492 
    493 void InspectorCSSAgent::mediaQueryResultChanged()
    494 {
    495     flushPendingFrontendMessages();
    496     m_frontend->mediaQueryResultChanged();
    497 }
    498 
    499 void InspectorCSSAgent::willMutateRules()
    500 {
    501     ++m_styleSheetsPendingMutation;
    502 }
    503 
    504 void InspectorCSSAgent::didMutateRules(CSSStyleSheet* styleSheet)
    505 {
    506     --m_styleSheetsPendingMutation;
    507     ASSERT(m_styleSheetsPendingMutation >= 0);
    508 
    509     if (!styleSheetEditInProgress()) {
    510         Document* owner = styleSheet->ownerDocument();
    511         if (owner)
    512             owner->modifiedStyleSheet(styleSheet, FullStyleUpdate);
    513     }
    514 }
    515 
    516 void InspectorCSSAgent::willMutateStyle()
    517 {
    518     m_styleDeclarationPendingMutation = true;
    519 }
    520 
    521 void InspectorCSSAgent::didMutateStyle(CSSStyleDeclaration* style, bool isInlineStyle)
    522 {
    523     ASSERT(m_styleDeclarationPendingMutation);
    524     m_styleDeclarationPendingMutation = false;
    525     if (!styleSheetEditInProgress() && !isInlineStyle) {
    526         CSSStyleSheet* parentSheet = style->parentStyleSheet();
    527         Document* owner = parentSheet ? parentSheet->ownerDocument() : 0;
    528         if (owner)
    529             owner->modifiedStyleSheet(parentSheet, FullStyleUpdate);
    530     }
    531 }
    532 
    533 void InspectorCSSAgent::activeStyleSheetsUpdated(Document* document)
    534 {
    535     if (styleSheetEditInProgress())
    536         return;
    537 
    538     m_invalidatedDocuments.add(document);
    539     if (m_creatingViaInspectorStyleSheet)
    540         flushPendingFrontendMessages();
    541 }
    542 
    543 void InspectorCSSAgent::updateActiveStyleSheets(Document* document, StyleSheetsUpdateType styleSheetsUpdateType)
    544 {
    545     WillBeHeapVector<RawPtrWillBeMember<CSSStyleSheet> > newSheetsVector;
    546     InspectorCSSAgent::collectAllDocumentStyleSheets(document, newSheetsVector);
    547     setActiveStyleSheets(document, newSheetsVector, styleSheetsUpdateType);
    548 }
    549 
    550 void InspectorCSSAgent::setActiveStyleSheets(Document* document, const WillBeHeapVector<RawPtrWillBeMember<CSSStyleSheet> >& allSheetsVector, StyleSheetsUpdateType styleSheetsUpdateType)
    551 {
    552     bool isInitialFrontendLoad = styleSheetsUpdateType == InitialFrontendLoad;
    553 
    554     WillBeHeapHashSet<RawPtrWillBeMember<CSSStyleSheet> >* documentCSSStyleSheets = m_documentToCSSStyleSheets.get(document);
    555     if (!documentCSSStyleSheets) {
    556         documentCSSStyleSheets = new WillBeHeapHashSet<RawPtrWillBeMember<CSSStyleSheet> >();
    557         OwnPtrWillBeRawPtr<WillBeHeapHashSet<RawPtrWillBeMember<CSSStyleSheet> > > documentCSSStyleSheetsPtr = adoptPtrWillBeNoop(documentCSSStyleSheets);
    558         m_documentToCSSStyleSheets.set(document, documentCSSStyleSheetsPtr.release());
    559     }
    560 
    561     WillBeHeapHashSet<RawPtrWillBeMember<CSSStyleSheet> > removedSheets(*documentCSSStyleSheets);
    562     WillBeHeapVector<RawPtrWillBeMember<CSSStyleSheet> > addedSheets;
    563     for (WillBeHeapVector<RawPtrWillBeMember<CSSStyleSheet> >::const_iterator it = allSheetsVector.begin(); it != allSheetsVector.end(); ++it) {
    564         CSSStyleSheet* cssStyleSheet = *it;
    565         if (removedSheets.contains(cssStyleSheet)) {
    566             removedSheets.remove(cssStyleSheet);
    567             if (isInitialFrontendLoad)
    568                 addedSheets.append(cssStyleSheet);
    569         } else {
    570             addedSheets.append(cssStyleSheet);
    571         }
    572     }
    573 
    574     for (WillBeHeapHashSet<RawPtrWillBeMember<CSSStyleSheet> >::iterator it = removedSheets.begin(); it != removedSheets.end(); ++it) {
    575         CSSStyleSheet* cssStyleSheet = *it;
    576         RefPtrWillBeRawPtr<InspectorStyleSheet> inspectorStyleSheet = m_cssStyleSheetToInspectorStyleSheet.get(cssStyleSheet);
    577         ASSERT(inspectorStyleSheet);
    578 
    579         documentCSSStyleSheets->remove(cssStyleSheet);
    580         if (m_idToInspectorStyleSheet.contains(inspectorStyleSheet->id())) {
    581             String id = unbindStyleSheet(inspectorStyleSheet.get());
    582             if (m_frontend && !isInitialFrontendLoad)
    583                 m_frontend->styleSheetRemoved(id);
    584         }
    585     }
    586 
    587     for (WillBeHeapVector<RawPtrWillBeMember<CSSStyleSheet> >::iterator it = addedSheets.begin(); it != addedSheets.end(); ++it) {
    588         CSSStyleSheet* cssStyleSheet = *it;
    589         bool isNew = isInitialFrontendLoad || !m_cssStyleSheetToInspectorStyleSheet.contains(cssStyleSheet);
    590         if (isNew) {
    591             InspectorStyleSheet* newStyleSheet = bindStyleSheet(cssStyleSheet);
    592             documentCSSStyleSheets->add(cssStyleSheet);
    593             if (m_frontend)
    594                 m_frontend->styleSheetAdded(newStyleSheet->buildObjectForStyleSheetInfo());
    595         }
    596     }
    597 
    598     if (documentCSSStyleSheets->isEmpty())
    599         m_documentToCSSStyleSheets.remove(document);
    600 }
    601 
    602 void InspectorCSSAgent::documentDetached(Document* document)
    603 {
    604     m_invalidatedDocuments.remove(document);
    605     setActiveStyleSheets(document, WillBeHeapVector<RawPtrWillBeMember<CSSStyleSheet> >(), ExistingFrontendRefresh);
    606 }
    607 
    608 bool InspectorCSSAgent::forcePseudoState(Element* element, CSSSelector::PseudoType pseudoType)
    609 {
    610     if (m_nodeIdToForcedPseudoState.isEmpty())
    611         return false;
    612 
    613     int nodeId = m_domAgent->boundNodeId(element);
    614     if (!nodeId)
    615         return false;
    616 
    617     NodeIdToForcedPseudoState::iterator it = m_nodeIdToForcedPseudoState.find(nodeId);
    618     if (it == m_nodeIdToForcedPseudoState.end())
    619         return false;
    620 
    621     unsigned forcedPseudoState = it->value;
    622     switch (pseudoType) {
    623     case CSSSelector::PseudoActive:
    624         return forcedPseudoState & PseudoActive;
    625     case CSSSelector::PseudoFocus:
    626         return forcedPseudoState & PseudoFocus;
    627     case CSSSelector::PseudoHover:
    628         return forcedPseudoState & PseudoHover;
    629     case CSSSelector::PseudoVisited:
    630         return forcedPseudoState & PseudoVisited;
    631     default:
    632         return false;
    633     }
    634 }
    635 
    636 void InspectorCSSAgent::getMediaQueries(ErrorString* errorString, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> >& medias)
    637 {
    638     medias = TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>::create();
    639     for (IdToInspectorStyleSheet::iterator it = m_idToInspectorStyleSheet.begin(); it != m_idToInspectorStyleSheet.end(); ++it) {
    640         RefPtrWillBeRawPtr<InspectorStyleSheet> styleSheet = it->value;
    641         collectMediaQueriesFromStyleSheet(styleSheet->pageStyleSheet(), medias.get());
    642         const CSSRuleVector& flatRules = styleSheet->flatRules();
    643         for (unsigned i = 0; i < flatRules.size(); ++i) {
    644             CSSRule* rule = flatRules.at(i).get();
    645             if (rule->type() == CSSRule::MEDIA_RULE)
    646                 collectMediaQueriesFromRule(rule, medias.get());
    647         }
    648     }
    649 }
    650 
    651 void InspectorCSSAgent::getMatchedStylesForNode(ErrorString* errorString, int nodeId, const bool* excludePseudo, const bool* excludeInherited, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> >& matchedCSSRules, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> >& pseudoIdMatches, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> >& inheritedEntries)
    652 {
    653     Element* element = elementForId(errorString, nodeId);
    654     if (!element) {
    655         *errorString = "Node not found";
    656         return;
    657     }
    658 
    659     Element* originalElement = element;
    660     PseudoId elementPseudoId = element->pseudoId();
    661     if (elementPseudoId) {
    662         element = element->parentOrShadowHostElement();
    663         if (!element) {
    664             *errorString = "Pseudo element has no parent";
    665             return;
    666         }
    667     }
    668 
    669     Document* ownerDocument = element->ownerDocument();
    670     // A non-active document has no styles.
    671     if (!ownerDocument->isActive())
    672         return;
    673 
    674     // FIXME: It's really gross for the inspector to reach in and access StyleResolver
    675     // directly here. We need to provide the Inspector better APIs to get this information
    676     // without grabbing at internal style classes!
    677 
    678     // Matched rules.
    679     StyleResolver& styleResolver = ownerDocument->ensureStyleResolver();
    680 
    681     RefPtrWillBeRawPtr<CSSRuleList> matchedRules = styleResolver.pseudoCSSRulesForElement(element, elementPseudoId, StyleResolver::AllCSSRules);
    682     matchedCSSRules = buildArrayForMatchedRuleList(matchedRules.get(), originalElement);
    683 
    684     // Pseudo elements.
    685     if (!elementPseudoId && !asBool(excludePseudo)) {
    686         RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> > pseudoElements = TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches>::create();
    687         for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_INTERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) {
    688             RefPtrWillBeRawPtr<CSSRuleList> matchedRules = styleResolver.pseudoCSSRulesForElement(element, pseudoId, StyleResolver::AllCSSRules);
    689             if (matchedRules && matchedRules->length()) {
    690                 RefPtr<TypeBuilder::CSS::PseudoIdMatches> matches = TypeBuilder::CSS::PseudoIdMatches::create()
    691                     .setPseudoId(static_cast<int>(pseudoId))
    692                     .setMatches(buildArrayForMatchedRuleList(matchedRules.get(), element));
    693                 pseudoElements->addItem(matches.release());
    694             }
    695         }
    696 
    697         pseudoIdMatches = pseudoElements.release();
    698     }
    699 
    700     // Inherited styles.
    701     if (!elementPseudoId && !asBool(excludeInherited)) {
    702         RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> > entries = TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry>::create();
    703         Element* parentElement = element->parentElement();
    704         while (parentElement) {
    705             StyleResolver& parentStyleResolver = parentElement->ownerDocument()->ensureStyleResolver();
    706             RefPtrWillBeRawPtr<CSSRuleList> parentMatchedRules = parentStyleResolver.cssRulesForElement(parentElement, StyleResolver::AllCSSRules);
    707             RefPtr<TypeBuilder::CSS::InheritedStyleEntry> entry = TypeBuilder::CSS::InheritedStyleEntry::create()
    708                 .setMatchedCSSRules(buildArrayForMatchedRuleList(parentMatchedRules.get(), parentElement));
    709             if (parentElement->style() && parentElement->style()->length()) {
    710                 InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyleSheet(parentElement);
    711                 if (styleSheet)
    712                     entry->setInlineStyle(styleSheet->buildObjectForStyle(styleSheet->styleForId(InspectorCSSId(styleSheet->id(), 0))));
    713             }
    714 
    715             entries->addItem(entry.release());
    716             parentElement = parentElement->parentElement();
    717         }
    718 
    719         inheritedEntries = entries.release();
    720     }
    721 }
    722 
    723 void InspectorCSSAgent::getInlineStylesForNode(ErrorString* errorString, int nodeId, RefPtr<TypeBuilder::CSS::CSSStyle>& inlineStyle, RefPtr<TypeBuilder::CSS::CSSStyle>& attributesStyle)
    724 {
    725     Element* element = elementForId(errorString, nodeId);
    726     if (!element)
    727         return;
    728 
    729     InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyleSheet(element);
    730     if (!styleSheet)
    731         return;
    732 
    733     inlineStyle = styleSheet->buildObjectForStyle(element->style());
    734     RefPtr<TypeBuilder::CSS::CSSStyle> attributes = buildObjectForAttributesStyle(element);
    735     attributesStyle = attributes ? attributes.release() : nullptr;
    736 }
    737 
    738 void InspectorCSSAgent::getComputedStyleForNode(ErrorString* errorString, int nodeId, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> >& style)
    739 {
    740     Node* node = m_domAgent->assertNode(errorString, nodeId);
    741     if (!node)
    742         return;
    743 
    744     RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> computedStyleInfo = CSSComputedStyleDeclaration::create(node, true);
    745     RefPtrWillBeRawPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, 0);
    746     style = inspectorStyle->buildArrayForComputedStyle();
    747 }
    748 
    749 void InspectorCSSAgent::collectPlatformFontsForRenderer(RenderText* renderer, HashCountedSet<String>* fontStats)
    750 {
    751     for (InlineTextBox* box = renderer->firstTextBox(); box; box = box->nextTextBox()) {
    752         RenderStyle* style = renderer->style(box->isFirstLineStyle());
    753         const Font& font = style->font();
    754         TextRun run = box->constructTextRunForInspector(style, font);
    755         WidthIterator it(&font, run, 0, false);
    756         GlyphBuffer glyphBuffer;
    757         it.advance(run.length(), &glyphBuffer);
    758         for (unsigned i = 0; i < glyphBuffer.size(); ++i) {
    759             String familyName = glyphBuffer.fontDataAt(i)->platformData().fontFamilyName();
    760             if (familyName.isNull())
    761                 familyName = "";
    762             fontStats->add(familyName);
    763         }
    764     }
    765 }
    766 
    767 void InspectorCSSAgent::getPlatformFontsForNode(ErrorString* errorString, int nodeId,
    768     String* cssFamilyName, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PlatformFontUsage> >& platformFonts)
    769 {
    770     Node* node = m_domAgent->assertNode(errorString, nodeId);
    771     if (!node)
    772         return;
    773 
    774     RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> computedStyleInfo = CSSComputedStyleDeclaration::create(node, true);
    775     *cssFamilyName = computedStyleInfo->getPropertyValue(CSSPropertyFontFamily);
    776 
    777     WillBeHeapVector<RawPtrWillBeMember<Text> > textNodes;
    778     if (node->nodeType() == Node::TEXT_NODE) {
    779         if (node->renderer())
    780             textNodes.append(toText(node));
    781     } else {
    782         for (Node* child = node->firstChild(); child; child = child->nextSibling()) {
    783             if (child->nodeType() == Node::TEXT_NODE && child->renderer())
    784                 textNodes.append(toText(child));
    785         }
    786     }
    787 
    788     HashCountedSet<String> fontStats;
    789     for (size_t i = 0; i < textNodes.size(); ++i) {
    790         RenderText* renderer = textNodes[i]->renderer();
    791         collectPlatformFontsForRenderer(renderer, &fontStats);
    792         if (renderer->isTextFragment()) {
    793             RenderTextFragment* textFragment = toRenderTextFragment(renderer);
    794             if (textFragment->firstLetter()) {
    795                 RenderBoxModelObject* firstLetter = textFragment->firstLetter();
    796                 for (RenderObject* current = firstLetter->slowFirstChild(); current; current = current->nextSibling()) {
    797                     if (current->isText())
    798                         collectPlatformFontsForRenderer(toRenderText(current), &fontStats);
    799                 }
    800             }
    801         }
    802     }
    803 
    804     platformFonts = TypeBuilder::Array<TypeBuilder::CSS::PlatformFontUsage>::create();
    805     for (HashCountedSet<String>::iterator it = fontStats.begin(), end = fontStats.end(); it != end; ++it) {
    806         RefPtr<TypeBuilder::CSS::PlatformFontUsage> platformFont = TypeBuilder::CSS::PlatformFontUsage::create()
    807             .setFamilyName(it->key)
    808             .setGlyphCount(it->value);
    809         platformFonts->addItem(platformFont);
    810     }
    811 }
    812 
    813 void InspectorCSSAgent::getStyleSheetText(ErrorString* errorString, const String& styleSheetId, String* result)
    814 {
    815     InspectorStyleSheetBase* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
    816     if (!inspectorStyleSheet)
    817         return;
    818 
    819     inspectorStyleSheet->getText(result);
    820 }
    821 
    822 void InspectorCSSAgent::setStyleSheetText(ErrorString* errorString, const String& styleSheetId, const String& text)
    823 {
    824     InspectorStyleSheetBase* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
    825     if (!inspectorStyleSheet) {
    826         *errorString = "Style sheet with id " + styleSheetId + " not found";
    827         return;
    828     }
    829 
    830     TrackExceptionState exceptionState;
    831     m_domAgent->history()->perform(adoptRefWillBeNoop(new SetStyleSheetTextAction(inspectorStyleSheet, text)), exceptionState);
    832     *errorString = InspectorDOMAgent::toErrorString(exceptionState);
    833 }
    834 
    835 static bool extractRangeComponent(ErrorString* errorString, const RefPtr<JSONObject>& range, const String& component, unsigned& result)
    836 {
    837     int parsedValue = 0;
    838     if (!range->getNumber(component, &parsedValue) || parsedValue < 0) {
    839         *errorString = "range." + component + " must be a non-negative integer";
    840         return false;
    841     }
    842     result = parsedValue;
    843     return true;
    844 }
    845 
    846 static bool jsonRangeToSourceRange(ErrorString* errorString, InspectorStyleSheetBase* inspectorStyleSheet, const RefPtr<JSONObject>& range, SourceRange* sourceRange)
    847 {
    848     unsigned startLineNumber = 0;
    849     unsigned startColumn = 0;
    850     unsigned endLineNumber = 0;
    851     unsigned endColumn = 0;
    852     if (!extractRangeComponent(errorString, range, "startLine", startLineNumber)
    853         || !extractRangeComponent(errorString, range, "startColumn", startColumn)
    854         || !extractRangeComponent(errorString, range, "endLine", endLineNumber)
    855         || !extractRangeComponent(errorString, range, "endColumn", endColumn))
    856         return false;
    857 
    858     unsigned startOffset = 0;
    859     unsigned endOffset = 0;
    860     bool success = inspectorStyleSheet->lineNumberAndColumnToOffset(startLineNumber, startColumn, &startOffset)
    861         && inspectorStyleSheet->lineNumberAndColumnToOffset(endLineNumber, endColumn, &endOffset);
    862     if (!success) {
    863         *errorString = "Specified range is out of bounds";
    864         return false;
    865     }
    866 
    867     if (startOffset > endOffset) {
    868         *errorString = "Range start must not succeed its end";
    869         return false;
    870     }
    871     sourceRange->start = startOffset;
    872     sourceRange->end = endOffset;
    873     return true;
    874 }
    875 
    876 void InspectorCSSAgent::setPropertyText(ErrorString* errorString, const String& styleSheetId, const RefPtr<JSONObject>& range, const String& text, RefPtr<TypeBuilder::CSS::CSSStyle>& result)
    877 {
    878     InspectorStyleSheetBase* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
    879     if (!inspectorStyleSheet)
    880         return;
    881     SourceRange propertyRange;
    882     if (!jsonRangeToSourceRange(errorString, inspectorStyleSheet, range, &propertyRange))
    883         return;
    884     InspectorCSSId compoundId;
    885     unsigned propertyIndex;
    886     bool overwrite;
    887     if (!inspectorStyleSheet->findPropertyByRange(propertyRange, &compoundId, &propertyIndex, &overwrite)) {
    888         *errorString = "Source range didn't match any existing property source range nor any property insertion point";
    889         return;
    890     }
    891 
    892     TrackExceptionState exceptionState;
    893     bool success = m_domAgent->history()->perform(adoptRefWillBeNoop(new SetPropertyTextAction(inspectorStyleSheet, compoundId, propertyIndex, text, overwrite)), exceptionState);
    894     if (success)
    895         result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
    896     *errorString = InspectorDOMAgent::toErrorString(exceptionState);
    897 }
    898 
    899 void InspectorCSSAgent::setRuleSelector(ErrorString* errorString, const String& styleSheetId, const RefPtr<JSONObject>& range, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result)
    900 {
    901     InspectorStyleSheet* inspectorStyleSheet = assertInspectorStyleSheetForId(errorString, styleSheetId);
    902     if (!inspectorStyleSheet)
    903         return;
    904     SourceRange selectorRange;
    905     if (!jsonRangeToSourceRange(errorString, inspectorStyleSheet, range, &selectorRange))
    906         return;
    907     InspectorCSSId compoundId;
    908     if (!inspectorStyleSheet->findRuleBySelectorRange(selectorRange, &compoundId)) {
    909         *errorString = "Source range didn't match any rule selector source range";
    910         return;
    911     }
    912 
    913     TrackExceptionState exceptionState;
    914     bool success = m_domAgent->history()->perform(adoptRefWillBeNoop(new SetRuleSelectorAction(inspectorStyleSheet, compoundId, selector)), exceptionState);
    915     if (success) {
    916         CSSStyleRule* rule = inspectorStyleSheet->ruleForId(compoundId);
    917         result = inspectorStyleSheet->buildObjectForRule(rule, buildMediaListChain(rule));
    918     }
    919     *errorString = InspectorDOMAgent::toErrorString(exceptionState);
    920 }
    921 
    922 void InspectorCSSAgent::createStyleSheet(ErrorString* errorString, const String& frameId, TypeBuilder::CSS::StyleSheetId* outStyleSheetId)
    923 {
    924     LocalFrame* frame = m_pageAgent->frameForId(frameId);
    925     if (!frame) {
    926         *errorString = "Frame not found";
    927         return;
    928     }
    929 
    930     Document* document = frame->document();
    931     if (!document) {
    932         *errorString = "Frame does not have a document";
    933         return;
    934     }
    935 
    936     InspectorStyleSheet* inspectorStyleSheet = viaInspectorStyleSheet(document, true);
    937     if (!inspectorStyleSheet) {
    938         *errorString = "No target stylesheet found";
    939         return;
    940     }
    941 
    942     updateActiveStyleSheets(document, ExistingFrontendRefresh);
    943 
    944     *outStyleSheetId = inspectorStyleSheet->id();
    945 }
    946 
    947 void InspectorCSSAgent::addRule(ErrorString* errorString, const String& styleSheetId, const String& ruleText, const RefPtr<JSONObject>& location, RefPtr<TypeBuilder::CSS::CSSRule>& result)
    948 {
    949     InspectorStyleSheet* inspectorStyleSheet = assertInspectorStyleSheetForId(errorString, styleSheetId);
    950     if (!inspectorStyleSheet)
    951         return;
    952     SourceRange ruleLocation;
    953     if (!jsonRangeToSourceRange(errorString, inspectorStyleSheet, location, &ruleLocation))
    954         return;
    955 
    956     TrackExceptionState exceptionState;
    957     RefPtrWillBeRawPtr<AddRuleAction> action = adoptRefWillBeNoop(new AddRuleAction(inspectorStyleSheet, ruleText, ruleLocation));
    958     bool success = m_domAgent->history()->perform(action, exceptionState);
    959     if (!success) {
    960         *errorString = InspectorDOMAgent::toErrorString(exceptionState);
    961         return;
    962     }
    963 
    964     InspectorCSSId ruleId = action->newRuleId();
    965     CSSStyleRule* rule = inspectorStyleSheet->ruleForId(ruleId);
    966     result = inspectorStyleSheet->buildObjectForRule(rule, buildMediaListChain(rule));
    967 }
    968 
    969 void InspectorCSSAgent::forcePseudoState(ErrorString* errorString, int nodeId, const RefPtr<JSONArray>& forcedPseudoClasses)
    970 {
    971     Element* element = m_domAgent->assertElement(errorString, nodeId);
    972     if (!element)
    973         return;
    974 
    975     unsigned forcedPseudoState = computePseudoClassMask(forcedPseudoClasses.get());
    976     NodeIdToForcedPseudoState::iterator it = m_nodeIdToForcedPseudoState.find(nodeId);
    977     unsigned currentForcedPseudoState = it == m_nodeIdToForcedPseudoState.end() ? 0 : it->value;
    978     bool needStyleRecalc = forcedPseudoState != currentForcedPseudoState;
    979     if (!needStyleRecalc)
    980         return;
    981 
    982     if (forcedPseudoState)
    983         m_nodeIdToForcedPseudoState.set(nodeId, forcedPseudoState);
    984     else
    985         m_nodeIdToForcedPseudoState.remove(nodeId);
    986     element->ownerDocument()->setNeedsStyleRecalc(SubtreeStyleChange);
    987 }
    988 
    989 PassRefPtr<TypeBuilder::CSS::CSSMedia> InspectorCSSAgent::buildMediaObject(const MediaList* media, MediaListSource mediaListSource, const String& sourceURL, CSSStyleSheet* parentStyleSheet)
    990 {
    991     // Make certain compilers happy by initializing |source| up-front.
    992     TypeBuilder::CSS::CSSMedia::Source::Enum source = TypeBuilder::CSS::CSSMedia::Source::InlineSheet;
    993     switch (mediaListSource) {
    994     case MediaListSourceMediaRule:
    995         source = TypeBuilder::CSS::CSSMedia::Source::MediaRule;
    996         break;
    997     case MediaListSourceImportRule:
    998         source = TypeBuilder::CSS::CSSMedia::Source::ImportRule;
    999         break;
   1000     case MediaListSourceLinkedSheet:
   1001         source = TypeBuilder::CSS::CSSMedia::Source::LinkedSheet;
   1002         break;
   1003     case MediaListSourceInlineSheet:
   1004         source = TypeBuilder::CSS::CSSMedia::Source::InlineSheet;
   1005         break;
   1006     }
   1007 
   1008     const MediaQuerySet* queries = media->queries();
   1009     const WillBeHeapVector<OwnPtrWillBeMember<MediaQuery> >& queryVector = queries->queryVector();
   1010     OwnPtr<MediaQueryEvaluator> mediaEvaluator = adoptPtr(new MediaQueryEvaluator(parentStyleSheet->ownerDocument()->frame()));
   1011 
   1012     RefPtr<TypeBuilder::Array<TypeBuilder::CSS::MediaQuery> > mediaListArray = TypeBuilder::Array<TypeBuilder::CSS::MediaQuery>::create();
   1013     RefPtr<MediaValues> mediaValues = MediaValues::createDynamicIfFrameExists(parentStyleSheet->ownerDocument()->frame());
   1014     bool hasMediaQueryItems = false;
   1015     for (size_t i = 0; i < queryVector.size(); ++i) {
   1016         MediaQuery* query = queryVector.at(i).get();
   1017         const ExpressionHeapVector& expressions = query->expressions();
   1018         RefPtr<TypeBuilder::Array<TypeBuilder::CSS::MediaQueryExpression> > expressionArray = TypeBuilder::Array<TypeBuilder::CSS::MediaQueryExpression>::create();
   1019         bool hasExpressionItems = false;
   1020         for (size_t j = 0; j < expressions.size(); ++j) {
   1021             MediaQueryExp* mediaQueryExp = expressions.at(j).get();
   1022             MediaQueryExpValue expValue = mediaQueryExp->expValue();
   1023             if (!expValue.isValue)
   1024                 continue;
   1025             const char* valueName = CSSPrimitiveValue::unitTypeToString(expValue.unit);
   1026             RefPtr<TypeBuilder::CSS::MediaQueryExpression> mediaQueryExpression = TypeBuilder::CSS::MediaQueryExpression::create()
   1027                 .setValue(expValue.value)
   1028                 .setUnit(String(valueName))
   1029                 .setFeature(mediaQueryExp->mediaFeature());
   1030 
   1031             int computedLength;
   1032             if (mediaValues->computeLength(expValue.value, expValue.unit, computedLength))
   1033                 mediaQueryExpression->setComputedLength(computedLength);
   1034 
   1035             expressionArray->addItem(mediaQueryExpression);
   1036             hasExpressionItems = true;
   1037         }
   1038         if (!hasExpressionItems)
   1039             continue;
   1040         RefPtr<TypeBuilder::CSS::MediaQuery> mediaQuery = TypeBuilder::CSS::MediaQuery::create()
   1041             .setActive(mediaEvaluator->eval(query, nullptr))
   1042             .setExpressions(expressionArray);
   1043         mediaListArray->addItem(mediaQuery);
   1044         hasMediaQueryItems = true;
   1045     }
   1046 
   1047     RefPtr<TypeBuilder::CSS::CSSMedia> mediaObject = TypeBuilder::CSS::CSSMedia::create()
   1048         .setText(media->mediaText())
   1049         .setSource(source);
   1050     if (hasMediaQueryItems)
   1051         mediaObject->setMediaList(mediaListArray);
   1052 
   1053     if (parentStyleSheet && mediaListSource != MediaListSourceLinkedSheet) {
   1054         if (InspectorStyleSheet* inspectorStyleSheet = m_cssStyleSheetToInspectorStyleSheet.get(parentStyleSheet))
   1055             mediaObject->setParentStyleSheetId(inspectorStyleSheet->id());
   1056     }
   1057 
   1058     if (!sourceURL.isEmpty()) {
   1059         mediaObject->setSourceURL(sourceURL);
   1060 
   1061         CSSRule* parentRule = media->parentRule();
   1062         if (!parentRule)
   1063             return mediaObject.release();
   1064         InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(parentRule->parentStyleSheet());
   1065         RefPtr<TypeBuilder::CSS::SourceRange> mediaRange = inspectorStyleSheet->ruleHeaderSourceRange(parentRule);
   1066         if (mediaRange)
   1067             mediaObject->setRange(mediaRange);
   1068     }
   1069     return mediaObject.release();
   1070 }
   1071 
   1072 bool InspectorCSSAgent::collectMediaQueriesFromStyleSheet(CSSStyleSheet* styleSheet, TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>* mediaArray)
   1073 {
   1074     bool addedItems = false;
   1075     MediaList* mediaList = styleSheet->media();
   1076     String sourceURL;
   1077     if (mediaList && mediaList->length()) {
   1078         Document* doc = styleSheet->ownerDocument();
   1079         if (doc)
   1080             sourceURL = doc->url();
   1081         else if (!styleSheet->contents()->baseURL().isEmpty())
   1082             sourceURL = styleSheet->contents()->baseURL();
   1083         else
   1084             sourceURL = "";
   1085         mediaArray->addItem(buildMediaObject(mediaList, styleSheet->ownerNode() ? MediaListSourceLinkedSheet : MediaListSourceInlineSheet, sourceURL, styleSheet));
   1086         addedItems = true;
   1087     }
   1088     return addedItems;
   1089 }
   1090 
   1091 bool InspectorCSSAgent::collectMediaQueriesFromRule(CSSRule* rule, TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>* mediaArray)
   1092 {
   1093     MediaList* mediaList;
   1094     String sourceURL;
   1095     CSSStyleSheet* parentStyleSheet = 0;
   1096     bool isMediaRule = true;
   1097     bool addedItems = false;
   1098     if (rule->type() == CSSRule::MEDIA_RULE) {
   1099         CSSMediaRule* mediaRule = toCSSMediaRule(rule);
   1100         mediaList = mediaRule->media();
   1101         parentStyleSheet = mediaRule->parentStyleSheet();
   1102     } else if (rule->type() == CSSRule::IMPORT_RULE) {
   1103         CSSImportRule* importRule = toCSSImportRule(rule);
   1104         mediaList = importRule->media();
   1105         parentStyleSheet = importRule->parentStyleSheet();
   1106         isMediaRule = false;
   1107     } else {
   1108         mediaList = 0;
   1109     }
   1110 
   1111     if (parentStyleSheet) {
   1112         sourceURL = parentStyleSheet->contents()->baseURL();
   1113         if (sourceURL.isEmpty())
   1114             sourceURL = InspectorDOMAgent::documentURLString(parentStyleSheet->ownerDocument());
   1115     } else {
   1116         sourceURL = "";
   1117     }
   1118 
   1119     if (mediaList && mediaList->length()) {
   1120         mediaArray->addItem(buildMediaObject(mediaList, isMediaRule ? MediaListSourceMediaRule : MediaListSourceImportRule, sourceURL, parentStyleSheet));
   1121         addedItems = true;
   1122     }
   1123     return addedItems;
   1124 }
   1125 
   1126 PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> > InspectorCSSAgent::buildMediaListChain(CSSRule* rule)
   1127 {
   1128     if (!rule)
   1129         return nullptr;
   1130     RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> > mediaArray = TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>::create();
   1131     bool hasItems = false;
   1132     CSSRule* parentRule = rule;
   1133     while (parentRule) {
   1134         hasItems = collectMediaQueriesFromRule(parentRule, mediaArray.get()) || hasItems;
   1135         if (parentRule->parentRule()) {
   1136             parentRule = parentRule->parentRule();
   1137         } else {
   1138             CSSStyleSheet* styleSheet = parentRule->parentStyleSheet();
   1139             while (styleSheet) {
   1140                 hasItems = collectMediaQueriesFromStyleSheet(styleSheet, mediaArray.get()) || hasItems;
   1141                 parentRule = styleSheet->ownerRule();
   1142                 if (parentRule)
   1143                     break;
   1144                 styleSheet = styleSheet->parentStyleSheet();
   1145             }
   1146         }
   1147     }
   1148     return hasItems ? mediaArray : nullptr;
   1149 }
   1150 
   1151 InspectorStyleSheetForInlineStyle* InspectorCSSAgent::asInspectorStyleSheet(Element* element)
   1152 {
   1153     NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(element);
   1154     if (it != m_nodeToInspectorStyleSheet.end())
   1155         return it->value.get();
   1156 
   1157     CSSStyleDeclaration* style = element->style();
   1158     if (!style)
   1159         return 0;
   1160 
   1161     String newStyleSheetId = String::number(m_lastStyleSheetId++);
   1162     RefPtrWillBeRawPtr<InspectorStyleSheetForInlineStyle> inspectorStyleSheet = InspectorStyleSheetForInlineStyle::create(newStyleSheetId, element, this);
   1163     m_idToInspectorStyleSheetForInlineStyle.set(newStyleSheetId, inspectorStyleSheet);
   1164     m_nodeToInspectorStyleSheet.set(element, inspectorStyleSheet);
   1165     return inspectorStyleSheet.get();
   1166 }
   1167 
   1168 Element* InspectorCSSAgent::elementForId(ErrorString* errorString, int nodeId)
   1169 {
   1170     Node* node = m_domAgent->nodeForId(nodeId);
   1171     if (!node) {
   1172         *errorString = "No node with given id found";
   1173         return 0;
   1174     }
   1175     if (!node->isElementNode()) {
   1176         *errorString = "Not an element node";
   1177         return 0;
   1178     }
   1179     return toElement(node);
   1180 }
   1181 
   1182 // static
   1183 void InspectorCSSAgent::collectAllDocumentStyleSheets(Document* document, WillBeHeapVector<RawPtrWillBeMember<CSSStyleSheet> >& result)
   1184 {
   1185     const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > activeStyleSheets = document->styleEngine()->activeStyleSheetsForInspector();
   1186     for (WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >::const_iterator it = activeStyleSheets.begin(); it != activeStyleSheets.end(); ++it) {
   1187         CSSStyleSheet* styleSheet = it->get();
   1188         InspectorCSSAgent::collectStyleSheets(styleSheet, result);
   1189     }
   1190 }
   1191 
   1192 // static
   1193 void InspectorCSSAgent::collectStyleSheets(CSSStyleSheet* styleSheet, WillBeHeapVector<RawPtrWillBeMember<CSSStyleSheet> >& result)
   1194 {
   1195     result.append(styleSheet);
   1196     for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) {
   1197         CSSRule* rule = styleSheet->item(i);
   1198         if (rule->type() == CSSRule::IMPORT_RULE) {
   1199             CSSStyleSheet* importedStyleSheet = toCSSImportRule(rule)->styleSheet();
   1200             if (importedStyleSheet)
   1201                 InspectorCSSAgent::collectStyleSheets(importedStyleSheet, result);
   1202         }
   1203     }
   1204 }
   1205 
   1206 InspectorStyleSheet* InspectorCSSAgent::bindStyleSheet(CSSStyleSheet* styleSheet)
   1207 {
   1208     RefPtrWillBeRawPtr<InspectorStyleSheet> inspectorStyleSheet = m_cssStyleSheetToInspectorStyleSheet.get(styleSheet);
   1209     if (!inspectorStyleSheet) {
   1210         String id = String::number(m_lastStyleSheetId++);
   1211         Document* document = styleSheet->ownerDocument();
   1212         inspectorStyleSheet = InspectorStyleSheet::create(m_pageAgent, m_resourceAgent, id, styleSheet, detectOrigin(styleSheet, document), InspectorDOMAgent::documentURLString(document), this);
   1213         m_idToInspectorStyleSheet.set(id, inspectorStyleSheet);
   1214         m_cssStyleSheetToInspectorStyleSheet.set(styleSheet, inspectorStyleSheet);
   1215         if (m_creatingViaInspectorStyleSheet)
   1216             m_documentToViaInspectorStyleSheet.add(document, inspectorStyleSheet);
   1217     }
   1218     return inspectorStyleSheet.get();
   1219 }
   1220 
   1221 String InspectorCSSAgent::unbindStyleSheet(InspectorStyleSheet* inspectorStyleSheet)
   1222 {
   1223     String id = inspectorStyleSheet->id();
   1224     m_idToInspectorStyleSheet.remove(id);
   1225     if (inspectorStyleSheet->pageStyleSheet())
   1226         m_cssStyleSheetToInspectorStyleSheet.remove(inspectorStyleSheet->pageStyleSheet());
   1227     return id;
   1228 }
   1229 
   1230 InspectorStyleSheet* InspectorCSSAgent::viaInspectorStyleSheet(Document* document, bool createIfAbsent)
   1231 {
   1232     if (!document) {
   1233         ASSERT(!createIfAbsent);
   1234         return 0;
   1235     }
   1236 
   1237     if (!document->isHTMLDocument() && !document->isSVGDocument())
   1238         return 0;
   1239 
   1240     RefPtrWillBeRawPtr<InspectorStyleSheet> inspectorStyleSheet = m_documentToViaInspectorStyleSheet.get(document);
   1241     if (inspectorStyleSheet || !createIfAbsent)
   1242         return inspectorStyleSheet.get();
   1243 
   1244     TrackExceptionState exceptionState;
   1245     RefPtrWillBeRawPtr<Element> styleElement = document->createElement("style", exceptionState);
   1246     if (!exceptionState.hadException())
   1247         styleElement->setAttribute("type", "text/css", exceptionState);
   1248     if (!exceptionState.hadException()) {
   1249         ContainerNode* targetNode;
   1250         // HEAD is absent in ImageDocuments, for example.
   1251         if (document->head())
   1252             targetNode = document->head();
   1253         else if (document->body())
   1254             targetNode = document->body();
   1255         else
   1256             return 0;
   1257 
   1258         InlineStyleOverrideScope overrideScope(document);
   1259         m_creatingViaInspectorStyleSheet = true;
   1260         targetNode->appendChild(styleElement, exceptionState);
   1261         // At this point the added stylesheet will get bound through the updateActiveStyleSheets() invocation.
   1262         // We just need to pick the respective InspectorStyleSheet from m_documentToViaInspectorStyleSheet.
   1263         m_creatingViaInspectorStyleSheet = false;
   1264     }
   1265     if (exceptionState.hadException())
   1266         return 0;
   1267 
   1268     return m_documentToViaInspectorStyleSheet.get(document);
   1269 }
   1270 
   1271 InspectorStyleSheet* InspectorCSSAgent::assertInspectorStyleSheetForId(ErrorString* errorString, const String& styleSheetId)
   1272 {
   1273     IdToInspectorStyleSheet::iterator it = m_idToInspectorStyleSheet.find(styleSheetId);
   1274     if (it == m_idToInspectorStyleSheet.end()) {
   1275         *errorString = "No style sheet with given id found";
   1276         return 0;
   1277     }
   1278     return it->value.get();
   1279 }
   1280 
   1281 InspectorStyleSheetBase* InspectorCSSAgent::assertStyleSheetForId(ErrorString* errorString, const String& styleSheetId)
   1282 {
   1283     String placeholder;
   1284     InspectorStyleSheetBase* result = assertInspectorStyleSheetForId(&placeholder, styleSheetId);
   1285     if (result)
   1286         return result;
   1287     IdToInspectorStyleSheetForInlineStyle::iterator it = m_idToInspectorStyleSheetForInlineStyle.find(styleSheetId);
   1288     if (it == m_idToInspectorStyleSheetForInlineStyle.end()) {
   1289         *errorString = "No style sheet with given id found";
   1290         return 0;
   1291     }
   1292     return it->value.get();
   1293 }
   1294 
   1295 TypeBuilder::CSS::StyleSheetOrigin::Enum InspectorCSSAgent::detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument)
   1296 {
   1297     if (m_creatingViaInspectorStyleSheet)
   1298         return TypeBuilder::CSS::StyleSheetOrigin::Inspector;
   1299 
   1300     TypeBuilder::CSS::StyleSheetOrigin::Enum origin = TypeBuilder::CSS::StyleSheetOrigin::Regular;
   1301     if (pageStyleSheet && !pageStyleSheet->ownerNode() && pageStyleSheet->href().isEmpty())
   1302         origin = TypeBuilder::CSS::StyleSheetOrigin::User_agent;
   1303     else if (pageStyleSheet && pageStyleSheet->ownerNode() && pageStyleSheet->ownerNode()->isDocumentNode())
   1304         origin = TypeBuilder::CSS::StyleSheetOrigin::User;
   1305     else {
   1306         InspectorStyleSheet* viaInspectorStyleSheetForOwner = viaInspectorStyleSheet(ownerDocument, false);
   1307         if (viaInspectorStyleSheetForOwner && pageStyleSheet == viaInspectorStyleSheetForOwner->pageStyleSheet())
   1308             origin = TypeBuilder::CSS::StyleSheetOrigin::Inspector;
   1309     }
   1310     return origin;
   1311 }
   1312 
   1313 PassRefPtr<TypeBuilder::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(CSSStyleRule* rule)
   1314 {
   1315     if (!rule)
   1316         return nullptr;
   1317 
   1318     // CSSRules returned by StyleResolver::pseudoCSSRulesForElement lack parent pointers if they are coming from
   1319     // user agent stylesheets. To work around this issue, we use CSSOM wrapper created by inspector.
   1320     if (!rule->parentStyleSheet()) {
   1321         if (!m_inspectorUserAgentStyleSheet)
   1322             m_inspectorUserAgentStyleSheet = CSSStyleSheet::create(CSSDefaultStyleSheets::instance().defaultStyleSheet());
   1323         rule->setParentStyleSheet(m_inspectorUserAgentStyleSheet.get());
   1324     }
   1325     return bindStyleSheet(rule->parentStyleSheet())->buildObjectForRule(rule, buildMediaListChain(rule));
   1326 }
   1327 
   1328 static inline bool matchesPseudoElement(const CSSSelector* selector, PseudoId elementPseudoId)
   1329 {
   1330     // According to http://www.w3.org/TR/css3-selectors/#pseudo-elements, "Only one pseudo-element may appear per selector."
   1331     // As such, check the last selector in the tag history.
   1332     for (; !selector->isLastInTagHistory(); ++selector) { }
   1333     PseudoId selectorPseudoId = selector->matchesPseudoElement() ? CSSSelector::pseudoId(selector->pseudoType()) : NOPSEUDO;
   1334 
   1335     // FIXME: This only covers the case of matching pseudo-element selectors against PseudoElements.
   1336     // We should come up with a solution for matching pseudo-element selectors against ordinary Elements, too.
   1337     return selectorPseudoId == elementPseudoId;
   1338 }
   1339 
   1340 PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > InspectorCSSAgent::buildArrayForMatchedRuleList(CSSRuleList* ruleList, Element* element)
   1341 {
   1342     RefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > result = TypeBuilder::Array<TypeBuilder::CSS::RuleMatch>::create();
   1343     if (!ruleList)
   1344         return result.release();
   1345 
   1346     for (unsigned i = 0, size = ruleList->length(); i < size; ++i) {
   1347         CSSStyleRule* rule = asCSSStyleRule(ruleList->item(i));
   1348         RefPtr<TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(rule);
   1349         if (!ruleObject)
   1350             continue;
   1351         RefPtr<TypeBuilder::Array<int> > matchingSelectors = TypeBuilder::Array<int>::create();
   1352         const CSSSelectorList& selectorList = rule->styleRule()->selectorList();
   1353         long index = 0;
   1354         PseudoId elementPseudoId = element->pseudoId();
   1355         for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector)) {
   1356             const CSSSelector* firstTagHistorySelector = selector;
   1357             bool matched = false;
   1358             if (elementPseudoId)
   1359                 matched = matchesPseudoElement(selector, elementPseudoId); // Modifies |selector|.
   1360             matched |= element->matches(firstTagHistorySelector->selectorText(), IGNORE_EXCEPTION);
   1361             if (matched)
   1362                 matchingSelectors->addItem(index);
   1363             ++index;
   1364         }
   1365         RefPtr<TypeBuilder::CSS::RuleMatch> match = TypeBuilder::CSS::RuleMatch::create()
   1366             .setRule(ruleObject.release())
   1367             .setMatchingSelectors(matchingSelectors.release());
   1368         result->addItem(match);
   1369     }
   1370 
   1371     return result;
   1372 }
   1373 
   1374 PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorCSSAgent::buildObjectForAttributesStyle(Element* element)
   1375 {
   1376     if (!element->isStyledElement())
   1377         return nullptr;
   1378 
   1379     // FIXME: Ugliness below.
   1380     StylePropertySet* attributeStyle = const_cast<StylePropertySet*>(element->presentationAttributeStyle());
   1381     if (!attributeStyle)
   1382         return nullptr;
   1383 
   1384     MutableStylePropertySet* mutableAttributeStyle = toMutableStylePropertySet(attributeStyle);
   1385 
   1386     RefPtrWillBeRawPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), mutableAttributeStyle->ensureCSSStyleDeclaration(), 0);
   1387     return inspectorStyle->buildObjectForStyle();
   1388 }
   1389 
   1390 void InspectorCSSAgent::didRemoveDocument(Document* document)
   1391 {
   1392     if (document)
   1393         m_documentToViaInspectorStyleSheet.remove(document);
   1394 }
   1395 
   1396 void InspectorCSSAgent::didRemoveDOMNode(Node* node)
   1397 {
   1398     if (!node)
   1399         return;
   1400 
   1401     int nodeId = m_domAgent->boundNodeId(node);
   1402     if (nodeId)
   1403         m_nodeIdToForcedPseudoState.remove(nodeId);
   1404 
   1405     NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(node);
   1406     if (it == m_nodeToInspectorStyleSheet.end())
   1407         return;
   1408 
   1409     m_idToInspectorStyleSheetForInlineStyle.remove(it->value->id());
   1410     m_nodeToInspectorStyleSheet.remove(node);
   1411 }
   1412 
   1413 void InspectorCSSAgent::didModifyDOMAttr(Element* element)
   1414 {
   1415     if (!element)
   1416         return;
   1417 
   1418     NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(element);
   1419     if (it == m_nodeToInspectorStyleSheet.end())
   1420         return;
   1421 
   1422     it->value->didModifyElementAttribute();
   1423 }
   1424 
   1425 void InspectorCSSAgent::styleSheetChanged(InspectorStyleSheetBase* styleSheet)
   1426 {
   1427     flushPendingFrontendMessages();
   1428     m_frontend->styleSheetChanged(styleSheet->id());
   1429 }
   1430 
   1431 void InspectorCSSAgent::willReparseStyleSheet()
   1432 {
   1433     ASSERT(!m_isSettingStyleSheetText);
   1434     m_isSettingStyleSheetText = true;
   1435 }
   1436 
   1437 void InspectorCSSAgent::didReparseStyleSheet()
   1438 {
   1439     ASSERT(m_isSettingStyleSheetText);
   1440     m_isSettingStyleSheetText = false;
   1441 }
   1442 
   1443 void InspectorCSSAgent::resetPseudoStates()
   1444 {
   1445     WillBeHeapHashSet<RawPtrWillBeMember<Document> > documentsToChange;
   1446     for (NodeIdToForcedPseudoState::iterator it = m_nodeIdToForcedPseudoState.begin(), end = m_nodeIdToForcedPseudoState.end(); it != end; ++it) {
   1447         Element* element = toElement(m_domAgent->nodeForId(it->key));
   1448         if (element && element->ownerDocument())
   1449             documentsToChange.add(element->ownerDocument());
   1450     }
   1451 
   1452     m_nodeIdToForcedPseudoState.clear();
   1453     for (WillBeHeapHashSet<RawPtrWillBeMember<Document> >::iterator it = documentsToChange.begin(), end = documentsToChange.end(); it != end; ++it)
   1454         (*it)->setNeedsStyleRecalc(SubtreeStyleChange);
   1455 }
   1456 
   1457 void InspectorCSSAgent::trace(Visitor* visitor)
   1458 {
   1459     visitor->trace(m_domAgent);
   1460     visitor->trace(m_pageAgent);
   1461     visitor->trace(m_resourceAgent);
   1462 #if ENABLE(OILPAN)
   1463     visitor->trace(m_idToInspectorStyleSheet);
   1464     visitor->trace(m_idToInspectorStyleSheetForInlineStyle);
   1465     visitor->trace(m_cssStyleSheetToInspectorStyleSheet);
   1466     visitor->trace(m_documentToCSSStyleSheets);
   1467     visitor->trace(m_invalidatedDocuments);
   1468     visitor->trace(m_nodeToInspectorStyleSheet);
   1469     visitor->trace(m_documentToViaInspectorStyleSheet);
   1470 #endif
   1471     visitor->trace(m_inspectorUserAgentStyleSheet);
   1472     InspectorBaseAgent::trace(visitor);
   1473 }
   1474 
   1475 } // namespace blink
   1476 
   1477