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/frame/csp/ContentSecurityPolicy.h" 31 #include "core/inspector/InspectorBaseAgent.h" 32 #include "core/inspector/InspectorDOMAgent.h" 33 #include "core/inspector/InspectorStyleSheet.h" 34 #include "platform/JSONValues.h" 35 #include "wtf/HashCountedSet.h" 36 #include "wtf/HashMap.h" 37 #include "wtf/HashSet.h" 38 #include "wtf/PassRefPtr.h" 39 #include "wtf/RefPtr.h" 40 #include "wtf/Vector.h" 41 #include "wtf/text/WTFString.h" 42 43 namespace WebCore { 44 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 InspectorResourceAgent; 54 class InstrumentingAgents; 55 class MediaList; 56 class Node; 57 class PlatformFontUsage; 58 class RenderText; 59 class StyleResolver; 60 61 class InspectorCSSAgent FINAL 62 : public InspectorBaseAgent<InspectorCSSAgent> 63 , public InspectorDOMAgent::DOMListener 64 , public InspectorBackendDispatcher::CSSCommandHandler 65 , public InspectorStyleSheetBase::Listener { 66 WTF_MAKE_NONCOPYABLE(InspectorCSSAgent); 67 public: 68 enum MediaListSource { 69 MediaListSourceLinkedSheet, 70 MediaListSourceInlineSheet, 71 MediaListSourceMediaRule, 72 MediaListSourceImportRule 73 }; 74 75 enum StyleSheetsUpdateType { 76 InitialFrontendLoad = 0, 77 ExistingFrontendRefresh, 78 }; 79 80 class InlineStyleOverrideScope { 81 public: 82 InlineStyleOverrideScope(SecurityContext* context) 83 : m_contentSecurityPolicy(context->contentSecurityPolicy()) 84 { 85 m_contentSecurityPolicy->setOverrideAllowInlineStyle(true); 86 } 87 88 ~InlineStyleOverrideScope() 89 { 90 m_contentSecurityPolicy->setOverrideAllowInlineStyle(false); 91 } 92 93 private: 94 ContentSecurityPolicy* m_contentSecurityPolicy; 95 }; 96 97 static CSSStyleRule* asCSSStyleRule(CSSRule*); 98 99 static PassOwnPtr<InspectorCSSAgent> create(InspectorDOMAgent* domAgent, InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent) 100 { 101 return adoptPtr(new InspectorCSSAgent(domAgent, pageAgent, resourceAgent)); 102 } 103 104 static void collectAllDocumentStyleSheets(Document*, Vector<CSSStyleSheet*>&); 105 106 virtual ~InspectorCSSAgent(); 107 108 bool forcePseudoState(Element*, CSSSelector::PseudoType); 109 virtual void setFrontend(InspectorFrontend*) OVERRIDE; 110 virtual void clearFrontend() OVERRIDE; 111 virtual void discardAgent() OVERRIDE; 112 virtual void didCommitLoadForMainFrame() OVERRIDE; 113 virtual void restore() OVERRIDE; 114 virtual void flushPendingFrontendMessages() OVERRIDE; 115 virtual void enable(ErrorString*, PassRefPtr<EnableCallback>) OVERRIDE; 116 virtual void disable(ErrorString*) OVERRIDE; 117 void reset(); 118 void mediaQueryResultChanged(); 119 void willMutateRules(); 120 void didMutateRules(CSSStyleSheet*); 121 void willMutateStyle(); 122 void didMutateStyle(CSSStyleDeclaration*, bool); 123 124 void activeStyleSheetsUpdated(Document*); 125 void documentDetached(Document*); 126 127 virtual void getComputedStyleForNode(ErrorString*, int nodeId, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> >&) OVERRIDE; 128 virtual void getPlatformFontsForNode(ErrorString*, int nodeId, String* cssFamilyName, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PlatformFontUsage> >&) OVERRIDE; 129 virtual void getInlineStylesForNode(ErrorString*, int nodeId, RefPtr<TypeBuilder::CSS::CSSStyle>& inlineStyle, RefPtr<TypeBuilder::CSS::CSSStyle>& attributes) OVERRIDE; 130 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> >&, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> >& inheritedEntries) OVERRIDE; 131 virtual void getStyleSheetText(ErrorString*, const String& styleSheetId, String* result) OVERRIDE; 132 virtual void setStyleSheetText(ErrorString*, const String& styleSheetId, const String& text) OVERRIDE; 133 134 virtual void setPropertyText(ErrorString*, const String& styleSheetId, const RefPtr<JSONObject>& range, const String& text, RefPtr<TypeBuilder::CSS::CSSStyle>& result) OVERRIDE; 135 virtual void setRuleSelector(ErrorString*, const String& styleSheetId, const RefPtr<JSONObject>& range, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result) OVERRIDE; 136 virtual void createStyleSheet(ErrorString*, const String& frameId, TypeBuilder::CSS::StyleSheetId* outStyleSheetId) OVERRIDE; 137 virtual void addRule(ErrorString*, const String& styleSheetId, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result) OVERRIDE; 138 virtual void forcePseudoState(ErrorString*, int nodeId, const RefPtr<JSONArray>& forcedPseudoClasses) OVERRIDE; 139 virtual void getMediaQueries(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> >& medias) OVERRIDE; 140 141 142 bool collectMediaQueriesFromRule(CSSRule*, TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>* mediaArray); 143 bool collectMediaQueriesFromStyleSheet(CSSStyleSheet*, TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>* mediaArray); 144 PassRefPtr<TypeBuilder::CSS::CSSMedia> buildMediaObject(const MediaList*, MediaListSource, const String&, CSSStyleSheet*); 145 PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> > buildMediaListChain(CSSRule*); 146 147 private: 148 class StyleSheetAction; 149 class SetStyleSheetTextAction; 150 class SetPropertyTextAction; 151 class SetRuleSelectorAction; 152 class AddRuleAction; 153 class InspectorResourceContentLoaderCallback; 154 155 static void collectStyleSheets(CSSStyleSheet*, Vector<CSSStyleSheet*>&); 156 157 InspectorCSSAgent(InspectorDOMAgent*, InspectorPageAgent*, InspectorResourceAgent*); 158 159 typedef HashMap<String, RefPtr<InspectorStyleSheet> > IdToInspectorStyleSheet; 160 typedef HashMap<String, RefPtr<InspectorStyleSheetForInlineStyle> > IdToInspectorStyleSheetForInlineStyle; 161 typedef HashMap<Node*, RefPtr<InspectorStyleSheetForInlineStyle> > NodeToInspectorStyleSheet; // bogus "stylesheets" with elements' inline styles 162 typedef HashMap<int, unsigned> NodeIdToForcedPseudoState; 163 164 void wasEnabled(); 165 void resetNonPersistentData(); 166 InspectorStyleSheetForInlineStyle* asInspectorStyleSheet(Element* element); 167 Element* elementForId(ErrorString*, int nodeId); 168 169 void updateActiveStyleSheets(Document*, StyleSheetsUpdateType); 170 void setActiveStyleSheets(Document*, const Vector<CSSStyleSheet*>&, StyleSheetsUpdateType); 171 172 void collectPlatformFontsForRenderer(RenderText*, HashCountedSet<String>*); 173 174 InspectorStyleSheet* bindStyleSheet(CSSStyleSheet*); 175 String unbindStyleSheet(InspectorStyleSheet*); 176 InspectorStyleSheet* viaInspectorStyleSheet(Document*, bool createIfAbsent); 177 InspectorStyleSheet* assertInspectorStyleSheetForId(ErrorString*, const String&); 178 InspectorStyleSheetBase* assertStyleSheetForId(ErrorString*, const String&); 179 TypeBuilder::CSS::StyleSheetOrigin::Enum detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument); 180 bool styleSheetEditInProgress() const { return m_styleSheetsPendingMutation || m_styleDeclarationPendingMutation || m_isSettingStyleSheetText; } 181 182 PassRefPtr<TypeBuilder::CSS::CSSRule> buildObjectForRule(CSSStyleRule*); 183 PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > buildArrayForMatchedRuleList(CSSRuleList*, Element*); 184 PassRefPtr<TypeBuilder::CSS::CSSStyle> buildObjectForAttributesStyle(Element*); 185 186 // InspectorDOMAgent::DOMListener implementation 187 virtual void didRemoveDocument(Document*) OVERRIDE; 188 virtual void didRemoveDOMNode(Node*) OVERRIDE; 189 virtual void didModifyDOMAttr(Element*) OVERRIDE; 190 191 // InspectorStyleSheet::Listener implementation 192 virtual void styleSheetChanged(InspectorStyleSheetBase*) OVERRIDE; 193 virtual void willReparseStyleSheet() OVERRIDE; 194 virtual void didReparseStyleSheet() OVERRIDE; 195 196 void resetPseudoStates(); 197 198 InspectorFrontend::CSS* m_frontend; 199 InspectorDOMAgent* m_domAgent; 200 InspectorPageAgent* m_pageAgent; 201 InspectorResourceAgent* m_resourceAgent; 202 203 IdToInspectorStyleSheet m_idToInspectorStyleSheet; 204 IdToInspectorStyleSheetForInlineStyle m_idToInspectorStyleSheetForInlineStyle; 205 HashMap<CSSStyleSheet*, RefPtr<InspectorStyleSheet> > m_cssStyleSheetToInspectorStyleSheet; 206 typedef HashMap<Document*, OwnPtr<HashSet<CSSStyleSheet*> > > DocumentStyleSheets; 207 DocumentStyleSheets m_documentToCSSStyleSheets; 208 HashSet<Document*> m_invalidatedDocuments; 209 210 NodeToInspectorStyleSheet m_nodeToInspectorStyleSheet; 211 WillBePersistentHeapHashMap<RefPtrWillBeMember<Document>, RefPtr<InspectorStyleSheet> > m_documentToViaInspectorStyleSheet; // "via inspector" stylesheets 212 NodeIdToForcedPseudoState m_nodeIdToForcedPseudoState; 213 214 RefPtrWillBePersistent<CSSStyleSheet> m_inspectorUserAgentStyleSheet; 215 216 int m_lastStyleSheetId; 217 int m_styleSheetsPendingMutation; 218 bool m_styleDeclarationPendingMutation; 219 bool m_creatingViaInspectorStyleSheet; 220 bool m_isSettingStyleSheetText; 221 222 friend class InspectorResourceContentLoaderCallback; 223 friend class StyleSheetBinder; 224 }; 225 226 227 } // namespace WebCore 228 229 #endif // !defined(InspectorCSSAgent_h) 230