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