Part 2 of removing PlatformString.h, remove PlatformString.h
[WebKit-https.git] / Source / WebCore / inspector / InspectorStyleSheet.h
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 "CSSStyleDeclaration.h"
30 #include "ExceptionCode.h"
31 #include "InspectorStyleTextEditor.h"
32 #include "InspectorTypeBuilder.h"
33 #include "InspectorValues.h"
34
35 #include <wtf/HashMap.h>
36 #include <wtf/HashSet.h>
37 #include <wtf/PassRefPtr.h>
38 #include <wtf/RefPtr.h>
39 #include <wtf/Vector.h>
40 #include <wtf/text/WTFString.h>
41
42 class ParsedStyleSheet;
43
44 namespace WebCore {
45
46 class CSSRuleList;
47 class CSSStyleDeclaration;
48 class CSSStyleRule;
49 class CSSStyleSheet;
50 class Document;
51 class Element;
52 class InspectorPageAgent;
53 class InspectorStyleSheet;
54 class Node;
55
56 #if ENABLE(INSPECTOR)
57
58 typedef String ErrorString;
59
60 class InspectorCSSId {
61 public:
62     InspectorCSSId()
63         : m_ordinal(0)
64     {
65     }
66
67     explicit InspectorCSSId(RefPtr<InspectorObject> value)
68     {
69         if (!value->getString("styleSheetId", &m_styleSheetId))
70             return;
71         
72         RefPtr<InspectorValue> ordinalValue = value->get("ordinal");
73         if (!ordinalValue || !ordinalValue->asNumber(&m_ordinal))
74             m_styleSheetId = "";
75     }
76
77     InspectorCSSId(const String& styleSheetId, unsigned ordinal)
78         : m_styleSheetId(styleSheetId)
79         , m_ordinal(ordinal)
80     {
81     }
82
83     bool isEmpty() const { return m_styleSheetId.isEmpty(); }
84
85     const String& styleSheetId() const { return m_styleSheetId; }
86     unsigned ordinal() const { return m_ordinal; }
87
88     // ID type is either TypeBuilder::CSS::CSSStyleId or TypeBuilder::CSS::CSSRuleId.
89     template<typename ID>
90     PassRefPtr<ID> asProtocolValue() const
91     {
92         if (isEmpty())
93             return 0;
94
95         RefPtr<ID> result = ID::create()
96             .setStyleSheetId(m_styleSheetId)
97             .setOrdinal(m_ordinal);
98         return result.release();
99     }
100
101 private:
102     String m_styleSheetId;
103     unsigned m_ordinal;
104 };
105
106 struct InspectorStyleProperty {
107     InspectorStyleProperty()
108         : hasSource(false)
109         , disabled(false)
110     {
111     }
112
113     InspectorStyleProperty(CSSPropertySourceData sourceData, bool hasSource, bool disabled)
114         : sourceData(sourceData)
115         , hasSource(hasSource)
116         , disabled(disabled)
117     {
118     }
119
120     void setRawTextFromStyleDeclaration(const String& styleDeclaration)
121     {
122         unsigned start = sourceData.range.start;
123         unsigned end = sourceData.range.end;
124         ASSERT(start < end);
125         ASSERT(end <= styleDeclaration.length());
126         rawText = styleDeclaration.substring(start, end - start);
127     }
128
129     bool hasRawText() const { return !rawText.isEmpty(); }
130
131     CSSPropertySourceData sourceData;
132     bool hasSource;
133     bool disabled;
134     String rawText;
135 };
136
137 class InspectorStyle : public RefCounted<InspectorStyle> {
138 public:
139     static PassRefPtr<InspectorStyle> create(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet);
140     virtual ~InspectorStyle();
141
142     CSSStyleDeclaration* cssStyle() const { return m_style.get(); }
143     PassRefPtr<TypeBuilder::CSS::CSSStyle> buildObjectForStyle() const;
144     PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> > buildArrayForComputedStyle() const;
145     bool hasDisabledProperties() const { return !m_disabledProperties.isEmpty(); }
146     bool setPropertyText(unsigned index, const String& text, bool overwrite, String* oldText, ExceptionCode&);
147     bool toggleProperty(unsigned index, bool disable, ExceptionCode&);
148
149 private:
150     InspectorStyle(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet);
151
152     bool styleText(String* result) const;
153     bool populateAllProperties(Vector<InspectorStyleProperty>* result) const;
154     PassRefPtr<TypeBuilder::CSS::CSSStyle> styleWithProperties() const;
155     bool applyStyleText(const String&);
156     String shorthandValue(const String& shorthandProperty) const;
157     String shorthandPriority(const String& shorthandProperty) const;
158     Vector<String> longhandProperties(const String& shorthandProperty) const;
159     NewLineAndWhitespace& newLineAndWhitespaceDelimiters() const;
160
161     InspectorCSSId m_styleId;
162     RefPtr<CSSStyleDeclaration> m_style;
163     InspectorStyleSheet* m_parentStyleSheet;
164     Vector<InspectorStyleProperty> m_disabledProperties;
165     mutable std::pair<String, String> m_format;
166     mutable bool m_formatAcquired;
167 };
168
169 class InspectorStyleSheet : public RefCounted<InspectorStyleSheet> {
170 public:
171     class Listener {
172     public:
173         Listener() { }
174         virtual ~Listener() { }
175         virtual void styleSheetChanged(InspectorStyleSheet*) = 0;
176     };
177
178     typedef HashMap<CSSStyleDeclaration*, RefPtr<InspectorStyle> > InspectorStyleMap;
179     static PassRefPtr<InspectorStyleSheet> create(InspectorPageAgent*, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum, const String& documentURL, Listener*);
180     static String styleSheetURL(CSSStyleSheet* pageStyleSheet);
181
182     virtual ~InspectorStyleSheet();
183
184     String id() const { return m_id; }
185     String finalURL() const;
186     CSSStyleSheet* pageStyleSheet() const { return m_pageStyleSheet.get(); }
187     void reparseStyleSheet(const String&);
188     bool setText(const String&);
189     String ruleSelector(const InspectorCSSId&, ExceptionCode&);
190     bool setRuleSelector(const InspectorCSSId&, const String& selector, ExceptionCode&);
191     CSSStyleRule* addRule(const String& selector, ExceptionCode&);
192     bool deleteRule(const InspectorCSSId&, ExceptionCode&);
193     CSSStyleRule* ruleForId(const InspectorCSSId&) const;
194     PassRefPtr<TypeBuilder::CSS::CSSStyleSheetBody> buildObjectForStyleSheet();
195     PassRefPtr<TypeBuilder::CSS::CSSStyleSheetHeader> buildObjectForStyleSheetInfo();
196     PassRefPtr<TypeBuilder::CSS::CSSRule> buildObjectForRule(CSSStyleRule*);
197     PassRefPtr<TypeBuilder::CSS::CSSStyle> buildObjectForStyle(CSSStyleDeclaration*);
198     bool setPropertyText(const InspectorCSSId&, unsigned propertyIndex, const String& text, bool overwrite, String* oldPropertyText, ExceptionCode&);
199     bool toggleProperty(const InspectorCSSId&, unsigned propertyIndex, bool disable, ExceptionCode&);
200
201     virtual bool getText(String* result) const;
202     virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const;
203     void fireStyleSheetChanged();
204
205     InspectorCSSId ruleId(CSSStyleRule*) const;
206     InspectorCSSId styleId(CSSStyleDeclaration* style) const { return ruleOrStyleId(style); }
207
208 protected:
209     InspectorStyleSheet(InspectorPageAgent*, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum, const String& documentURL, Listener*);
210
211     bool canBind() const { return m_origin != TypeBuilder::CSS::StyleSheetOrigin::User_agent && m_origin != TypeBuilder::CSS::StyleSheetOrigin::User; }
212     InspectorCSSId ruleOrStyleId(CSSStyleDeclaration* style) const;
213     virtual Document* ownerDocument() const;
214     virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const;
215     virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const;
216     virtual bool ensureParsedDataReady();
217     virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&);
218     virtual void rememberInspectorStyle(RefPtr<InspectorStyle> inspectorStyle);
219     virtual void forgetInspectorStyle(CSSStyleDeclaration* style);
220
221     // Also accessed by friend class InspectorStyle.
222     virtual bool setStyleText(CSSStyleDeclaration*, const String&);
223
224 private:
225     friend class InspectorStyle;
226
227     static void collectFlatRules(PassRefPtr<CSSRuleList>, Vector<CSSStyleRule*>* result);
228     bool ensureText() const;
229     bool ensureSourceData();
230     void ensureFlatRules() const;
231     bool styleSheetTextWithChangedStyle(CSSStyleDeclaration*, const String& newStyleText, String* result);
232     void revalidateStyle(CSSStyleDeclaration*);
233     bool originalStyleSheetText(String* result) const;
234     bool resourceStyleSheetText(String* result) const;
235     bool inlineStyleSheetText(String* result) const;
236     PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSRule> > buildArrayForRuleList(CSSRuleList*);
237
238     InspectorPageAgent* m_pageAgent;
239     String m_id;
240     RefPtr<CSSStyleSheet> m_pageStyleSheet;
241     TypeBuilder::CSS::StyleSheetOrigin::Enum m_origin;
242     String m_documentURL;
243     bool m_isRevalidating;
244     ParsedStyleSheet* m_parsedStyleSheet;
245     InspectorStyleMap m_inspectorStyles;
246     mutable Vector<CSSStyleRule*> m_flatRules;
247     Listener* m_listener;
248 };
249
250 class InspectorStyleSheetForInlineStyle : public InspectorStyleSheet {
251 public:
252     static PassRefPtr<InspectorStyleSheetForInlineStyle> create(InspectorPageAgent*, const String& id, PassRefPtr<Element>, TypeBuilder::CSS::StyleSheetOrigin::Enum, Listener*);
253
254     void didModifyElementAttribute();
255     virtual bool getText(String* result) const;
256     virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const { ASSERT_UNUSED(id, !id.ordinal()); return inlineStyle(); }
257
258 protected:
259     InspectorStyleSheetForInlineStyle(InspectorPageAgent*, const String& id, PassRefPtr<Element>, TypeBuilder::CSS::StyleSheetOrigin::Enum, Listener*);
260
261     virtual Document* ownerDocument() const;
262     virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const { ASSERT_UNUSED(style, style == inlineStyle()); return m_ruleSourceData; }
263     virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const { return 0; }
264     virtual bool ensureParsedDataReady();
265     virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&);
266     virtual void rememberInspectorStyle(RefPtr<InspectorStyle>) { }
267     virtual void forgetInspectorStyle(CSSStyleDeclaration*) { }
268
269     // Also accessed by friend class InspectorStyle.
270     virtual bool setStyleText(CSSStyleDeclaration*, const String&);
271
272 private:
273     CSSStyleDeclaration* inlineStyle() const;
274     const String& elementStyleText() const;
275     bool getStyleAttributeRanges(CSSRuleSourceData* result) const;
276
277     RefPtr<Element> m_element;
278     RefPtr<CSSRuleSourceData> m_ruleSourceData;
279     RefPtr<InspectorStyle> m_inspectorStyle;
280
281     // Contains "style" attribute value.
282     mutable String m_styleText;
283     mutable bool m_isStyleTextValid;
284 };
285
286 #endif
287
288 } // namespace WebCore
289
290 #endif // !defined(InspectorStyleSheet_h)