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 InspectorStyleSheet_h 26 #define InspectorStyleSheet_h 27 28 #include "core/InspectorTypeBuilder.h" 29 #include "core/css/CSSPropertySourceData.h" 30 #include "core/css/CSSStyleDeclaration.h" 31 #include "core/inspector/InspectorStyleTextEditor.h" 32 #include "platform/JSONValues.h" 33 #include "platform/heap/Handle.h" 34 #include "wtf/HashMap.h" 35 #include "wtf/PassRefPtr.h" 36 #include "wtf/RefPtr.h" 37 #include "wtf/Vector.h" 38 #include "wtf/text/WTFString.h" 39 40 class ParsedStyleSheet; 41 42 namespace blink { 43 44 class CSSMediaRule; 45 class CSSRuleList; 46 class CSSStyleDeclaration; 47 class CSSStyleRule; 48 class CSSStyleSheet; 49 class Document; 50 class Element; 51 class ExceptionState; 52 class InspectorPageAgent; 53 class InspectorResourceAgent; 54 class InspectorStyleSheetBase; 55 56 typedef WillBeHeapVector<RefPtrWillBeMember<CSSRule> > CSSRuleVector; 57 typedef String ErrorString; 58 59 class InspectorCSSId { 60 public: InspectorCSSId()61 InspectorCSSId() 62 : m_ordinal(0) 63 { 64 } 65 InspectorCSSId(const String & styleSheetId,unsigned ordinal)66 InspectorCSSId(const String& styleSheetId, unsigned ordinal) 67 : m_styleSheetId(styleSheetId) 68 , m_ordinal(ordinal) 69 { 70 } 71 isEmpty()72 bool isEmpty() const { return m_styleSheetId.isEmpty(); } 73 styleSheetId()74 const String& styleSheetId() const { return m_styleSheetId; } ordinal()75 unsigned ordinal() const { return m_ordinal; } 76 77 private: 78 String m_styleSheetId; 79 unsigned m_ordinal; 80 }; 81 82 struct InspectorStyleProperty { 83 ALLOW_ONLY_INLINE_ALLOCATION(); 84 public: InspectorStylePropertyInspectorStyleProperty85 explicit InspectorStyleProperty(CSSPropertySourceData sourceData) 86 : sourceData(sourceData) 87 , hasSource(true) 88 { 89 } 90 InspectorStylePropertyInspectorStyleProperty91 InspectorStyleProperty(CSSPropertySourceData sourceData, bool hasSource) 92 : sourceData(sourceData) 93 , hasSource(hasSource) 94 { 95 } 96 hasRawTextInspectorStyleProperty97 bool hasRawText() const { return !rawText.isEmpty(); } 98 traceInspectorStyleProperty99 void trace(Visitor* visitor) { visitor->trace(sourceData); } 100 101 CSSPropertySourceData sourceData; 102 bool hasSource; 103 String rawText; 104 }; 105 106 class InspectorStyle FINAL : public RefCountedWillBeGarbageCollectedFinalized<InspectorStyle> { 107 public: 108 static PassRefPtrWillBeRawPtr<InspectorStyle> create(const InspectorCSSId&, PassRefPtrWillBeRawPtr<CSSStyleDeclaration>, InspectorStyleSheetBase* parentStyleSheet); 109 cssStyle()110 CSSStyleDeclaration* cssStyle() const { return m_style.get(); } 111 PassRefPtr<TypeBuilder::CSS::CSSStyle> buildObjectForStyle() const; 112 PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> > buildArrayForComputedStyle() const; 113 bool setPropertyText(unsigned index, const String& text, bool overwrite, ExceptionState&); 114 bool styleText(String* result) const; 115 bool textForRange(const SourceRange&, String* result) const; 116 117 void trace(Visitor*); 118 119 private: 120 InspectorStyle(const InspectorCSSId&, PassRefPtrWillBeRawPtr<CSSStyleDeclaration>, InspectorStyleSheetBase* parentStyleSheet); 121 122 bool verifyPropertyText(const String& propertyText, bool canOmitSemicolon); 123 void populateAllProperties(WillBeHeapVector<InspectorStyleProperty>& result) const; 124 PassRefPtr<TypeBuilder::CSS::CSSStyle> styleWithProperties() const; 125 PassRefPtrWillBeRawPtr<CSSRuleSourceData> extractSourceData() const; 126 bool applyStyleText(const String&); 127 String shorthandValue(const String& shorthandProperty) const; 128 NewLineAndWhitespace& newLineAndWhitespaceDelimiters() const; 129 inline Document* ownerDocument() const; 130 131 InspectorCSSId m_styleId; 132 RefPtrWillBeMember<CSSStyleDeclaration> m_style; 133 RawPtrWillBeMember<InspectorStyleSheetBase> m_parentStyleSheet; 134 mutable std::pair<String, String> m_format; 135 mutable bool m_formatAcquired; 136 }; 137 138 class InspectorStyleSheetBase : public RefCountedWillBeGarbageCollectedFinalized<InspectorStyleSheetBase> { 139 public: 140 class Listener { 141 public: Listener()142 Listener() { } ~Listener()143 virtual ~Listener() { } 144 virtual void styleSheetChanged(InspectorStyleSheetBase*) = 0; 145 virtual void willReparseStyleSheet() = 0; 146 virtual void didReparseStyleSheet() = 0; 147 }; ~InspectorStyleSheetBase()148 virtual ~InspectorStyleSheetBase() { } trace(Visitor *)149 virtual void trace(Visitor*) { } 150 id()151 String id() const { return m_id; } 152 153 virtual Document* ownerDocument() const = 0; 154 virtual bool setText(const String&, ExceptionState&) = 0; 155 virtual bool getText(String* result) const = 0; 156 bool setPropertyText(const InspectorCSSId&, unsigned propertyIndex, const String& text, bool overwrite, ExceptionState&); 157 158 virtual bool setStyleText(const InspectorCSSId&, const String&) = 0; 159 bool getStyleText(const InspectorCSSId&, String*); 160 161 virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const = 0; 162 virtual InspectorCSSId styleId(CSSStyleDeclaration*) const = 0; 163 164 PassRefPtr<TypeBuilder::CSS::CSSStyle> buildObjectForStyle(CSSStyleDeclaration*); 165 bool findPropertyByRange(const SourceRange&, InspectorCSSId*, unsigned* propertyIndex, bool* overwrite); 166 bool lineNumberAndColumnToOffset(unsigned lineNumber, unsigned columnNumber, unsigned* offset); 167 168 protected: 169 InspectorStyleSheetBase(const String& id, Listener*); 170 listener()171 Listener* listener() const { return m_listener; } 172 void fireStyleSheetChanged(); 173 PassOwnPtr<Vector<unsigned> > lineEndings(); 174 175 virtual PassRefPtrWillBeRawPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&) = 0; 176 virtual unsigned ruleCount() = 0; 177 178 // Also accessed by friend class InspectorStyle. 179 virtual PassRefPtrWillBeRawPtr<CSSRuleSourceData> ruleSourceDataAt(unsigned) const = 0; 180 virtual bool ensureParsedDataReady() = 0; 181 182 private: 183 friend class InspectorStyle; 184 185 String m_id; 186 Listener* m_listener; 187 }; 188 189 class InspectorStyleSheet : public InspectorStyleSheetBase { 190 public: 191 static PassRefPtrWillBeRawPtr<InspectorStyleSheet> create(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtrWillBeRawPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum, const String& documentURL, Listener*); 192 193 virtual ~InspectorStyleSheet(); 194 virtual void trace(Visitor*) OVERRIDE; 195 196 String finalURL() const; 197 virtual Document* ownerDocument() const OVERRIDE; 198 virtual bool setText(const String&, ExceptionState&) OVERRIDE; 199 virtual bool getText(String* result) const OVERRIDE; 200 String ruleSelector(const InspectorCSSId&, ExceptionState&); 201 bool setRuleSelector(const InspectorCSSId&, const String& selector, ExceptionState&); 202 CSSStyleRule* addRule(const String& ruleText, const SourceRange& location, ExceptionState&); 203 bool deleteRule(const InspectorCSSId&, const String& oldText, ExceptionState&); 204 pageStyleSheet()205 CSSStyleSheet* pageStyleSheet() const { return m_pageStyleSheet.get(); } 206 207 PassRefPtr<TypeBuilder::CSS::CSSStyleSheetHeader> buildObjectForStyleSheetInfo() const; 208 PassRefPtr<TypeBuilder::CSS::CSSRule> buildObjectForRule(CSSStyleRule*, PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> >); 209 210 PassRefPtr<TypeBuilder::CSS::SourceRange> ruleHeaderSourceRange(const CSSRule*); 211 212 InspectorCSSId ruleId(CSSStyleRule*) const; 213 CSSStyleRule* ruleForId(const InspectorCSSId&) const; 214 215 virtual InspectorCSSId styleId(CSSStyleDeclaration*) const OVERRIDE; 216 virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const OVERRIDE; 217 virtual bool setStyleText(const InspectorCSSId&, const String&) OVERRIDE; 218 219 bool findRuleBySelectorRange(const SourceRange&, InspectorCSSId*); 220 221 const CSSRuleVector& flatRules(); 222 223 protected: 224 virtual PassRefPtrWillBeRawPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&) OVERRIDE; 225 virtual unsigned ruleCount() OVERRIDE; 226 227 // Also accessed by friend class InspectorStyle. 228 virtual PassRefPtrWillBeRawPtr<CSSRuleSourceData> ruleSourceDataAt(unsigned) const OVERRIDE; 229 virtual bool ensureParsedDataReady() OVERRIDE; 230 231 private: 232 InspectorStyleSheet(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtrWillBeRawPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum, const String& documentURL, Listener*); 233 unsigned ruleIndexBySourceRange(const CSSMediaRule* parentMediaRule, const SourceRange&); 234 CSSStyleRule* insertCSSOMRuleInStyleSheet(const SourceRange&, const String& ruleText, ExceptionState&); 235 CSSStyleRule* insertCSSOMRuleInMediaRule(CSSMediaRule*, const SourceRange&, const String& ruleText, ExceptionState&); 236 CSSStyleRule* insertCSSOMRuleBySourceRange(const SourceRange&, const String& ruleText, ExceptionState&); 237 bool verifyRuleText(const String& ruleText); 238 unsigned ruleIndexByStyle(CSSStyleDeclaration*) const; 239 String sourceMapURL() const; 240 String sourceURL() const; 241 bool ensureText() const; 242 void ensureFlatRules() const; 243 bool styleSheetTextWithChangedStyle(CSSStyleDeclaration*, const String& newStyleText, String* result); 244 bool originalStyleSheetText(String* result) const; 245 bool resourceStyleSheetText(String* result) const; 246 bool inlineStyleSheetText(String* result) const; 247 PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::Selector> > selectorsFromSource(const CSSRuleSourceData*, const String&); 248 PassRefPtr<TypeBuilder::CSS::SelectorList> buildObjectForSelectorList(CSSStyleRule*); 249 String url() const; 250 bool hasSourceURL() const; 251 bool startsAtZero() const; 252 253 void updateText(const String& newText); 254 Element* ownerStyleElement() const; 255 256 RawPtrWillBeMember<InspectorPageAgent> m_pageAgent; 257 RawPtrWillBeMember<InspectorResourceAgent> m_resourceAgent; 258 RefPtrWillBeMember<CSSStyleSheet> m_pageStyleSheet; 259 TypeBuilder::CSS::StyleSheetOrigin::Enum m_origin; 260 String m_documentURL; 261 OwnPtr<ParsedStyleSheet> m_parsedStyleSheet; 262 mutable CSSRuleVector m_flatRules; 263 mutable String m_sourceURL; 264 }; 265 266 class InspectorStyleSheetForInlineStyle FINAL : public InspectorStyleSheetBase { 267 public: 268 static PassRefPtrWillBeRawPtr<InspectorStyleSheetForInlineStyle> create(const String& id, PassRefPtrWillBeRawPtr<Element>, Listener*); 269 270 void didModifyElementAttribute(); 271 virtual Document* ownerDocument() const OVERRIDE; 272 virtual bool setText(const String&, ExceptionState&) OVERRIDE; 273 virtual bool getText(String* result) const OVERRIDE; 274 styleForId(const InspectorCSSId & id)275 virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const OVERRIDE { ASSERT_UNUSED(id, !id.ordinal()); return inlineStyle(); } styleId(CSSStyleDeclaration * style)276 virtual InspectorCSSId styleId(CSSStyleDeclaration* style) const OVERRIDE { return InspectorCSSId(id(), 0); } 277 virtual bool setStyleText(const InspectorCSSId&, const String&) OVERRIDE; 278 279 virtual void trace(Visitor*) OVERRIDE; 280 281 protected: 282 virtual PassRefPtrWillBeRawPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&) OVERRIDE; ruleCount()283 virtual unsigned ruleCount() OVERRIDE { return 1; } 284 285 // Also accessed by friend class InspectorStyle. 286 virtual bool ensureParsedDataReady() OVERRIDE; ruleSourceDataAt(unsigned ruleIndex)287 virtual PassRefPtrWillBeRawPtr<CSSRuleSourceData> ruleSourceDataAt(unsigned ruleIndex) const OVERRIDE { ASSERT_UNUSED(ruleIndex, !ruleIndex); return m_ruleSourceData; } 288 289 private: 290 InspectorStyleSheetForInlineStyle(const String& id, PassRefPtrWillBeRawPtr<Element>, Listener*); 291 CSSStyleDeclaration* inlineStyle() const; 292 const String& elementStyleText() const; 293 PassRefPtrWillBeRawPtr<CSSRuleSourceData> getStyleAttributeData() const; 294 295 RefPtrWillBeMember<Element> m_element; 296 RefPtrWillBeMember<CSSRuleSourceData> m_ruleSourceData; 297 RefPtrWillBeMember<InspectorStyle> m_inspectorStyle; 298 299 // Contains "style" attribute value. 300 mutable String m_styleText; 301 mutable bool m_isStyleTextValid; 302 }; 303 304 305 } // namespace blink 306 307 WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::InspectorStyleProperty); 308 309 #endif // !defined(InspectorStyleSheet_h) 310