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