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 #ifndef InspectorCSSAgent_h
     26 #define InspectorCSSAgent_h
     27 
     28 #include "core/css/CSSSelector.h"
     29 #include "core/dom/SecurityContext.h"
     30 #include "core/inspector/InspectorBaseAgent.h"
     31 #include "core/inspector/InspectorDOMAgent.h"
     32 #include "core/inspector/InspectorStyleSheet.h"
     33 #include "core/page/ContentSecurityPolicy.h"
     34 #include "core/platform/JSONValues.h"
     35 #include "wtf/HashMap.h"
     36 #include "wtf/HashSet.h"
     37 #include "wtf/PassRefPtr.h"
     38 #include "wtf/RefPtr.h"
     39 #include "wtf/Vector.h"
     40 #include "wtf/text/WTFString.h"
     41 
     42 namespace WebCore {
     43 
     44 class ChangeRegionOversetTask;
     45 struct CSSParserString;
     46 class CSSRule;
     47 class CSSRuleList;
     48 class CSSStyleRule;
     49 class CSSStyleSheet;
     50 class Document;
     51 class Element;
     52 class InspectorFrontend;
     53 class InstrumentingAgents;
     54 class MediaList;
     55 class Node;
     56 class NodeList;
     57 class StyleResolver;
     58 class UpdateRegionLayoutTask;
     59 
     60 typedef HashMap<CSSStyleSheet*, RefPtr<InspectorStyleSheet> > CSSStyleSheetToInspectorStyleSheet;
     61 typedef Vector<RefPtr<StyleSheet> > StyleSheetVector;
     62 
     63 class InspectorCSSAgent
     64     : public InspectorBaseAgent<InspectorCSSAgent>
     65     , public InspectorDOMAgent::DOMListener
     66     , public InspectorBackendDispatcher::CSSCommandHandler
     67     , public InspectorStyleSheet::Listener {
     68     WTF_MAKE_NONCOPYABLE(InspectorCSSAgent);
     69 public:
     70     enum MediaListSource {
     71         MediaListSourceLinkedSheet,
     72         MediaListSourceInlineSheet,
     73         MediaListSourceMediaRule,
     74         MediaListSourceImportRule
     75     };
     76 
     77     class InlineStyleOverrideScope {
     78     public:
     79         InlineStyleOverrideScope(SecurityContext* context)
     80             : m_contentSecurityPolicy(context->contentSecurityPolicy())
     81         {
     82             m_contentSecurityPolicy->setOverrideAllowInlineStyle(true);
     83         }
     84 
     85         ~InlineStyleOverrideScope()
     86         {
     87             m_contentSecurityPolicy->setOverrideAllowInlineStyle(false);
     88         }
     89 
     90     private:
     91         ContentSecurityPolicy* m_contentSecurityPolicy;
     92     };
     93 
     94     static CSSStyleRule* asCSSStyleRule(CSSRule*);
     95     static bool cssErrorFilter(const CSSParserString& content, int propertyId, int errorType);
     96 
     97     static PassOwnPtr<InspectorCSSAgent> create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InspectorDOMAgent* domAgent, InspectorPageAgent* pageAgent)
     98     {
     99         return adoptPtr(new InspectorCSSAgent(instrumentingAgents, state, domAgent, pageAgent));
    100     }
    101     ~InspectorCSSAgent();
    102 
    103     bool forcePseudoState(Element*, CSSSelector::PseudoType);
    104     virtual void setFrontend(InspectorFrontend*);
    105     virtual void clearFrontend();
    106     virtual void discardAgent();
    107     virtual void restore();
    108     virtual void enable(ErrorString*);
    109     virtual void disable(ErrorString*);
    110     void reset();
    111     void didCommitLoad(Frame*, DocumentLoader*);
    112     void mediaQueryResultChanged();
    113     void didCreateNamedFlow(Document*, NamedFlow*);
    114     void willRemoveNamedFlow(Document*, NamedFlow*);
    115 
    116 private:
    117     void regionLayoutUpdated(NamedFlow*, int documentNodeId);
    118     void regionOversetChanged(NamedFlow*, int documentNodeId);
    119 
    120 public:
    121     void didUpdateRegionLayout(Document*, NamedFlow*);
    122     void didChangeRegionOverset(Document*, NamedFlow*);
    123 
    124     void activeStyleSheetsUpdated(Document*, const StyleSheetVector& newSheets);
    125     void frameDetachedFromParent(Frame*);
    126 
    127     virtual void getComputedStyleForNode(ErrorString*, int nodeId, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> >&);
    128     virtual void getInlineStylesForNode(ErrorString*, int nodeId, RefPtr<TypeBuilder::CSS::CSSStyle>& inlineStyle, RefPtr<TypeBuilder::CSS::CSSStyle>& attributes);
    129     virtual void getMatchedStylesForNode(ErrorString*, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> >& matchedCSSRules, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> >& pseudoIdMatches, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> >& inheritedEntries);
    130     virtual void getAllStyleSheets(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSStyleSheetHeader> >& styleSheetInfos);
    131     virtual void getStyleSheet(ErrorString*, const String& styleSheetId, RefPtr<TypeBuilder::CSS::CSSStyleSheetBody>& result);
    132     virtual void getStyleSheetText(ErrorString*, const String& styleSheetId, String* result);
    133     virtual void setStyleSheetText(ErrorString*, const String& styleSheetId, const String& text);
    134     virtual void setStyleText(ErrorString*, const RefPtr<JSONObject>& styleId, const String& text, RefPtr<TypeBuilder::CSS::CSSStyle>& result);
    135     virtual void setPropertyText(ErrorString*, const RefPtr<JSONObject>& styleId, int propertyIndex, const String& text, bool overwrite, RefPtr<TypeBuilder::CSS::CSSStyle>& result);
    136     virtual void toggleProperty(ErrorString*, const RefPtr<JSONObject>& styleId, int propertyIndex, bool disable, RefPtr<TypeBuilder::CSS::CSSStyle>& result);
    137     virtual void setRuleSelector(ErrorString*, const RefPtr<JSONObject>& ruleId, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result);
    138     virtual void addRule(ErrorString*, int contextNodeId, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result);
    139     virtual void getSupportedCSSProperties(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSPropertyInfo> >& result);
    140     virtual void forcePseudoState(ErrorString*, int nodeId, const RefPtr<JSONArray>& forcedPseudoClasses);
    141     virtual void getNamedFlowCollection(ErrorString*, int documentNodeId, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::NamedFlow> >& result);
    142 
    143     PassRefPtr<TypeBuilder::CSS::CSSMedia> buildMediaObject(const MediaList*, MediaListSource, const String&, CSSStyleSheet*);
    144     PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> > buildMediaListChain(CSSRule*);
    145 
    146 private:
    147     class StyleSheetAction;
    148     class SetStyleSheetTextAction;
    149     class SetStyleTextAction;
    150     class SetPropertyTextAction;
    151     class TogglePropertyAction;
    152     class SetRuleSelectorAction;
    153     class AddRuleAction;
    154 
    155     InspectorCSSAgent(InstrumentingAgents*, InspectorCompositeState*, InspectorDOMAgent*, InspectorPageAgent*);
    156 
    157     typedef HashMap<String, RefPtr<InspectorStyleSheet> > IdToInspectorStyleSheet;
    158     typedef HashMap<Node*, RefPtr<InspectorStyleSheetForInlineStyle> > NodeToInspectorStyleSheet; // bogus "stylesheets" with elements' inline styles
    159     typedef HashMap<RefPtr<Document>, RefPtr<InspectorStyleSheet> > DocumentToViaInspectorStyleSheet; // "via inspector" stylesheets
    160     typedef HashMap<int, unsigned> NodeIdToForcedPseudoState;
    161 
    162     void resetNonPersistentData();
    163     InspectorStyleSheetForInlineStyle* asInspectorStyleSheet(Element* element);
    164     Element* elementForId(ErrorString*, int nodeId);
    165     int documentNodeWithRequestedFlowsId(Document*);
    166     void collectAllStyleSheets(Vector<InspectorStyleSheet*>&);
    167     void collectStyleSheets(CSSStyleSheet*, Vector<InspectorStyleSheet*>&);
    168 
    169     InspectorStyleSheet* bindStyleSheet(CSSStyleSheet*);
    170     String unbindStyleSheet(InspectorStyleSheet*);
    171     InspectorStyleSheet* viaInspectorStyleSheet(Document*, bool createIfAbsent);
    172     InspectorStyleSheet* assertStyleSheetForId(ErrorString*, const String&);
    173     TypeBuilder::CSS::StyleSheetOrigin::Enum detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument);
    174 
    175     PassRefPtr<TypeBuilder::CSS::CSSRule> buildObjectForRule(CSSStyleRule*, StyleResolver*);
    176     PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSRule> > buildArrayForRuleList(CSSRuleList*, StyleResolver*);
    177     PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > buildArrayForMatchedRuleList(CSSRuleList*, StyleResolver*, Element*);
    178     PassRefPtr<TypeBuilder::CSS::CSSStyle> buildObjectForAttributesStyle(Element*);
    179     PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::Region> > buildArrayForRegions(ErrorString*, PassRefPtr<NodeList>, int documentNodeId);
    180     PassRefPtr<TypeBuilder::CSS::NamedFlow> buildObjectForNamedFlow(ErrorString*, NamedFlow*, int documentNodeId);
    181 
    182     // InspectorDOMAgent::DOMListener implementation
    183     virtual void didRemoveDocument(Document*);
    184     virtual void didRemoveDOMNode(Node*);
    185     virtual void didModifyDOMAttr(Element*);
    186 
    187     // InspectorCSSAgent::Listener implementation
    188     virtual void styleSheetChanged(InspectorStyleSheet*) OVERRIDE;
    189     virtual void willReparseStyleSheet() OVERRIDE;
    190     virtual void didReparseStyleSheet() OVERRIDE;
    191 
    192     void resetPseudoStates();
    193 
    194     InspectorFrontend::CSS* m_frontend;
    195     InspectorDOMAgent* m_domAgent;
    196     InspectorPageAgent* m_pageAgent;
    197 
    198     IdToInspectorStyleSheet m_idToInspectorStyleSheet;
    199     CSSStyleSheetToInspectorStyleSheet m_cssStyleSheetToInspectorStyleSheet;
    200     NodeToInspectorStyleSheet m_nodeToInspectorStyleSheet;
    201     DocumentToViaInspectorStyleSheet m_documentToInspectorStyleSheet;
    202     NodeIdToForcedPseudoState m_nodeIdToForcedPseudoState;
    203     HashSet<int> m_namedFlowCollectionsRequested;
    204     OwnPtr<UpdateRegionLayoutTask> m_updateRegionLayoutTask;
    205     OwnPtr<ChangeRegionOversetTask> m_changeRegionOversetTask;
    206 
    207     int m_lastStyleSheetId;
    208     bool m_creatingViaInspectorStyleSheet;
    209     bool m_isSettingStyleSheetText;
    210 
    211     friend class ChangeRegionOversetTask;
    212     friend class StyleSheetBinder;
    213     friend class UpdateRegionLayoutTask;
    214 };
    215 
    216 
    217 } // namespace WebCore
    218 
    219 #endif // !defined(InspectorCSSAgent_h)
    220