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