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