Home | History | Annotate | Download | only in inspector
      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 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:
    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     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 
    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;
    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;
    263     virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const { ASSERT_UNUSED(id, !id.ordinal()); return inlineStyle(); }
    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;
    270     virtual PassRefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const { ASSERT_UNUSED(style, style == inlineStyle()); return m_ruleSourceData; }
    271     virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const { return 0; }
    272     virtual bool ensureParsedDataReady();
    273     virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&);
    274     virtual String sourceMapURL() const OVERRIDE { return String(); }
    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