• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
InspectorCSSId()56     InspectorCSSId() { }
57 
InspectorCSSId(RefPtr<InspectorObject> value)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 
InspectorCSSId(const String & styleSheetId,unsigned ordinal)68     InspectorCSSId(const String& styleSheetId, unsigned ordinal)
69         : m_styleSheetId(styleSheetId)
70         , m_ordinal(ordinal)
71     {
72     }
73 
isEmpty()74     bool isEmpty() const { return m_styleSheetId.isEmpty(); }
75 
styleSheetId()76     const String& styleSheetId() const { return m_styleSheetId; }
ordinal()77     unsigned ordinal() const { return m_ordinal; }
78 
asInspectorValue()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 {
InspectorStylePropertyInspectorStyleProperty96     InspectorStyleProperty()
97     {
98     }
99 
InspectorStylePropertyInspectorStyleProperty100     InspectorStyleProperty(CSSPropertySourceData sourceData, bool hasSource, bool disabled)
101         : sourceData(sourceData)
102         , hasSource(hasSource)
103         , disabled(disabled)
104     {
105     }
106 
setRawTextFromStyleDeclarationInspectorStyleProperty107     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 
hasRawTextInspectorStyleProperty116     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 
cssStyle()129     CSSStyleDeclaration* cssStyle() const { return m_style.get(); }
130     PassRefPtr<InspectorObject> buildObjectForStyle() const;
hasDisabledProperties()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 
id()164     String id() const { return m_id; }
165     String finalURL() const;
pageStyleSheet()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 
canBind()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;
styleId(CSSStyleDeclaration * style)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;
styleForId(const InspectorCSSId & id)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;
ruleSourceDataFor(CSSStyleDeclaration * style)237     virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const { ASSERT_UNUSED(style, style == inlineStyle()); return m_ruleSourceData; }
ruleIndexByStyle(CSSStyleDeclaration *)238     virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const { return 0; }
239     virtual bool ensureParsedDataReady();
240     virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&);
rememberInspectorStyle(RefPtr<InspectorStyle>)241     virtual void rememberInspectorStyle(RefPtr<InspectorStyle>) { }
forgetInspectorStyle(CSSStyleDeclaration *)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