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 "CSSPropertySourceData.h" 29 #include "InspectorValues.h" 30 #include "PlatformString.h" 31 32 #include <wtf/HashMap.h> 33 #include <wtf/HashSet.h> 34 #include <wtf/PassRefPtr.h> 35 #include <wtf/RefPtr.h> 36 #include <wtf/Vector.h> 37 38 class ParsedStyleSheet; 39 40 namespace WebCore { 41 42 class CSSRuleList; 43 class CSSStyleDeclaration; 44 class CSSStyleSheet; 45 class Document; 46 class Element; 47 class InspectorStyleSheet; 48 class Node; 49 50 #if ENABLE(INSPECTOR) 51 52 typedef String ErrorString; 53 54 class InspectorCSSId { 55 public: 56 InspectorCSSId() { } 57 58 explicit InspectorCSSId(RefPtr<InspectorObject> value) 59 { 60 if (!value->getString("styleSheetId", &m_styleSheetId)) 61 return; 62 63 RefPtr<InspectorValue> ordinalValue = value->get("ordinal"); 64 if (!ordinalValue || !ordinalValue->asNumber(&m_ordinal)) 65 m_styleSheetId = ""; 66 } 67 68 InspectorCSSId(const String& styleSheetId, unsigned ordinal) 69 : m_styleSheetId(styleSheetId) 70 , m_ordinal(ordinal) 71 { 72 } 73 74 bool isEmpty() const { return m_styleSheetId.isEmpty(); } 75 76 const String& styleSheetId() const { return m_styleSheetId; } 77 unsigned ordinal() const { return m_ordinal; } 78 79 PassRefPtr<InspectorValue> asInspectorValue() const 80 { 81 if (isEmpty()) 82 return InspectorValue::null(); 83 84 RefPtr<InspectorObject> result = InspectorObject::create(); 85 result->setString("styleSheetId", m_styleSheetId); 86 result->setNumber("ordinal", m_ordinal); 87 return result.release(); 88 } 89 90 private: 91 String m_styleSheetId; 92 unsigned m_ordinal; 93 }; 94 95 struct InspectorStyleProperty { 96 InspectorStyleProperty() 97 { 98 } 99 100 InspectorStyleProperty(CSSPropertySourceData sourceData, bool hasSource, bool disabled) 101 : sourceData(sourceData) 102 , hasSource(hasSource) 103 , disabled(disabled) 104 { 105 } 106 107 void setRawTextFromStyleDeclaration(const String& styleDeclaration) 108 { 109 unsigned start = sourceData.range.start; 110 unsigned end = sourceData.range.end; 111 ASSERT(start < end); 112 ASSERT(end <= styleDeclaration.length()); 113 rawText = styleDeclaration.substring(start, end - start); 114 } 115 116 bool hasRawText() const { return !rawText.isEmpty(); } 117 118 CSSPropertySourceData sourceData; 119 bool hasSource; 120 bool disabled; 121 String rawText; 122 }; 123 124 class InspectorStyle : public RefCounted<InspectorStyle> { 125 public: 126 static PassRefPtr<InspectorStyle> create(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet); 127 virtual ~InspectorStyle(); 128 129 CSSStyleDeclaration* cssStyle() const { return m_style.get(); } 130 PassRefPtr<InspectorObject> buildObjectForStyle() const; 131 bool hasDisabledProperties() const { return !m_disabledProperties.isEmpty(); } 132 bool setPropertyText(ErrorString*, unsigned index, const String& text, bool overwrite); 133 bool toggleProperty(ErrorString*, unsigned index, bool disable); 134 135 private: 136 InspectorStyle(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet); 137 138 static unsigned disabledIndexByOrdinal(unsigned ordinal, bool canUseSubsequent, Vector<InspectorStyleProperty>& allProperties); 139 140 bool styleText(String* result) const; 141 bool disableProperty(unsigned indexToDisable, Vector<InspectorStyleProperty>& allProperties); 142 bool enableProperty(unsigned indexToEnable, Vector<InspectorStyleProperty>& allProperties); 143 bool populateAllProperties(Vector<InspectorStyleProperty>* result) const; 144 void populateObjectWithStyleProperties(InspectorObject* result) const; 145 void shiftDisabledProperties(unsigned fromIndex, long offset); 146 bool replacePropertyInStyleText(const InspectorStyleProperty& property, const String& newText); 147 String shorthandValue(const String& shorthandProperty) const; 148 String shorthandPriority(const String& shorthandProperty) const; 149 Vector<String> longhandProperties(const String& shorthandProperty) const; 150 151 InspectorCSSId m_styleId; 152 RefPtr<CSSStyleDeclaration> m_style; 153 InspectorStyleSheet* m_parentStyleSheet; 154 Vector<InspectorStyleProperty> m_disabledProperties; 155 }; 156 157 class InspectorStyleSheet : public RefCounted<InspectorStyleSheet> { 158 public: 159 typedef HashMap<CSSStyleDeclaration*, RefPtr<InspectorStyle> > InspectorStyleMap; 160 static PassRefPtr<InspectorStyleSheet> create(const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, const String& origin, const String& documentURL); 161 162 virtual ~InspectorStyleSheet(); 163 164 String id() const { return m_id; } 165 String finalURL() const; 166 CSSStyleSheet* pageStyleSheet() const { return m_pageStyleSheet.get(); } 167 void reparseStyleSheet(const String&); 168 bool setText(const String&); 169 bool setRuleSelector(const InspectorCSSId&, const String& selector); 170 CSSStyleRule* addRule(const String& selector); 171 CSSStyleRule* ruleForId(const InspectorCSSId&) const; 172 PassRefPtr<InspectorObject> buildObjectForStyleSheet(); 173 PassRefPtr<InspectorObject> buildObjectForStyleSheetInfo(); 174 PassRefPtr<InspectorObject> buildObjectForRule(CSSStyleRule*); 175 PassRefPtr<InspectorObject> buildObjectForStyle(CSSStyleDeclaration*); 176 bool setPropertyText(ErrorString*, const InspectorCSSId&, unsigned propertyIndex, const String& text, bool overwrite); 177 bool toggleProperty(ErrorString*, const InspectorCSSId&, unsigned propertyIndex, bool disable); 178 179 virtual bool text(String* result) const; 180 virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const; 181 182 protected: 183 InspectorStyleSheet(const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, const String& origin, const String& documentURL); 184 185 bool canBind() const { return m_origin != "userAgent" && m_origin != "user"; } 186 InspectorCSSId ruleOrStyleId(CSSStyleDeclaration* style) const; 187 virtual Document* ownerDocument() const; 188 virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const; 189 virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const; 190 virtual bool ensureParsedDataReady(); 191 virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&); 192 virtual void rememberInspectorStyle(RefPtr<InspectorStyle> inspectorStyle); 193 virtual void forgetInspectorStyle(CSSStyleDeclaration* style); 194 195 // Also accessed by friend class InspectorStyle. 196 virtual bool setStyleText(CSSStyleDeclaration*, const String&); 197 198 private: 199 static void fixUnparsedPropertyRanges(CSSRuleSourceData* ruleData, const String& styleSheetText); 200 static void collectFlatRules(PassRefPtr<CSSRuleList>, Vector<CSSStyleRule*>* result); 201 bool ensureText() const; 202 bool ensureSourceData(); 203 void ensureFlatRules() const; 204 bool styleSheetTextWithChangedStyle(CSSStyleDeclaration*, const String& newStyleText, String* result); 205 InspectorCSSId ruleId(CSSStyleRule* rule) const; 206 InspectorCSSId styleId(CSSStyleDeclaration* style) const { return ruleOrStyleId(style); } 207 void revalidateStyle(CSSStyleDeclaration*); 208 bool originalStyleSheetText(String* result) const; 209 bool resourceStyleSheetText(String* result) const; 210 bool inlineStyleSheetText(String* result) const; 211 PassRefPtr<InspectorArray> buildArrayForRuleList(CSSRuleList*); 212 213 String m_id; 214 RefPtr<CSSStyleSheet> m_pageStyleSheet; 215 String m_origin; 216 String m_documentURL; 217 bool m_isRevalidating; 218 ParsedStyleSheet* m_parsedStyleSheet; 219 InspectorStyleMap m_inspectorStyles; 220 mutable Vector<CSSStyleRule*> m_flatRules; 221 222 friend class InspectorStyle; 223 }; 224 225 class InspectorStyleSheetForInlineStyle : public InspectorStyleSheet { 226 public: 227 static PassRefPtr<InspectorStyleSheetForInlineStyle> create(const String& id, PassRefPtr<Element> element, const String& origin); 228 229 void didModifyElementAttribute(); 230 virtual bool text(String* result) const; 231 virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const { ASSERT_UNUSED(id, !id.ordinal()); return inlineStyle(); } 232 233 protected: 234 InspectorStyleSheetForInlineStyle(const String& id, PassRefPtr<Element> element, const String& origin); 235 236 virtual Document* ownerDocument() const; 237 virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const { ASSERT_UNUSED(style, style == inlineStyle()); return m_ruleSourceData; } 238 virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const { return 0; } 239 virtual bool ensureParsedDataReady(); 240 virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&); 241 virtual void rememberInspectorStyle(RefPtr<InspectorStyle>) { } 242 virtual void forgetInspectorStyle(CSSStyleDeclaration*) { } 243 244 // Also accessed by friend class InspectorStyle. 245 virtual bool setStyleText(CSSStyleDeclaration*, const String&); 246 247 private: 248 CSSStyleDeclaration* inlineStyle() const; 249 const String& elementStyleText() const; 250 bool getStyleAttributeRanges(RefPtr<CSSStyleSourceData>* result); 251 252 RefPtr<Element> m_element; 253 RefPtr<CSSRuleSourceData> m_ruleSourceData; 254 RefPtr<InspectorStyle> m_inspectorStyle; 255 256 // Contains "style" attribute value and should always be up-to-date. 257 String m_styleText; 258 }; 259 260 #endif 261 262 } // namespace WebCore 263 264 #endif // !defined(InspectorStyleSheet_h) 265