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