• 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 "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:
InspectorCSSId()59     InspectorCSSId()
60         : m_ordinal(0)
61     {
62     }
63 
InspectorCSSId(PassRefPtr<JSONObject> value)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 
InspectorCSSId(const String & styleSheetId,unsigned ordinal)74     InspectorCSSId(const String& styleSheetId, unsigned ordinal)
75         : m_styleSheetId(styleSheetId)
76         , m_ordinal(ordinal)
77     {
78     }
79 
isEmpty()80     bool isEmpty() const { return m_styleSheetId.isEmpty(); }
81 
styleSheetId()82     const String& styleSheetId() const { return m_styleSheetId; }
ordinal()83     unsigned ordinal() const { return m_ordinal; }
84 
85     // ID type is either TypeBuilder::CSS::CSSStyleId or TypeBuilder::CSS::CSSRuleId.
86     template<typename ID>
asProtocolValue()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 {
InspectorStylePropertyInspectorStyleProperty104     explicit InspectorStyleProperty(CSSPropertySourceData sourceData)
105         : sourceData(sourceData)
106         , hasSource(true)
107     {
108     }
109 
InspectorStylePropertyInspectorStyleProperty110     InspectorStyleProperty(CSSPropertySourceData sourceData, bool hasSource)
111         : sourceData(sourceData)
112         , hasSource(hasSource)
113     {
114     }
115 
setRawTextFromStyleDeclarationInspectorStyleProperty116     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 
hasRawTextInspectorStyleProperty125     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 
cssStyle()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 toggleProperty(unsigned index, bool disable, ExceptionState&);
141     bool styleText(String* result) const;
142 
143 private:
144     InspectorStyle(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet);
145 
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:
Listener()167         Listener() { }
~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 
id()181     String id() const { return m_id; }
182     String finalURL() const;
183     virtual Document* ownerDocument() const;
canBind()184     bool canBind() const { return m_origin != TypeBuilder::CSS::StyleSheetOrigin::User_agent && m_origin != TypeBuilder::CSS::StyleSheetOrigin::User; }
pageStyleSheet()185     CSSStyleSheet* pageStyleSheet() const { return m_pageStyleSheet.get(); }
186     void reparseStyleSheet(const String&);
187     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     bool toggleProperty(const InspectorCSSId&, unsigned propertyIndex, bool disable, ExceptionState&);
200 
origin()201     virtual TypeBuilder::CSS::StyleSheetOrigin::Enum origin() const { return m_origin; }
202     virtual bool getText(String* result) const;
203     virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const;
204     void fireStyleSheetChanged();
205     PassRefPtr<TypeBuilder::CSS::SourceRange> ruleHeaderSourceRange(const CSSRule*);
206 
207     InspectorCSSId ruleId(CSSStyleRule*) const;
styleId(CSSStyleDeclaration * style)208     InspectorCSSId styleId(CSSStyleDeclaration* style) const { return ruleOrStyleId(style); }
209 
210 protected:
211     InspectorStyleSheet(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum, const String& documentURL, Listener*);
212 
213     InspectorCSSId ruleOrStyleId(CSSStyleDeclaration* style) const;
214     virtual PassRefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration*) const;
215     virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const;
216     virtual unsigned ruleIndexByRule(const CSSRule*) const;
217     virtual bool ensureParsedDataReady();
218     virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&);
219     virtual String sourceMapURL() const;
220     virtual String sourceURL() const;
221 
222     // Also accessed by friend class InspectorStyle.
223     virtual bool setStyleText(CSSStyleDeclaration*, const String&);
224     virtual PassOwnPtr<Vector<unsigned> > lineEndings() const;
225 
226 private:
227     friend class InspectorStyle;
228 
229     bool checkPageStyleSheet(ExceptionState&) const;
230     bool ensureText() const;
231     bool ensureSourceData();
232     void ensureFlatRules() const;
233     bool styleSheetTextWithChangedStyle(CSSStyleDeclaration*, const String& newStyleText, String* result);
234     void revalidateStyle(CSSStyleDeclaration*);
235     bool originalStyleSheetText(String* result) const;
236     bool resourceStyleSheetText(String* result) const;
237     bool inlineStyleSheetText(String* result) const;
238     PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::Selector> > selectorsFromSource(const CSSRuleSourceData*, const String&) const;
239     PassRefPtr<TypeBuilder::CSS::SelectorList> buildObjectForSelectorList(CSSStyleRule*);
240     String url() const;
241     bool hasSourceURL() const;
242     bool startsAtZero() const;
243 
244     InspectorPageAgent* m_pageAgent;
245     InspectorResourceAgent* m_resourceAgent;
246     String m_id;
247     RefPtr<CSSStyleSheet> m_pageStyleSheet;
248     TypeBuilder::CSS::StyleSheetOrigin::Enum m_origin;
249     String m_documentURL;
250     bool m_isRevalidating;
251     ParsedStyleSheet* m_parsedStyleSheet;
252     mutable CSSRuleVector m_flatRules;
253     Listener* m_listener;
254     mutable String m_sourceURL;
255 };
256 
257 class InspectorStyleSheetForInlineStyle : public InspectorStyleSheet {
258 public:
259     static PassRefPtr<InspectorStyleSheetForInlineStyle> create(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtr<Element>, TypeBuilder::CSS::StyleSheetOrigin::Enum, Listener*);
260 
261     void didModifyElementAttribute();
262     virtual bool getText(String* result) const;
styleForId(const InspectorCSSId & id)263     virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const { ASSERT_UNUSED(id, !id.ordinal()); return inlineStyle(); }
origin()264     virtual TypeBuilder::CSS::StyleSheetOrigin::Enum origin() const { return TypeBuilder::CSS::StyleSheetOrigin::Regular; }
265 
266 protected:
267     InspectorStyleSheetForInlineStyle(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtr<Element>, TypeBuilder::CSS::StyleSheetOrigin::Enum, Listener*);
268 
269     virtual Document* ownerDocument() const;
ruleSourceDataFor(CSSStyleDeclaration * style)270     virtual PassRefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const { ASSERT_UNUSED(style, style == inlineStyle()); return m_ruleSourceData; }
ruleIndexByStyle(CSSStyleDeclaration *)271     virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const { return 0; }
272     virtual bool ensureParsedDataReady();
273     virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&);
sourceMapURL()274     virtual String sourceMapURL() const OVERRIDE { return String(); }
sourceURL()275     virtual String sourceURL() const OVERRIDE { return String(); }
276 
277     // Also accessed by friend class InspectorStyle.
278     virtual bool setStyleText(CSSStyleDeclaration*, const String&);
279     virtual PassOwnPtr<Vector<unsigned> > lineEndings() const;
280 
281 private:
282     CSSStyleDeclaration* inlineStyle() const;
283     const String& elementStyleText() const;
284     PassRefPtr<CSSRuleSourceData> getStyleAttributeData() const;
285 
286     RefPtr<Element> m_element;
287     RefPtr<CSSRuleSourceData> m_ruleSourceData;
288     RefPtr<InspectorStyle> m_inspectorStyle;
289 
290     // Contains "style" attribute value.
291     mutable String m_styleText;
292     mutable bool m_isStyleTextValid;
293 };
294 
295 
296 } // namespace WebCore
297 
298 #endif // !defined(InspectorStyleSheet_h)
299