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 "CSSPropertySourceData.h"
     29 #include "InspectorValues.h"
     30 #include "PlatformString.h"
     31 
     32 #include <wtf/HashMap.h>
     33 #include <wtf/HashSet.h>
     34 #include <wtf/PassRefPtr.h>
     35 #include <wtf/RefPtr.h>
     36 #include <wtf/Vector.h>
     37 
     38 class ParsedStyleSheet;
     39 
     40 namespace WebCore {
     41 
     42 class CSSRuleList;
     43 class CSSStyleDeclaration;
     44 class CSSStyleSheet;
     45 class Document;
     46 class Element;
     47 class InspectorStyleSheet;
     48 class Node;
     49 
     50 #if ENABLE(INSPECTOR)
     51 
     52 typedef String ErrorString;
     53 
     54 class InspectorCSSId {
     55 public:
     56     InspectorCSSId() { }
     57 
     58     explicit InspectorCSSId(RefPtr<InspectorObject> value)
     59     {
     60         if (!value->getString("styleSheetId", &m_styleSheetId))
     61             return;
     62 
     63         RefPtr<InspectorValue> ordinalValue = value->get("ordinal");
     64         if (!ordinalValue || !ordinalValue->asNumber(&m_ordinal))
     65             m_styleSheetId = "";
     66     }
     67 
     68     InspectorCSSId(const String& styleSheetId, unsigned ordinal)
     69         : m_styleSheetId(styleSheetId)
     70         , m_ordinal(ordinal)
     71     {
     72     }
     73 
     74     bool isEmpty() const { return m_styleSheetId.isEmpty(); }
     75 
     76     const String& styleSheetId() const { return m_styleSheetId; }
     77     unsigned ordinal() const { return m_ordinal; }
     78 
     79     PassRefPtr<InspectorValue> asInspectorValue() const
     80     {
     81         if (isEmpty())
     82             return InspectorValue::null();
     83 
     84         RefPtr<InspectorObject> result = InspectorObject::create();
     85         result->setString("styleSheetId", m_styleSheetId);
     86         result->setNumber("ordinal", m_ordinal);
     87         return result.release();
     88     }
     89 
     90 private:
     91     String m_styleSheetId;
     92     unsigned m_ordinal;
     93 };
     94 
     95 struct InspectorStyleProperty {
     96     InspectorStyleProperty()
     97     {
     98     }
     99 
    100     InspectorStyleProperty(CSSPropertySourceData sourceData, bool hasSource, bool disabled)
    101         : sourceData(sourceData)
    102         , hasSource(hasSource)
    103         , disabled(disabled)
    104     {
    105     }
    106 
    107     void setRawTextFromStyleDeclaration(const String& styleDeclaration)
    108     {
    109         unsigned start = sourceData.range.start;
    110         unsigned end = sourceData.range.end;
    111         ASSERT(start < end);
    112         ASSERT(end <= styleDeclaration.length());
    113         rawText = styleDeclaration.substring(start, end - start);
    114     }
    115 
    116     bool hasRawText() const { return !rawText.isEmpty(); }
    117 
    118     CSSPropertySourceData sourceData;
    119     bool hasSource;
    120     bool disabled;
    121     String rawText;
    122 };
    123 
    124 class InspectorStyle : public RefCounted<InspectorStyle> {
    125 public:
    126     static PassRefPtr<InspectorStyle> create(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet);
    127     virtual ~InspectorStyle();
    128 
    129     CSSStyleDeclaration* cssStyle() const { return m_style.get(); }
    130     PassRefPtr<InspectorObject> buildObjectForStyle() const;
    131     bool hasDisabledProperties() const { return !m_disabledProperties.isEmpty(); }
    132     bool setPropertyText(ErrorString*, unsigned index, const String& text, bool overwrite);
    133     bool toggleProperty(ErrorString*, unsigned index, bool disable);
    134 
    135 private:
    136     InspectorStyle(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet);
    137 
    138     static unsigned disabledIndexByOrdinal(unsigned ordinal, bool canUseSubsequent, Vector<InspectorStyleProperty>& allProperties);
    139 
    140     bool styleText(String* result) const;
    141     bool disableProperty(unsigned indexToDisable, Vector<InspectorStyleProperty>& allProperties);
    142     bool enableProperty(unsigned indexToEnable, Vector<InspectorStyleProperty>& allProperties);
    143     bool populateAllProperties(Vector<InspectorStyleProperty>* result) const;
    144     void populateObjectWithStyleProperties(InspectorObject* result) const;
    145     void shiftDisabledProperties(unsigned fromIndex, long offset);
    146     bool replacePropertyInStyleText(const InspectorStyleProperty& property, const String& newText);
    147     String shorthandValue(const String& shorthandProperty) const;
    148     String shorthandPriority(const String& shorthandProperty) const;
    149     Vector<String> longhandProperties(const String& shorthandProperty) const;
    150 
    151     InspectorCSSId m_styleId;
    152     RefPtr<CSSStyleDeclaration> m_style;
    153     InspectorStyleSheet* m_parentStyleSheet;
    154     Vector<InspectorStyleProperty> m_disabledProperties;
    155 };
    156 
    157 class InspectorStyleSheet : public RefCounted<InspectorStyleSheet> {
    158 public:
    159     typedef HashMap<CSSStyleDeclaration*, RefPtr<InspectorStyle> > InspectorStyleMap;
    160     static PassRefPtr<InspectorStyleSheet> create(const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, const String& origin, const String& documentURL);
    161 
    162     virtual ~InspectorStyleSheet();
    163 
    164     String id() const { return m_id; }
    165     String finalURL() const;
    166     CSSStyleSheet* pageStyleSheet() const { return m_pageStyleSheet.get(); }
    167     void reparseStyleSheet(const String&);
    168     bool setText(const String&);
    169     bool setRuleSelector(const InspectorCSSId&, const String& selector);
    170     CSSStyleRule* addRule(const String& selector);
    171     CSSStyleRule* ruleForId(const InspectorCSSId&) const;
    172     PassRefPtr<InspectorObject> buildObjectForStyleSheet();
    173     PassRefPtr<InspectorObject> buildObjectForStyleSheetInfo();
    174     PassRefPtr<InspectorObject> buildObjectForRule(CSSStyleRule*);
    175     PassRefPtr<InspectorObject> buildObjectForStyle(CSSStyleDeclaration*);
    176     bool setPropertyText(ErrorString*, const InspectorCSSId&, unsigned propertyIndex, const String& text, bool overwrite);
    177     bool toggleProperty(ErrorString*, const InspectorCSSId&, unsigned propertyIndex, bool disable);
    178 
    179     virtual bool text(String* result) const;
    180     virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const;
    181 
    182 protected:
    183     InspectorStyleSheet(const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, const String& origin, const String& documentURL);
    184 
    185     bool canBind() const { return m_origin != "userAgent" && m_origin != "user"; }
    186     InspectorCSSId ruleOrStyleId(CSSStyleDeclaration* style) const;
    187     virtual Document* ownerDocument() const;
    188     virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const;
    189     virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const;
    190     virtual bool ensureParsedDataReady();
    191     virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&);
    192     virtual void rememberInspectorStyle(RefPtr<InspectorStyle> inspectorStyle);
    193     virtual void forgetInspectorStyle(CSSStyleDeclaration* style);
    194 
    195     // Also accessed by friend class InspectorStyle.
    196     virtual bool setStyleText(CSSStyleDeclaration*, const String&);
    197 
    198 private:
    199     static void fixUnparsedPropertyRanges(CSSRuleSourceData* ruleData, const String& styleSheetText);
    200     static void collectFlatRules(PassRefPtr<CSSRuleList>, Vector<CSSStyleRule*>* result);
    201     bool ensureText() const;
    202     bool ensureSourceData();
    203     void ensureFlatRules() const;
    204     bool styleSheetTextWithChangedStyle(CSSStyleDeclaration*, const String& newStyleText, String* result);
    205     InspectorCSSId ruleId(CSSStyleRule* rule) const;
    206     InspectorCSSId styleId(CSSStyleDeclaration* style) const { return ruleOrStyleId(style); }
    207     void revalidateStyle(CSSStyleDeclaration*);
    208     bool originalStyleSheetText(String* result) const;
    209     bool resourceStyleSheetText(String* result) const;
    210     bool inlineStyleSheetText(String* result) const;
    211     PassRefPtr<InspectorArray> buildArrayForRuleList(CSSRuleList*);
    212 
    213     String m_id;
    214     RefPtr<CSSStyleSheet> m_pageStyleSheet;
    215     String m_origin;
    216     String m_documentURL;
    217     bool m_isRevalidating;
    218     ParsedStyleSheet* m_parsedStyleSheet;
    219     InspectorStyleMap m_inspectorStyles;
    220     mutable Vector<CSSStyleRule*> m_flatRules;
    221 
    222     friend class InspectorStyle;
    223 };
    224 
    225 class InspectorStyleSheetForInlineStyle : public InspectorStyleSheet {
    226 public:
    227     static PassRefPtr<InspectorStyleSheetForInlineStyle> create(const String& id, PassRefPtr<Element> element, const String& origin);
    228 
    229     void didModifyElementAttribute();
    230     virtual bool text(String* result) const;
    231     virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const { ASSERT_UNUSED(id, !id.ordinal()); return inlineStyle(); }
    232 
    233 protected:
    234     InspectorStyleSheetForInlineStyle(const String& id, PassRefPtr<Element> element, const String& origin);
    235 
    236     virtual Document* ownerDocument() const;
    237     virtual RefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const { ASSERT_UNUSED(style, style == inlineStyle()); return m_ruleSourceData; }
    238     virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const { return 0; }
    239     virtual bool ensureParsedDataReady();
    240     virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&);
    241     virtual void rememberInspectorStyle(RefPtr<InspectorStyle>) { }
    242     virtual void forgetInspectorStyle(CSSStyleDeclaration*) { }
    243 
    244     // Also accessed by friend class InspectorStyle.
    245     virtual bool setStyleText(CSSStyleDeclaration*, const String&);
    246 
    247 private:
    248     CSSStyleDeclaration* inlineStyle() const;
    249     const String& elementStyleText() const;
    250     bool getStyleAttributeRanges(RefPtr<CSSStyleSourceData>* result);
    251 
    252     RefPtr<Element> m_element;
    253     RefPtr<CSSRuleSourceData> m_ruleSourceData;
    254     RefPtr<InspectorStyle> m_inspectorStyle;
    255 
    256     // Contains "style" attribute value and should always be up-to-date.
    257     String m_styleText;
    258 };
    259 
    260 #endif
    261 
    262 } // namespace WebCore
    263 
    264 #endif // !defined(InspectorStyleSheet_h)
    265