15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010, Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1.  Redistributions of source code must retain the above copyright
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer.
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2.  Redistributions in binary form must reproduce the above copyright
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer in the
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     documentation and/or other materials provided with the distribution.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorStyleSheet.h"
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "CSSPropertyNames.h"
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "HTMLNames.h"
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "SVGNames.h"
31df95704c49daea886ddad70775bda23618d6274dBen Murdoch#include "bindings/v8/ExceptionState.h"
32df95704c49daea886ddad70775bda23618d6274dBen Murdoch#include "bindings/v8/ExceptionStatePlaceholder.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSHostRule.h"
345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "core/css/CSSKeyframesRule.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSMediaRule.h"
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSParser.h"
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSPropertySourceData.h"
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSRule.h"
3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSRuleList.h"
4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSStyleRule.h"
4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSStyleSheet.h"
4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSSupportsRule.h"
4353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/StylePropertySet.h"
4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/StyleRule.h"
4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/StyleSheetContents.h"
4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Element.h"
4853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Node.h"
4953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/parser/HTMLParserIdioms.h"
5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/ContentSearchUtils.h"
5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorCSSAgent.h"
5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorPageAgent.h"
535267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "core/page/Page.h"
545267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "core/page/PageConsole.h"
55591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/platform/JSONValues.h"
5653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/text/RegularExpression.h"
57591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/OwnPtr.h"
58591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/PassOwnPtr.h"
59591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/Vector.h"
60591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/text/StringBuilder.h"
61591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/text/TextPosition.h"
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using WebCore::TypeBuilder::Array;
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using WebCore::RuleSourceDataList;
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using WebCore::CSSRuleSourceData;
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class ParsedStyleSheet {
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    WTF_MAKE_FAST_ALLOCATED;
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ParsedStyleSheet();
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
72926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const String& text() const { ASSERT(m_hasText); return m_text; }
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setText(const String& text);
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool hasText() const { return m_hasText; }
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setSourceData(PassOwnPtr<RuleSourceDataList>);
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool hasSourceData() const { return m_sourceData; }
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    PassRefPtr<WebCore::CSSRuleSourceData> ruleSourceDataAt(unsigned) const;
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
80521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    void flattenSourceData(RuleSourceDataList*);
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String m_text;
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_hasText;
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    OwnPtr<RuleSourceDataList> m_sourceData;
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ParsedStyleSheet::ParsedStyleSheet()
88fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    : m_hasText(false)
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ParsedStyleSheet::setText(const String& text)
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_hasText = true;
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_text = text;
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setSourceData(nullptr);
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
99521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void ParsedStyleSheet::flattenSourceData(RuleSourceDataList* dataList)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < dataList->size(); ++i) {
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RefPtr<CSSRuleSourceData>& data = dataList->at(i);
103521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if (data->type == CSSRuleSourceData::STYLE_RULE) {
104521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            m_sourceData->append(data);
105521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        } else if (data->type == CSSRuleSourceData::IMPORT_RULE) {
106521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            m_sourceData->append(data);
107521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        } else if (data->type == CSSRuleSourceData::MEDIA_RULE) {
108521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            m_sourceData->append(data);
109521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            flattenSourceData(&data->childRules);
110521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        } else if (data->type == CSSRuleSourceData::HOST_RULE) {
111521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            flattenSourceData(&data->childRules);
112521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        } else if (data->type == CSSRuleSourceData::SUPPORTS_RULE) {
113521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            flattenSourceData(&data->childRules);
114521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        }
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ParsedStyleSheet::setSourceData(PassOwnPtr<RuleSourceDataList> sourceData)
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!sourceData) {
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_sourceData.clear();
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_sourceData = adoptPtr(new RuleSourceDataList());
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: This is a temporary solution to retain the original flat sourceData structure
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // containing only style rules, even though CSSParser now provides the full rule source data tree.
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Normally, we should just assign m_sourceData = sourceData;
130521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    flattenSourceData(sourceData.get());
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<WebCore::CSSRuleSourceData> ParsedStyleSheet::ruleSourceDataAt(unsigned index) const
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!hasSourceData() || index >= m_sourceData->size())
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_sourceData->at(index);
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static PassOwnPtr<CSSParser> createCSSParser(Document* document)
14453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
14593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    UseCounter* counter = 0;
14693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return adoptPtr(new CSSParser(document ? CSSParserContext(document) : strictCSSParserContext(), counter));
14753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
14853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
14953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)namespace {
15053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
15153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)class StyleSheetHandler : public CSSParser::SourceDataHandler {
15253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)public:
15353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    StyleSheetHandler(const String& parsedText, Document* document, StyleSheetContents* styleSheetContents, RuleSourceDataList* result)
15453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        : m_parsedText(parsedText)
15553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_document(document)
15653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_styleSheetContents(styleSheetContents)
15753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_result(result)
15853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_propertyRangeStart(UINT_MAX)
15953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_selectorRangeStart(UINT_MAX)
16053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        , m_commentRangeStart(UINT_MAX)
16153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
16253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        ASSERT(m_result);
16353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
16453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
16553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)private:
16653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void startRuleHeader(CSSRuleSourceData::Type, unsigned) OVERRIDE;
16753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void endRuleHeader(unsigned) OVERRIDE;
16853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void startSelector(unsigned) OVERRIDE;
16953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void endSelector(unsigned) OVERRIDE;
17053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void startRuleBody(unsigned) OVERRIDE;
17153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void endRuleBody(unsigned, bool) OVERRIDE;
17253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void startEndUnknownRule() OVERRIDE { addNewRuleToSourceTree(CSSRuleSourceData::createUnknown()); }
17353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void startProperty(unsigned) OVERRIDE;
17493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    virtual void endProperty(bool, bool, unsigned, CSSParser::ErrorType) OVERRIDE;
17553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void startComment(unsigned) OVERRIDE;
17653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    virtual void endComment(unsigned) OVERRIDE;
17753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
17853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    void addNewRuleToSourceTree(PassRefPtr<CSSRuleSourceData>);
17953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    PassRefPtr<CSSRuleSourceData> popRuleData();
18053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    template <typename CharacterType> inline void setRuleHeaderEnd(const CharacterType*, unsigned);
18153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    void fixUnparsedPropertyRanges(CSSRuleSourceData*);
18253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
18353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const String& m_parsedText;
18453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    Document* m_document;
18553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    StyleSheetContents* m_styleSheetContents;
18653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RuleSourceDataList* m_result;
18753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RuleSourceDataList m_currentRuleDataStack;
18853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RefPtr<CSSRuleSourceData> m_currentRuleData;
18953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    OwnPtr<CSSParser> m_commentParser;
19053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    unsigned m_propertyRangeStart;
19153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    unsigned m_selectorRangeStart;
19253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    unsigned m_commentRangeStart;
19353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)};
19453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
19553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void StyleSheetHandler::startRuleHeader(CSSRuleSourceData::Type type, unsigned offset)
19653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
19753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Pop off data for a previous invalid rule.
19853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_currentRuleData)
19953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_currentRuleDataStack.removeLast();
20053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
20153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RefPtr<CSSRuleSourceData> data = CSSRuleSourceData::create(type);
20253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    data->ruleHeaderRange.start = offset;
20353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_currentRuleData = data;
20453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_currentRuleDataStack.append(data.release());
20553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
20653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
20753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)template <typename CharacterType>
20853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)inline void StyleSheetHandler::setRuleHeaderEnd(const CharacterType* dataStart, unsigned listEndOffset)
20953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
21053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    while (listEndOffset > 1) {
21153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (isHTMLSpace(*(dataStart + listEndOffset - 1)))
21253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            --listEndOffset;
21353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        else
21453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
21553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
21653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
21753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_currentRuleDataStack.last()->ruleHeaderRange.end = listEndOffset;
21853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
21953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
22053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void StyleSheetHandler::endRuleHeader(unsigned offset)
22153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
22253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(!m_currentRuleDataStack.isEmpty());
22353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
22453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_parsedText.is8Bit())
22553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        setRuleHeaderEnd<LChar>(m_parsedText.characters8(), offset);
22653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    else
22753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        setRuleHeaderEnd<UChar>(m_parsedText.characters16(), offset);
22853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
22953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
23053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void StyleSheetHandler::startSelector(unsigned offset)
23153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
23253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_selectorRangeStart = offset;
23353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
23453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
23553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void StyleSheetHandler::endSelector(unsigned offset)
23653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
23753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(m_currentRuleDataStack.size());
23853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_currentRuleDataStack.last()->selectorRanges.append(SourceRange(m_selectorRangeStart, offset));
23953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_selectorRangeStart = UINT_MAX;
24053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
24153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
24253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void StyleSheetHandler::startRuleBody(unsigned offset)
24353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
24453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_currentRuleData.clear();
24553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(!m_currentRuleDataStack.isEmpty());
24653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_parsedText[offset] == '{')
24753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        ++offset; // Skip the rule body opening brace.
24853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_currentRuleDataStack.last()->ruleBodyRange.start = offset;
24953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
25053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
25153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void StyleSheetHandler::endRuleBody(unsigned offset, bool error)
25253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
25353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(!m_currentRuleDataStack.isEmpty());
25453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_currentRuleDataStack.last()->ruleBodyRange.end = offset;
25553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_propertyRangeStart = UINT_MAX;
25653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RefPtr<CSSRuleSourceData> rule = popRuleData();
25753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (error)
25853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
25953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
26053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    fixUnparsedPropertyRanges(rule.get());
26153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    addNewRuleToSourceTree(rule.release());
26253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
26353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
26453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void StyleSheetHandler::addNewRuleToSourceTree(PassRefPtr<CSSRuleSourceData> rule)
26553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
26653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_currentRuleDataStack.isEmpty())
26753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_result->append(rule);
26853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    else
26953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_currentRuleDataStack.last()->childRules.append(rule);
27053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
27153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
27253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)PassRefPtr<CSSRuleSourceData> StyleSheetHandler::popRuleData()
27353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
27453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(!m_currentRuleDataStack.isEmpty());
27553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_currentRuleData.clear();
27653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RefPtr<CSSRuleSourceData> data = m_currentRuleDataStack.last();
27753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_currentRuleDataStack.removeLast();
27853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return data.release();
27953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
28053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
28153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)template <typename CharacterType>
28253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static inline void fixUnparsedProperties(const CharacterType* characters, CSSRuleSourceData* ruleData)
28353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
28453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    Vector<CSSPropertySourceData>& propertyData = ruleData->styleSourceData->propertyData;
28553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    unsigned size = propertyData.size();
28653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!size)
28753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
28853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
28953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    unsigned styleStart = ruleData->ruleBodyRange.start;
29053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    CSSPropertySourceData* nextData = &(propertyData.at(0));
29153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for (unsigned i = 0; i < size; ++i) {
29253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        CSSPropertySourceData* currentData = nextData;
29353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        nextData = i < size - 1 ? &(propertyData.at(i + 1)) : 0;
29453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
29553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (currentData->parsedOk)
29653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            continue;
29753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (currentData->range.end > 0 && characters[styleStart + currentData->range.end - 1] == ';')
29853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            continue;
29953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
30053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        unsigned propertyEndInStyleSheet;
30153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (!nextData)
30253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            propertyEndInStyleSheet = ruleData->ruleBodyRange.end - 1;
30353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        else
30453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            propertyEndInStyleSheet = styleStart + nextData->range.start - 1;
30553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
30653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        while (isHTMLSpace(characters[propertyEndInStyleSheet]))
30753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            --propertyEndInStyleSheet;
30853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
30953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // propertyEndInStyleSheet points at the last property text character.
31053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        unsigned newPropertyEnd = propertyEndInStyleSheet - styleStart + 1; // Exclusive of the last property text character.
31153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (currentData->range.end != newPropertyEnd) {
31253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            currentData->range.end = newPropertyEnd;
31353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            unsigned valueStartInStyleSheet = styleStart + currentData->range.start + currentData->name.length();
31453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            while (valueStartInStyleSheet < propertyEndInStyleSheet && characters[valueStartInStyleSheet] != ':')
31553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                ++valueStartInStyleSheet;
31653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (valueStartInStyleSheet < propertyEndInStyleSheet)
31753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                ++valueStartInStyleSheet; // Shift past the ':'.
31853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            while (valueStartInStyleSheet < propertyEndInStyleSheet && isHTMLSpace(characters[valueStartInStyleSheet]))
31953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                ++valueStartInStyleSheet;
32053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            // Need to exclude the trailing ';' from the property value.
32153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            currentData->value = String(characters + valueStartInStyleSheet, propertyEndInStyleSheet - valueStartInStyleSheet + (characters[propertyEndInStyleSheet] == ';' ? 0 : 1));
32253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
32353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
32453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
32553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
32653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void StyleSheetHandler::fixUnparsedPropertyRanges(CSSRuleSourceData* ruleData)
32753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
32853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!ruleData->styleSourceData)
32953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
33053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
33153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_parsedText.is8Bit()) {
33253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        fixUnparsedProperties<LChar>(m_parsedText.characters8(), ruleData);
33353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
33453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
33553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
33653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    fixUnparsedProperties<UChar>(m_parsedText.characters16(), ruleData);
33753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
33853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
33953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void StyleSheetHandler::startProperty(unsigned offset)
34053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
34153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_currentRuleDataStack.isEmpty() || !m_currentRuleDataStack.last()->styleSourceData)
34253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
34353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_propertyRangeStart = offset;
34453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
34553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
34693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void StyleSheetHandler::endProperty(bool isImportant, bool isParsed, unsigned offset, CSSParser::ErrorType errorType)
34753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
34893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (errorType != CSSParser::NoError)
34953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_propertyRangeStart = UINT_MAX;
35053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
35153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_propertyRangeStart == UINT_MAX || m_currentRuleDataStack.isEmpty() || !m_currentRuleDataStack.last()->styleSourceData)
35253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
35353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
35453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(offset <= m_parsedText.length());
35553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (offset < m_parsedText.length() && m_parsedText[offset] == ';') // Include semicolon into the property text.
35653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        ++offset;
35753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
35853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const unsigned start = m_propertyRangeStart;
35953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const unsigned end = offset;
36053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(start < end);
36153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String propertyString = m_parsedText.substring(start, end - start).stripWhiteSpace();
36253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (propertyString.endsWith(';'))
36353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        propertyString = propertyString.left(propertyString.length() - 1);
36453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    size_t colonIndex = propertyString.find(':');
36553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(colonIndex != notFound);
36653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
36753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String name = propertyString.left(colonIndex).stripWhiteSpace();
36853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String value = propertyString.substring(colonIndex + 1, propertyString.length()).stripWhiteSpace();
36953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // The property range is relative to the declaration start offset.
37053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    unsigned topRuleBodyRangeStart = m_currentRuleDataStack.last()->ruleBodyRange.start;
37153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_currentRuleDataStack.last()->styleSourceData->propertyData.append(
37253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        CSSPropertySourceData(name, value, isImportant, false, isParsed, SourceRange(start - topRuleBodyRangeStart, end - topRuleBodyRangeStart)));
37353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_propertyRangeStart = UINT_MAX;
37453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
37553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
37653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void StyleSheetHandler::startComment(unsigned offset)
37753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
37853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(m_commentRangeStart == UINT_MAX);
37953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_commentRangeStart = offset;
38053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
38153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
38253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void StyleSheetHandler::endComment(unsigned offset)
38353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
38453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(offset <= m_parsedText.length());
38553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
38653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    unsigned startOffset = m_commentRangeStart;
38753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_commentRangeStart = UINT_MAX;
38853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_propertyRangeStart != UINT_MAX) {
38953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        ASSERT(startOffset >= m_propertyRangeStart);
39053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // startProperty() is called automatically at the start of a style declaration.
39153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // Check if no text has been scanned yet, otherwise the comment is inside a property.
39253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (!m_parsedText.substring(m_propertyRangeStart, startOffset).stripWhiteSpace().isEmpty())
39353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            return;
39453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_propertyRangeStart = UINT_MAX;
39553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
39653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (m_currentRuleDataStack.isEmpty() || !m_currentRuleDataStack.last()->ruleHeaderRange.end || !m_currentRuleDataStack.last()->styleSourceData)
39753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
39853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
39953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // The lexer is not inside a property AND it is scanning a declaration-aware rule body.
40053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String commentText = m_parsedText.substring(startOffset, offset - startOffset);
40153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
40253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(commentText.startsWith("/*"));
40353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    commentText = commentText.substring(2);
40453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
40553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Require well-formed comments.
40653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!commentText.endsWith("*/"))
40753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
40853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    commentText = commentText.substring(0, commentText.length() - 2).stripWhiteSpace();
40953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (commentText.isEmpty())
41053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
41153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
41253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // FIXME: Use the actual rule type rather than STYLE_RULE?
41353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!m_commentParser)
41453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_commentParser = createCSSParser(m_document);
41553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RuleSourceDataList sourceData;
41653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
41753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // FIXME: Use another subclass of CSSParser::SourceDataHandler and assert that
41853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // no comments are encountered (will not need m_document and m_styleSheetContents).
41953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    StyleSheetHandler handler(commentText, m_document, m_styleSheetContents, &sourceData);
42093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    RefPtr<MutableStylePropertySet> tempMutableStyle = MutableStylePropertySet::create();
42153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_commentParser->parseDeclaration(tempMutableStyle.get(), commentText, &handler, m_styleSheetContents);
42253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    Vector<CSSPropertySourceData>& commentPropertyData = sourceData.first()->styleSourceData->propertyData;
42353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (commentPropertyData.size() != 1)
42453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
42553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    CSSPropertySourceData& propertyData = commentPropertyData.at(0);
42653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (propertyData.range.length() != commentText.length())
42753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
42853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
42953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    unsigned topRuleBodyRangeStart = m_currentRuleDataStack.last()->ruleBodyRange.start;
43053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_currentRuleDataStack.last()->styleSourceData->propertyData.append(
43153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        CSSPropertySourceData(propertyData.name, propertyData.value, false, true, true, SourceRange(startOffset - topRuleBodyRangeStart, offset - topRuleBodyRangeStart)));
43253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
43353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
43453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} // namespace
43553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum MediaListSource {
4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MediaListSourceLinkedSheet,
4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MediaListSourceInlineSheet,
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MediaListSourceMediaRule,
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MediaListSourceImportRule
4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
443591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic PassRefPtr<TypeBuilder::CSS::SourceRange> buildSourceRangeObject(const SourceRange& range, Vector<unsigned>* lineEndings)
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
445926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!lineEndings)
446926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return 0;
447591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    TextPosition start = TextPosition::fromOffsetAndLineEndings(range.start, *lineEndings);
448591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    TextPosition end = TextPosition::fromOffsetAndLineEndings(range.end, *lineEndings);
449926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<TypeBuilder::CSS::SourceRange> result = TypeBuilder::CSS::SourceRange::create()
451926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        .setStartLine(start.m_line.zeroBasedInt())
452926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        .setStartColumn(start.m_column.zeroBasedInt())
453926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        .setEndLine(end.m_line.zeroBasedInt())
454926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        .setEndColumn(end.m_column.zeroBasedInt());
4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.release();
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static PassRefPtr<CSSRuleList> asCSSRuleList(CSSStyleSheet* styleSheet)
4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!styleSheet)
4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<StaticCSSRuleList> list = StaticCSSRuleList::create();
4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<RefPtr<CSSRule> >& listRules = list->rules();
4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) {
4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        CSSRule* item = styleSheet->item(i);
467926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (item->type() == CSSRule::CHARSET_RULE)
4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        listRules.append(item);
4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return list.release();
4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static PassRefPtr<CSSRuleList> asCSSRuleList(CSSRule* rule)
4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!rule)
4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
479926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (rule->type() == CSSRule::MEDIA_RULE)
4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return static_cast<CSSMediaRule*>(rule)->cssRules();
4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
482926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (rule->type() == CSSRule::WEBKIT_KEYFRAMES_RULE)
4835267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return static_cast<CSSKeyframesRule*>(rule)->cssRules();
4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
485926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (rule->type() == CSSRule::HOST_RULE)
486926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return static_cast<CSSHostRule*>(rule)->cssRules();
487926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
488926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (rule->type() == CSSRule::SUPPORTS_RULE)
489926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return static_cast<CSSSupportsRule*>(rule)->cssRules();
490926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<InspectorStyle> InspectorStyle::create(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet)
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return adoptRef(new InspectorStyle(styleId, style, parentStyleSheet));
4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InspectorStyle::InspectorStyle(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet)
5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_styleId(styleId)
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_style(style)
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_parentStyleSheet(parentStyleSheet)
5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_formatAcquired(false)
5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_style);
5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InspectorStyle::~InspectorStyle()
5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorStyle::buildObjectForStyle() const
5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<TypeBuilder::CSS::CSSStyle> result = styleWithProperties();
5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_styleId.isEmpty())
5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result->setStyleId(m_styleId.asProtocolValue<TypeBuilder::CSS::CSSStyleId>());
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result->setWidth(m_style->getPropertyValue("width"));
5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result->setHeight(m_style->getPropertyValue("height"));
5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
521926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RefPtr<CSSRuleSourceData> sourceData = extractSourceData();
5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (sourceData)
523926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        result->setRange(buildSourceRangeObject(sourceData->ruleBodyRange, m_parentStyleSheet->lineEndings().get()));
5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.release();
5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> > InspectorStyle::buildArrayForComputedStyle() const
5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> > result = TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty>::create();
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<InspectorStyleProperty> properties;
53253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    populateAllProperties(properties);
5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (Vector<InspectorStyleProperty>::iterator it = properties.begin(), itEnd = properties.end(); it != itEnd; ++it) {
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const CSSPropertySourceData& propertyEntry = it->sourceData;
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RefPtr<TypeBuilder::CSS::CSSComputedStyleProperty> entry = TypeBuilder::CSS::CSSComputedStyleProperty::create()
5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            .setName(propertyEntry.name)
5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            .setValue(propertyEntry.value);
5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result->addItem(entry);
5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.release();
5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This method does the following preprocessing of |propertyText| with |overwrite| == false and |index| past the last active property:
5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// - If the last property (if present) has no closing ";", the ";" is prepended to the current |propertyText| value.
5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// - A heuristic formatting is attempted to retain the style structure.
5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// The propertyText (if not empty) is checked to be a valid style declaration (containing at least one property). If not,
5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// the method returns false (denoting an error).
551df95704c49daea886ddad70775bda23618d6274dBen Murdochbool InspectorStyle::setPropertyText(unsigned index, const String& propertyText, bool overwrite, String* oldText, ExceptionState& es)
5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_parentStyleSheet);
554d24c94b5090b6aa121f0f82325c9379004dc3196Ben Murdoch    DEFINE_STATIC_LOCAL(String, bogusPropertyName, ("-webkit-boguz-propertee"));
5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_parentStyleSheet->ensureParsedDataReady()) {
557df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
56153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!propertyText.stripWhiteSpace().isEmpty()) {
56293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        RefPtr<MutableStylePropertySet> tempMutableStyle = MutableStylePropertySet::create();
56353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        String declarationText = propertyText + " " + bogusPropertyName + ": none";
56453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        RuleSourceDataList sourceData;
56553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        StyleSheetHandler handler(declarationText, ownerDocument(), m_style->parentStyleSheet()->contents(), &sourceData);
56653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        createCSSParser(ownerDocument())->parseDeclaration(tempMutableStyle.get(), declarationText, &handler, m_style->parentStyleSheet()->contents());
56753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        Vector<CSSPropertySourceData>& propertyData = sourceData.first()->styleSourceData->propertyData;
5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        unsigned propertyCount = propertyData.size();
5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // At least one property + the bogus property added just above should be present.
5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (propertyCount < 2) {
572df95704c49daea886ddad70775bda23618d6274dBen Murdoch            es.throwDOMException(SyntaxError);
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
57653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // Check for the proper propertyText termination (the parser could at least restore to the PROPERTY_NAME state).
5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (propertyData.at(propertyCount - 1).name != bogusPropertyName) {
578df95704c49daea886ddad70775bda23618d6274dBen Murdoch            es.throwDOMException(SyntaxError);
5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
583926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RefPtr<CSSRuleSourceData> sourceData = extractSourceData();
5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!sourceData) {
585df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String text;
5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool success = styleText(&text);
5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!success) {
592df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
596fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    Vector<InspectorStyleProperty> allProperties;
597fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    populateAllProperties(allProperties);
598fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
59953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    InspectorStyleTextEditor editor(&allProperties, text, newLineAndWhitespaceDelimiters());
6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (overwrite) {
6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (index >= allProperties.size()) {
602df95704c49daea886ddad70775bda23618d6274dBen Murdoch            es.throwDOMException(IndexSizeError);
6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *oldText = allProperties.at(index).rawText;
6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        editor.replaceProperty(index, propertyText);
6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else
6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        editor.insertProperty(index, propertyText, sourceData->ruleBodyRange.length());
6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return applyStyleText(editor.styleText());
6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
613df95704c49daea886ddad70775bda23618d6274dBen Murdochbool InspectorStyle::toggleProperty(unsigned index, bool disable, ExceptionState& es)
6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_parentStyleSheet);
6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_parentStyleSheet->ensureParsedDataReady()) {
617df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NoModificationAllowedError);
6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
621926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RefPtr<CSSRuleSourceData> sourceData = extractSourceData();
6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!sourceData) {
623df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String text;
6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool success = styleText(&text);
6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!success) {
630df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<InspectorStyleProperty> allProperties;
63553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    populateAllProperties(allProperties);
6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (index >= allProperties.size()) {
637df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(IndexSizeError);
6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InspectorStyleProperty& property = allProperties.at(index);
64253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (property.sourceData.disabled == disable)
6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true; // Idempotent operation.
6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
64553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    InspectorStyleTextEditor editor(&allProperties, text, newLineAndWhitespaceDelimiters());
6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (disable)
6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        editor.disableProperty(index);
6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        editor.enableProperty(index);
6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return applyStyleText(editor.styleText());
6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorStyle::styleText(String* result) const
6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
656926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RefPtr<CSSRuleSourceData> sourceData = extractSourceData();
6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!sourceData)
6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String styleSheetText;
6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool success = m_parentStyleSheet->getText(&styleSheetText);
6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!success)
6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SourceRange& bodyRange = sourceData->ruleBodyRange;
6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    *result = styleSheetText.substring(bodyRange.start, bodyRange.end - bodyRange.start);
6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
67053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void InspectorStyle::populateAllProperties(Vector<InspectorStyleProperty>& result) const
6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HashSet<String> sourcePropertyNames;
6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
674926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RefPtr<CSSRuleSourceData> sourceData = extractSourceData();
67553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (sourceData) {
6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String styleDeclaration;
6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool isStyleTextKnown = styleText(&styleDeclaration);
6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT_UNUSED(isStyleTextKnown, isStyleTextKnown);
67953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        Vector<CSSPropertySourceData>& sourcePropertyData = sourceData->styleSourceData->propertyData;
68053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        for (Vector<CSSPropertySourceData>::const_iterator it = sourcePropertyData.begin(); it != sourcePropertyData.end(); ++it) {
68153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            InspectorStyleProperty p(*it, true);
6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            p.setRawTextFromStyleDeclaration(styleDeclaration);
68353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            result.append(p);
6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            sourcePropertyNames.add(it->name.lower());
6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (int i = 0, size = m_style->length(); i < size; ++i) {
6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String name = m_style->item(i);
6905267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if (!sourcePropertyNames.add(name.lower()).isNewEntry)
6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
69353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        result.append(InspectorStyleProperty(CSSPropertySourceData(name, m_style->getPropertyValue(name), !m_style->getPropertyPriority(name).isEmpty(), false, true, SourceRange()), false));
6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorStyle::styleWithProperties() const
6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Array<TypeBuilder::CSS::CSSProperty> > propertiesObject = Array<TypeBuilder::CSS::CSSProperty>::create();
7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Array<TypeBuilder::CSS::ShorthandEntry> > shorthandEntries = Array<TypeBuilder::CSS::ShorthandEntry>::create();
7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HashMap<String, RefPtr<TypeBuilder::CSS::CSSProperty> > propertyNameToPreviousActiveProperty;
7025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HashSet<String> foundShorthands;
7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String previousPriority;
7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String previousStatus;
705591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    OwnPtr<Vector<unsigned> > lineEndings(m_parentStyleSheet ? m_parentStyleSheet->lineEndings() : PassOwnPtr<Vector<unsigned> >());
706926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RefPtr<CSSRuleSourceData> sourceData = extractSourceData();
707926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    unsigned ruleBodyRangeStart = sourceData ? sourceData->ruleBodyRange.start : 0;
7085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
709fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    Vector<InspectorStyleProperty> properties;
710fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    populateAllProperties(properties);
711fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
7125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (Vector<InspectorStyleProperty>::iterator it = properties.begin(), itEnd = properties.end(); it != itEnd; ++it) {
7135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const CSSPropertySourceData& propertyEntry = it->sourceData;
7145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const String& name = propertyEntry.name;
71553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        const bool disabled = it->sourceData.disabled;
7165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
71753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        TypeBuilder::CSS::CSSProperty::Status::Enum status = disabled ? TypeBuilder::CSS::CSSProperty::Status::Disabled : TypeBuilder::CSS::CSSProperty::Status::Active;
7185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RefPtr<TypeBuilder::CSS::CSSProperty> property = TypeBuilder::CSS::CSSProperty::create()
7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            .setName(name)
7215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            .setValue(propertyEntry.value);
7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        propertiesObject->addItem(property);
7235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Default "parsedOk" == true.
7255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!propertyEntry.parsedOk)
7265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            property->setParsedOk(false);
7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (it->hasRawText())
7285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            property->setText(it->rawText);
7295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Default "priority" == "".
7315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (propertyEntry.important)
7325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            property->setPriority("important");
73353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (it->hasSource) {
73453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            // The property range is relative to the style body start.
73553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            // Should be converted into an absolute range (relative to the stylesheet start)
73653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            // for the proper conversion into line:column.
73753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            SourceRange absolutePropertyRange = propertyEntry.range;
73853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            absolutePropertyRange.start += ruleBodyRangeStart;
73953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            absolutePropertyRange.end += ruleBodyRangeStart;
74053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            property->setRange(buildSourceRangeObject(absolutePropertyRange, lineEndings.get()));
74153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
74253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (!disabled) {
7435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (it->hasSource) {
744926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                ASSERT(sourceData);
7455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                property->setImplicit(false);
7465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Parsed property overrides any property with the same name. Non-parsed property overrides
7485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // previous non-parsed property with the same name (if any).
7495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                bool shouldInactivate = false;
7505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                CSSPropertyID propertyId = cssPropertyID(name);
7515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Canonicalize property names to treat non-prefixed and vendor-prefixed property names the same (opacity vs. -webkit-opacity).
7525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                String canonicalPropertyName = propertyId ? getPropertyNameString(propertyId) : name;
7535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                HashMap<String, RefPtr<TypeBuilder::CSS::CSSProperty> >::iterator activeIt = propertyNameToPreviousActiveProperty.find(canonicalPropertyName);
7545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (activeIt != propertyNameToPreviousActiveProperty.end()) {
7555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (propertyEntry.parsedOk) {
7565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        bool successPriority = activeIt->value->getString(TypeBuilder::CSS::CSSProperty::Priority, &previousPriority);
7575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        bool successStatus = activeIt->value->getString(TypeBuilder::CSS::CSSProperty::Status, &previousStatus);
7585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        if (successStatus && previousStatus != "inactive") {
7595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            if (propertyEntry.important || !successPriority) // Priority not set == "not important".
7605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                shouldInactivate = true;
7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            else if (status == TypeBuilder::CSS::CSSProperty::Status::Active) {
7625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                // Inactivate a non-important property following the same-named important property.
7635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                status = TypeBuilder::CSS::CSSProperty::Status::Inactive;
7645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            }
7655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        }
7665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    } else {
7675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        bool previousParsedOk;
7685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        bool success = activeIt->value->getBoolean(TypeBuilder::CSS::CSSProperty::ParsedOk, &previousParsedOk);
7695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        if (success && !previousParsedOk)
7705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            shouldInactivate = true;
7715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
7725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                } else
7735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    propertyNameToPreviousActiveProperty.set(canonicalPropertyName, property);
7745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (shouldInactivate) {
7765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    activeIt->value->setStatus(TypeBuilder::CSS::CSSProperty::Status::Inactive);
7775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    propertyNameToPreviousActiveProperty.set(canonicalPropertyName, property);
7785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
7795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            } else {
7805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                bool implicit = m_style->isPropertyImplicit(name);
7815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Default "implicit" == false.
7825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (implicit)
7835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    property->setImplicit(true);
7845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                status = TypeBuilder::CSS::CSSProperty::Status::Style;
7855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                String shorthand = m_style->getPropertyShorthand(name);
7875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (!shorthand.isEmpty()) {
7885267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)                    if (foundShorthands.add(shorthand).isNewEntry) {
7895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        RefPtr<TypeBuilder::CSS::ShorthandEntry> entry = TypeBuilder::CSS::ShorthandEntry::create()
7905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            .setName(shorthand)
7915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            .setValue(shorthandValue(shorthand));
7925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        shorthandEntries->addItem(entry);
7935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
7945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
7965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
7975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Default "status" == "style".
7995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (status != TypeBuilder::CSS::CSSProperty::Status::Style)
8005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            property->setStatus(status);
8015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<TypeBuilder::CSS::CSSStyle> result = TypeBuilder::CSS::CSSStyle::create()
8045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setCssProperties(propertiesObject)
8055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setShorthandEntries(shorthandEntries);
8065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.release();
8075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
809926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)PassRefPtr<CSSRuleSourceData> InspectorStyle::extractSourceData() const
810926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
811926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!m_parentStyleSheet || !m_parentStyleSheet->ensureParsedDataReady())
812926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return 0;
813926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return m_parentStyleSheet->ruleSourceDataFor(m_style.get());
814926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
815926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
8165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorStyle::applyStyleText(const String& text)
8175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_parentStyleSheet->setStyleText(m_style.get(), text);
8195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String InspectorStyle::shorthandValue(const String& shorthandProperty) const
8225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String value = m_style->getPropertyValue(shorthandProperty);
8245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (value.isEmpty()) {
8255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (unsigned i = 0; i < m_style->length(); ++i) {
8265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            String individualProperty = m_style->item(i);
8275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (m_style->getPropertyShorthand(individualProperty) != shorthandProperty)
8285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
8295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (m_style->isPropertyImplicit(individualProperty))
8305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
8315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            String individualValue = m_style->getPropertyValue(individualProperty);
8325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (individualValue == "initial")
8335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
8345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (value.length())
8355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                value.append(" ");
8365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            value.append(individualValue);
8375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
8385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return value;
8405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String InspectorStyle::shorthandPriority(const String& shorthandProperty) const
8435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String priority = m_style->getPropertyPriority(shorthandProperty);
8455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (priority.isEmpty()) {
8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (unsigned i = 0; i < m_style->length(); ++i) {
8475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            String individualProperty = m_style->item(i);
8485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (m_style->getPropertyShorthand(individualProperty) != shorthandProperty)
8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
8505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            priority = m_style->getPropertyPriority(individualProperty);
8515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
8525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
8535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return priority;
8555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Vector<String> InspectorStyle::longhandProperties(const String& shorthandProperty) const
8585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<String> properties;
8605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HashSet<String> foundProperties;
8615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < m_style->length(); ++i) {
8625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String individualProperty = m_style->item(i);
8635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (foundProperties.contains(individualProperty) || m_style->getPropertyShorthand(individualProperty) != shorthandProperty)
8645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
8655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        foundProperties.add(individualProperty);
8675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        properties.append(individualProperty);
8685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return properties;
8705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)NewLineAndWhitespace& InspectorStyle::newLineAndWhitespaceDelimiters() const
8735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
874d24c94b5090b6aa121f0f82325c9379004dc3196Ben Murdoch    DEFINE_STATIC_LOCAL(String, defaultPrefix, ("    "));
8755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_formatAcquired)
8775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_format;
8785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
879926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RefPtr<CSSRuleSourceData> sourceData = extractSourceData();
8805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<CSSPropertySourceData>* sourcePropertyData = sourceData ? &(sourceData->styleSourceData->propertyData) : 0;
8815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int propertyCount;
8825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!sourcePropertyData || !(propertyCount = sourcePropertyData->size())) {
8835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_format.first = "\n";
8845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_format.second = defaultPrefix;
8855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_format; // Do not remember the default formatting and attempt to acquire it later.
8865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String text;
8895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool success = styleText(&text);
8905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_UNUSED(success, success);
8915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_formatAcquired = true;
8935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String candidatePrefix = defaultPrefix;
8955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder formatLineFeed;
8965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder prefix;
8975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int scanStart = 0;
8985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int propertyIndex = 0;
8995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isFullPrefixScanned = false;
9005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool lineFeedTerminated = false;
9015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (propertyIndex < propertyCount) {
9025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const WebCore::CSSPropertySourceData& currentProperty = sourcePropertyData->at(propertyIndex++);
9035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool processNextProperty = false;
9055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int scanEnd = currentProperty.range.start;
9065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (int i = scanStart; i < scanEnd; ++i) {
907591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            UChar ch = text[i];
9085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            bool isLineFeed = isHTMLLineBreak(ch);
9095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (isLineFeed) {
9105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (!lineFeedTerminated)
9115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    formatLineFeed.append(ch);
9125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                prefix.clear();
9135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            } else if (isHTMLSpace(ch))
9145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                prefix.append(ch);
9155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else {
9165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                candidatePrefix = prefix.toString();
9175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                prefix.clear();
9185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                scanStart = currentProperty.range.end;
9195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ++propertyIndex;
9205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                processNextProperty = true;
9215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
9225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
9235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!isLineFeed && formatLineFeed.length())
9245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                lineFeedTerminated = true;
9255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!processNextProperty) {
9275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            isFullPrefixScanned = true;
9285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
9295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_format.first = formatLineFeed.toString();
9335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_format.second = isFullPrefixScanned ? prefix.toString() : candidatePrefix;
9345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_format;
9355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
93753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)Document* InspectorStyle::ownerDocument() const
93853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
93953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return m_parentStyleSheet->pageStyleSheet() ? m_parentStyleSheet->pageStyleSheet()->ownerDocument() : 0;
94053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
94153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
9425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<InspectorStyleSheet> InspectorStyleSheet::create(InspectorPageAgent* pageAgent, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum origin, const String& documentURL, Listener* listener)
9435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return adoptRef(new InspectorStyleSheet(pageAgent, id, pageStyleSheet, origin, documentURL, listener));
9455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// static
9485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String InspectorStyleSheet::styleSheetURL(CSSStyleSheet* pageStyleSheet)
9495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (pageStyleSheet && !pageStyleSheet->contents()->baseURL().isEmpty())
9515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return pageStyleSheet->contents()->baseURL().string();
9525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return emptyString();
9535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
955521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)// static
956521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void InspectorStyleSheet::collectFlatRules(PassRefPtr<CSSRuleList> ruleList, CSSRuleVector* result)
957521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
958521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (!ruleList)
959521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return;
960521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
961521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    for (unsigned i = 0, size = ruleList->length(); i < size; ++i) {
962521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        CSSRule* rule = ruleList->item(i);
963521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
964521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        // The result->append()'ed types should be exactly the same as in ParsedStyleSheet::flattenSourceData().
965521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        switch (rule->type()) {
966521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        case CSSRule::STYLE_RULE:
967521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            result->append(rule);
968521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            continue;
969521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        case CSSRule::IMPORT_RULE:
970521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        case CSSRule::MEDIA_RULE:
971521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            result->append(rule);
972521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            break;
973521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        default:
974521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            break;
975521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        }
976521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        RefPtr<CSSRuleList> childRuleList = asCSSRuleList(rule);
977521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if (childRuleList)
978521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            collectFlatRules(childRuleList, result);
979521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    }
980521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
981521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
9825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InspectorStyleSheet::InspectorStyleSheet(InspectorPageAgent* pageAgent, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum origin, const String& documentURL, Listener* listener)
9835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_pageAgent(pageAgent)
9845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_id(id)
9855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_pageStyleSheet(pageStyleSheet)
9865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_origin(origin)
9875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_documentURL(documentURL)
9885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_isRevalidating(false)
98953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    , m_isReparsing(false)
9905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_listener(listener)
9915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_parsedStyleSheet = new ParsedStyleSheet();
9935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InspectorStyleSheet::~InspectorStyleSheet()
9965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    delete m_parsedStyleSheet;
9985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String InspectorStyleSheet::finalURL() const
10015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
10025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String url = styleSheetURL(m_pageStyleSheet.get());
10035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return url.isEmpty() ? m_documentURL : url;
10045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorStyleSheet::reparseStyleSheet(const String& text)
10075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
10087757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    if (m_listener)
10097757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        m_listener->willReparseStyleSheet();
10107757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
10115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
10125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Have a separate scope for clearRules() (bug 95324).
10135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        CSSStyleSheet::RuleMutationScope mutationScope(m_pageStyleSheet.get());
10145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_pageStyleSheet->contents()->clearRules();
101553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_pageStyleSheet->clearChildRuleCSSOMWrappers();
10165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
101853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_isReparsing = true;
10195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        CSSStyleSheet::RuleMutationScope mutationScope(m_pageStyleSheet.get());
10205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_pageStyleSheet->contents()->parseString(text);
102153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_isReparsing = false;
10225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10237757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
10247757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    if (m_listener)
10257757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        m_listener->didReparseStyleSheet();
10267757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    fireStyleSheetChanged();
10277757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    m_pageStyleSheet->ownerDocument()->styleResolverChanged(RecalcStyleImmediately, FullStyleUpdate);
10285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1030df95704c49daea886ddad70775bda23618d6274dBen Murdochbool InspectorStyleSheet::setText(const String& text, ExceptionState& es)
10315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1032df95704c49daea886ddad70775bda23618d6274dBen Murdoch    if (!checkPageStyleSheet(es))
1033926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return false;
10345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_parsedStyleSheet)
10355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
10365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_parsedStyleSheet->setText(text);
10385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_flatRules.clear();
10395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
10415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1043df95704c49daea886ddad70775bda23618d6274dBen MurdochString InspectorStyleSheet::ruleSelector(const InspectorCSSId& id, ExceptionState& es)
10445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
10455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSStyleRule* rule = ruleForId(id);
10465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!rule) {
1047df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
10485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return "";
10495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return rule->selectorText();
10515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1053df95704c49daea886ddad70775bda23618d6274dBen Murdochbool InspectorStyleSheet::setRuleSelector(const InspectorCSSId& id, const String& selector, ExceptionState& es)
10545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1055df95704c49daea886ddad70775bda23618d6274dBen Murdoch    if (!checkPageStyleSheet(es))
1056926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return false;
10575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSStyleRule* rule = ruleForId(id);
10585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!rule) {
1059df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
10605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
10615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSStyleSheet* styleSheet = rule->parentStyleSheet();
10635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!styleSheet || !ensureParsedDataReady()) {
1064df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
10655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
10665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    rule->setSelectorText(selector);
10695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<CSSRuleSourceData> sourceData = ruleSourceDataFor(rule->style());
10705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!sourceData) {
1071df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
10725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
10735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String sheetText = m_parsedStyleSheet->text();
10765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sheetText.replace(sourceData->ruleHeaderRange.start, sourceData->ruleHeaderRange.length(), selector);
10775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_parsedStyleSheet->setText(sheetText);
10785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fireStyleSheetChanged();
10795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
10805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool checkStyleRuleSelector(Document* document, const String& selector)
10835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
10845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSSelectorList selectorList;
10855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    createCSSParser(document)->parseSelector(selector, selectorList);
1086926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return selectorList.isValid();
10875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1089df95704c49daea886ddad70775bda23618d6274dBen MurdochCSSStyleRule* InspectorStyleSheet::addRule(const String& selector, ExceptionState& es)
10905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1091df95704c49daea886ddad70775bda23618d6274dBen Murdoch    if (!checkPageStyleSheet(es))
1092926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return 0;
10935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!checkStyleRuleSelector(m_pageStyleSheet->ownerDocument(), selector)) {
1094df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(SyntaxError);
10955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
10965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String text;
10995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool success = getText(&text);
11005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!success) {
1101df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
11025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
11035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder styleSheetText;
11055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    styleSheetText.append(text);
11065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1107df95704c49daea886ddad70775bda23618d6274dBen Murdoch    m_pageStyleSheet->addRule(selector, "", es);
1108df95704c49daea886ddad70775bda23618d6274dBen Murdoch    if (es.hadException())
11095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
11105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_pageStyleSheet->length());
11115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned lastRuleIndex = m_pageStyleSheet->length() - 1;
11125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSRule* rule = m_pageStyleSheet->item(lastRuleIndex);
11135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(rule);
11145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSStyleRule* styleRule = InspectorCSSAgent::asCSSStyleRule(rule);
11165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!styleRule) {
11175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // What we just added has to be a CSSStyleRule - we cannot handle other types of rules yet.
11185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If it is not a style rule, pretend we never touched the stylesheet.
11191fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        m_pageStyleSheet->deleteRule(lastRuleIndex, ASSERT_NO_EXCEPTION);
1120df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(SyntaxError);
11215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
11225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!styleSheetText.isEmpty())
11255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        styleSheetText.append('\n');
11265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    styleSheetText.append(selector);
11285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    styleSheetText.appendLiteral(" {}");
11295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Using setText() as this operation changes the style sheet rule set.
11301fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    setText(styleSheetText.toString(), ASSERT_NO_EXCEPTION);
11315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fireStyleSheetChanged();
11335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return styleRule;
11355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1137df95704c49daea886ddad70775bda23618d6274dBen Murdochbool InspectorStyleSheet::deleteRule(const InspectorCSSId& id, ExceptionState& es)
11385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1139df95704c49daea886ddad70775bda23618d6274dBen Murdoch    if (!checkPageStyleSheet(es))
1140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return false;
11415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<CSSStyleRule> rule = ruleForId(id);
11425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!rule) {
1143df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
11445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
11455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSStyleSheet* styleSheet = rule->parentStyleSheet();
11475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!styleSheet || !ensureParsedDataReady()) {
1148df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
11495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
11505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<CSSRuleSourceData> sourceData = ruleSourceDataFor(rule->style());
11535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!sourceData) {
1154df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
11555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
11565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1158df95704c49daea886ddad70775bda23618d6274dBen Murdoch    styleSheet->deleteRule(id.ordinal(), es);
11595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // |rule| MAY NOT be addressed after this line!
11605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1161df95704c49daea886ddad70775bda23618d6274dBen Murdoch    if (es.hadException())
11625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
11635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String sheetText = m_parsedStyleSheet->text();
11655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sheetText.remove(sourceData->ruleHeaderRange.start, sourceData->ruleBodyRange.end - sourceData->ruleHeaderRange.start + 1);
11661fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    setText(sheetText, ASSERT_NO_EXCEPTION);
11675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fireStyleSheetChanged();
11685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
11695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CSSStyleRule* InspectorStyleSheet::ruleForId(const InspectorCSSId& id) const
11725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_pageStyleSheet)
11745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
11755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!id.isEmpty());
11775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ensureFlatRules();
1178521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return InspectorCSSAgent::asCSSStyleRule(id.ordinal() >= m_flatRules.size() ? 0 : m_flatRules.at(id.ordinal()).get());
11795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1181521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)bool InspectorStyleSheet::fillObjectForStyleSheet(PassRefPtr<TypeBuilder::CSS::CSSStyleSheetBody> prpResult)
11825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSStyleSheet* styleSheet = pageStyleSheet();
11845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!styleSheet)
1185521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return false;
11865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1187521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    RefPtr<TypeBuilder::CSS::CSSStyleSheetBody> result = prpResult;
11885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String styleSheetText;
11905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool success = getText(&styleSheetText);
11915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (success)
11925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result->setText(styleSheetText);
1193521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return success;
11945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
119681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)PassRefPtr<TypeBuilder::CSS::CSSStyleSheetHeader> InspectorStyleSheet::buildObjectForStyleSheetInfo() const
11975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSStyleSheet* styleSheet = pageStyleSheet();
11995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!styleSheet)
12005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
12015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Document* document = styleSheet->ownerDocument();
12035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Frame* frame = document ? document->frame() : 0;
120493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
12055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<TypeBuilder::CSS::CSSStyleSheetHeader> result = TypeBuilder::CSS::CSSStyleSheetHeader::create()
12065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setStyleSheetId(id())
12075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setOrigin(m_origin)
12085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setDisabled(styleSheet->disabled())
120993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        .setSourceURL(url())
12105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setTitle(styleSheet->title())
121193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        .setFrameId(m_pageAgent->frameId(frame))
121293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        .setIsInline(styleSheet->isInline() && !startsAtZero())
121393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        .setStartLine(styleSheet->startPositionInSource().m_line.zeroBasedInt())
121493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        .setStartColumn(styleSheet->startPositionInSource().m_column.zeroBasedInt());
121593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
121693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (hasSourceURL())
121793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        result->setHasSourceURL(true);
12185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
121993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    String sourceMapURLValue = sourceMapURL();
122093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!sourceMapURLValue.isEmpty())
122193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        result->setSourceMapURL(sourceMapURLValue);
12225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.release();
12235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1225926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static PassRefPtr<TypeBuilder::Array<String> > selectorsFromSource(const CSSRuleSourceData* sourceData, const String& sheetText)
12265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
122753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RegularExpression comment("/\\*[^]*?\\*/", TextCaseSensitive, MultilineEnabled);
1228926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RefPtr<TypeBuilder::Array<String> > result = TypeBuilder::Array<String>::create();
1229926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const SelectorRangeList& ranges = sourceData->selectorRanges;
1230926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (size_t i = 0, size = ranges.size(); i < size; ++i) {
1231926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        const SourceRange& range = ranges.at(i);
1232926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        String selector = sheetText.substring(range.start, range.length());
12335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1234926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // We don't want to see any comments in the selector components, only the meaningful parts.
123553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        int matchLength;
123653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        int offset = 0;
123753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        while ((offset = comment.match(selector, offset, &matchLength)) >= 0)
123853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            selector.replace(offset, matchLength, "");
123953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1240926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        result->addItem(selector.stripWhiteSpace());
1241926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
1242926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return result.release();
1243926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
12445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1245926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)PassRefPtr<TypeBuilder::CSS::SelectorList> InspectorStyleSheet::buildObjectForSelectorList(CSSStyleRule* rule)
1246926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
12475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<CSSRuleSourceData> sourceData;
12485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (ensureParsedDataReady())
12495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        sourceData = ruleSourceDataFor(rule->style());
1250926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RefPtr<TypeBuilder::Array<String> > selectors;
1251926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1252926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // This intentionally does not rely on the source data to avoid catching the trailing comments (before the declaration starting '{').
1253926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    String selectorText = rule->selectorText();
1254926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1255926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (sourceData)
1256926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        selectors = selectorsFromSource(sourceData.get(), m_parsedStyleSheet->text());
1257926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    else {
1258926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        selectors = TypeBuilder::Array<String>::create();
1259926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        const CSSSelectorList& selectorList = rule->styleRule()->selectorList();
1260926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector))
1261926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            selectors->addItem(selector->selectorText());
1262926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
1263926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RefPtr<TypeBuilder::CSS::SelectorList> result = TypeBuilder::CSS::SelectorList::create()
1264926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        .setSelectors(selectors)
1265926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        .setText(selectorText)
1266926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        .release();
12675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (sourceData)
1268926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        result->setRange(buildSourceRangeObject(sourceData->ruleHeaderRange, lineEndings().get()));
12695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.release();
12705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1272521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)PassRefPtr<TypeBuilder::CSS::CSSRule> InspectorStyleSheet::buildObjectForRule(CSSStyleRule* rule, PassRefPtr<Array<TypeBuilder::CSS::CSSMedia> > mediaStack)
12735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSStyleSheet* styleSheet = pageStyleSheet();
12755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!styleSheet)
12765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
12775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<TypeBuilder::CSS::CSSRule> result = TypeBuilder::CSS::CSSRule::create()
12795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setSelectorList(buildObjectForSelectorList(rule))
12805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setOrigin(m_origin)
12815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setStyle(buildObjectForStyle(rule->style()));
12825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
128393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    String url = this->url();
128493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!url.isEmpty())
128593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        result->setSourceURL(url);
12865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (canBind()) {
12885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        InspectorCSSId id(ruleId(rule));
12895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!id.isEmpty())
12905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result->setRuleId(id.asProtocolValue<TypeBuilder::CSS::CSSRuleId>());
12915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Array<TypeBuilder::CSS::CSSMedia> > mediaArray = Array<TypeBuilder::CSS::CSSMedia>::create();
12945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1295521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (mediaStack)
1296521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        result->setMedia(mediaStack);
12975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.release();
12995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorStyleSheet::buildObjectForStyle(CSSStyleDeclaration* style)
13025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<CSSRuleSourceData> sourceData;
13045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (ensureParsedDataReady())
13055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        sourceData = ruleSourceDataFor(style);
13065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InspectorCSSId id = ruleOrStyleId(style);
13085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (id.isEmpty()) {
13095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RefPtr<TypeBuilder::CSS::CSSStyle> bogusStyle = TypeBuilder::CSS::CSSStyle::create()
13105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            .setCssProperties(Array<TypeBuilder::CSS::CSSProperty>::create())
13115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            .setShorthandEntries(Array<TypeBuilder::CSS::ShorthandEntry>::create());
13125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return bogusStyle.release();
13135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
13155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<TypeBuilder::CSS::CSSStyle> result = inspectorStyle->buildObjectForStyle();
13165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Style text cannot be retrieved without stylesheet, so set cssText here.
13185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (sourceData) {
13195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String sheetText;
13205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool success = getText(&sheetText);
13215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (success) {
13225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            const SourceRange& bodyRange = sourceData->ruleBodyRange;
13235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result->setCssText(sheetText.substring(bodyRange.start, bodyRange.end - bodyRange.start));
13245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
13255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.release();
13285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1330df95704c49daea886ddad70775bda23618d6274dBen Murdochbool InspectorStyleSheet::setStyleText(const InspectorCSSId& id, const String& text, String* oldText, ExceptionState& es)
133153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
133253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
133353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!inspectorStyle || !inspectorStyle->cssStyle()) {
1334df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
133553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return false;
133653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
133753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
133853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bool success = inspectorStyle->styleText(oldText);
133953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!success) {
1340df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
134153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return false;
134253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
134353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
134453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    success = setStyleText(inspectorStyle->cssStyle(), text);
134553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (success)
134653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        fireStyleSheetChanged();
134753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    else
1348df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(SyntaxError);
134953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return success;
135053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
135153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1352df95704c49daea886ddad70775bda23618d6274dBen Murdochbool InspectorStyleSheet::setPropertyText(const InspectorCSSId& id, unsigned propertyIndex, const String& text, bool overwrite, String* oldText, ExceptionState& es)
13535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
13555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!inspectorStyle) {
1356df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
13575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
13585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1360df95704c49daea886ddad70775bda23618d6274dBen Murdoch    bool success = inspectorStyle->setPropertyText(propertyIndex, text, overwrite, oldText, es);
13615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (success)
13625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fireStyleSheetChanged();
13635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return success;
13645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1366df95704c49daea886ddad70775bda23618d6274dBen Murdochbool InspectorStyleSheet::toggleProperty(const InspectorCSSId& id, unsigned propertyIndex, bool disable, ExceptionState& es)
13675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
13695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!inspectorStyle) {
1370df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotFoundError);
13715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
13725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1374df95704c49daea886ddad70775bda23618d6274dBen Murdoch    bool success = inspectorStyle->toggleProperty(propertyIndex, disable, es);
137553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (success)
13765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fireStyleSheetChanged();
13775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return success;
13785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorStyleSheet::getText(String* result) const
13815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!ensureText())
13835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
13845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    *result = m_parsedStyleSheet->text();
13855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
13865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CSSStyleDeclaration* InspectorStyleSheet::styleForId(const InspectorCSSId& id) const
13895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSStyleRule* rule = ruleForId(id);
13915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!rule)
13925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
13935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return rule->style();
13955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorStyleSheet::fireStyleSheetChanged()
13985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_listener)
14005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_listener->styleSheetChanged(this);
14015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1403521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)PassRefPtr<TypeBuilder::CSS::SourceRange> InspectorStyleSheet::ruleHeaderSourceRange(const CSSRule* rule)
1404521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
1405521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (!ensureParsedDataReady())
1406521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return 0;
1407521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
1408521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    RefPtr<CSSRuleSourceData> sourceData = m_parsedStyleSheet->ruleSourceDataAt(ruleIndexByRule(rule));
1409521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (!sourceData)
1410521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return 0;
1411521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return buildSourceRangeObject(sourceData->ruleHeaderRange, lineEndings().get());
1412521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
1413521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
14145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<InspectorStyle> InspectorStyleSheet::inspectorStyleForId(const InspectorCSSId& id)
14155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSStyleDeclaration* style = styleForId(id);
14175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!style)
14185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
14195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
142053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return InspectorStyle::create(id, style, this);
14215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
142393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)String InspectorStyleSheet::sourceURL() const
142493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
142593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!m_sourceURL.isNull())
142693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return m_sourceURL;
142793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (m_origin != TypeBuilder::CSS::StyleSheetOrigin::Regular) {
142893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        m_sourceURL = "";
142993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return m_sourceURL;
143093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
143193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
143293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    String styleSheetText;
143393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    bool success = getText(&styleSheetText);
143493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (success) {
14355267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        bool deprecated;
14365267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        String commentValue = ContentSearchUtils::findSourceURL(styleSheetText, ContentSearchUtils::CSSMagicComment, &deprecated);
143793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        if (!commentValue.isEmpty()) {
1438591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            // FIXME: add deprecated console message here.
143993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            m_sourceURL = commentValue;
14405267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            return commentValue;
144193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
144293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
144393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    m_sourceURL = "";
144493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return m_sourceURL;
144593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
144693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
144793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)String InspectorStyleSheet::url() const
144893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
144993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // "sourceURL" is present only for regular rules, otherwise "origin" should be used in the frontend.
145093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (m_origin != TypeBuilder::CSS::StyleSheetOrigin::Regular)
145193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return String();
145293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
145393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    CSSStyleSheet* styleSheet = pageStyleSheet();
145493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!styleSheet)
145593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return String();
145693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
145793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (hasSourceURL())
145893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return sourceURL();
145993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
146093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (styleSheet->isInline() && startsAtZero())
146193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return String();
146293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
146393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return finalURL();
146493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
146593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
146693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)bool InspectorStyleSheet::hasSourceURL() const
146793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
146893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return !sourceURL().isEmpty();
146993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
147093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
147193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)bool InspectorStyleSheet::startsAtZero() const
147293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
147393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    CSSStyleSheet* styleSheet = pageStyleSheet();
147493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!styleSheet)
147593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return true;
147693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
147793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return styleSheet->startPositionInSource() == TextPosition::minimumPosition();
147893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
147993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
148093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)String InspectorStyleSheet::sourceMapURL() const
148193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
148293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (m_origin != TypeBuilder::CSS::StyleSheetOrigin::Regular)
148393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return String();
148493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
148593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    String styleSheetText;
148693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    bool success = getText(&styleSheetText);
148793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (success) {
14885267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        bool deprecated;
14895267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        String commentValue = ContentSearchUtils::findSourceMapURL(styleSheetText, ContentSearchUtils::CSSMagicComment, &deprecated);
14905267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if (!commentValue.isEmpty()) {
1491591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            // FIXME: add deprecated console message here.
149293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            return commentValue;
14935267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        }
149493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
14955267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    return m_pageAgent->resourceSourceMapURL(finalURL());
149693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
149793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
14985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InspectorCSSId InspectorStyleSheet::ruleOrStyleId(CSSStyleDeclaration* style) const
14995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned index = ruleIndexByStyle(style);
15015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (index != UINT_MAX)
15025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return InspectorCSSId(id(), index);
15035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return InspectorCSSId();
15045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Document* InspectorStyleSheet::ownerDocument() const
15075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_pageStyleSheet->ownerDocument();
15095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
151153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)PassRefPtr<CSSRuleSourceData> InspectorStyleSheet::ruleSourceDataFor(CSSStyleDeclaration* style) const
15125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_parsedStyleSheet->ruleSourceDataAt(ruleIndexByStyle(style));
15145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1516591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochPassOwnPtr<Vector<unsigned> > InspectorStyleSheet::lineEndings() const
1517926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
1518926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!m_parsedStyleSheet->hasText())
1519591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        return PassOwnPtr<Vector<unsigned> >();
1520591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    return WTF::lineEndings(m_parsedStyleSheet->text());
1521926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
1522926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
15235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned InspectorStyleSheet::ruleIndexByStyle(CSSStyleDeclaration* pageStyle) const
15245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ensureFlatRules();
15265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0, size = m_flatRules.size(); i < size; ++i) {
1527521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        CSSStyleRule* styleRule = InspectorCSSAgent::asCSSStyleRule(m_flatRules.at(i).get());
1528521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if (styleRule && styleRule->style() == pageStyle)
1529521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            return i;
15305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
15315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return UINT_MAX;
15325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1534521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)unsigned InspectorStyleSheet::ruleIndexByRule(const CSSRule* rule) const
1535521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
1536521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    ensureFlatRules();
1537521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    size_t index = m_flatRules.find(rule);
1538521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return index == notFound ? UINT_MAX : static_cast<unsigned>(index);
1539521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
1540521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
1541df95704c49daea886ddad70775bda23618d6274dBen Murdochbool InspectorStyleSheet::checkPageStyleSheet(ExceptionState& es) const
1542926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
1543926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!m_pageStyleSheet) {
1544df95704c49daea886ddad70775bda23618d6274dBen Murdoch        es.throwDOMException(NotSupportedError);
1545926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return false;
1546926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
1547926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return true;
1548926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
1549926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
15505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorStyleSheet::ensureParsedDataReady()
15515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return ensureText() && ensureSourceData();
15535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorStyleSheet::ensureText() const
15565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_parsedStyleSheet)
15585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
15595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_parsedStyleSheet->hasText())
15605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
15615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String text;
15635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool success = originalStyleSheetText(&text);
15645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (success)
15655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_parsedStyleSheet->setText(text);
15665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // No need to clear m_flatRules here - it's empty.
15675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return success;
15695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorStyleSheet::ensureSourceData()
15725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_parsedStyleSheet->hasSourceData())
15745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
15755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_parsedStyleSheet->hasText())
15775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
15785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<StyleSheetContents> newStyleSheet = StyleSheetContents::create();
158053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    OwnPtr<RuleSourceDataList> result = adoptPtr(new RuleSourceDataList());
158153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    StyleSheetHandler handler(m_parsedStyleSheet->text(), m_pageStyleSheet->ownerDocument(), newStyleSheet.get(), result.get());
1582e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    createCSSParser(m_pageStyleSheet->ownerDocument())->parseSheet(newStyleSheet.get(), m_parsedStyleSheet->text(), TextPosition::minimumPosition(), &handler);
158353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_parsedStyleSheet->setSourceData(result.release());
15845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_parsedStyleSheet->hasSourceData();
15855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorStyleSheet::ensureFlatRules() const
15885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We are fine with redoing this for empty stylesheets as this will run fast.
15905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_flatRules.isEmpty())
15915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        collectFlatRules(asCSSRuleList(pageStyleSheet()), &m_flatRules);
15925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorStyleSheet::setStyleText(CSSStyleDeclaration* style, const String& text)
15955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1596926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!m_pageStyleSheet)
15975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
15985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!ensureParsedDataReady())
15995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
16005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String patchedStyleSheetText;
16025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool success = styleSheetTextWithChangedStyle(style, text, &patchedStyleSheetText);
16035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!success)
16045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
16055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InspectorCSSId id = ruleOrStyleId(style);
16075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (id.isEmpty())
16085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
16095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1610df95704c49daea886ddad70775bda23618d6274dBen Murdoch    TrackExceptionState es;
1611df95704c49daea886ddad70775bda23618d6274dBen Murdoch    style->setCssText(text, es);
1612df95704c49daea886ddad70775bda23618d6274dBen Murdoch    if (!es.hadException())
16135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_parsedStyleSheet->setText(patchedStyleSheetText);
16145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1615df95704c49daea886ddad70775bda23618d6274dBen Murdoch    return !es.hadException();
16165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorStyleSheet::styleSheetTextWithChangedStyle(CSSStyleDeclaration* style, const String& newStyleText, String* result)
16195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!style)
16215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
16225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!ensureParsedDataReady())
16245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
16255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<CSSRuleSourceData> sourceData = ruleSourceDataFor(style);
16275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned bodyStart = sourceData->ruleBodyRange.start;
16285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned bodyEnd = sourceData->ruleBodyRange.end;
16295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(bodyStart <= bodyEnd);
16305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String text = m_parsedStyleSheet->text();
1632926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT_WITH_SECURITY_IMPLICATION(bodyEnd <= text.length()); // bodyEnd is exclusive
16335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    text.replace(bodyStart, bodyEnd - bodyStart, newStyleText);
16355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    *result = text;
16365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
16375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InspectorCSSId InspectorStyleSheet::ruleId(CSSStyleRule* rule) const
16405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return ruleOrStyleId(rule->style());
16425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorStyleSheet::revalidateStyle(CSSStyleDeclaration* pageStyle)
16455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_isRevalidating)
16475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
16485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_isRevalidating = true;
16505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ensureFlatRules();
16515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0, size = m_flatRules.size(); i < size; ++i) {
1652521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        CSSStyleRule* parsedRule = InspectorCSSAgent::asCSSStyleRule(m_flatRules.at(i).get());
1653521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if (parsedRule && parsedRule->style() == pageStyle) {
165453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (parsedRule->styleRule()->properties()->asText() != pageStyle->cssText())
16555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                setStyleText(pageStyle, pageStyle->cssText());
16565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
16575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
16585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
16595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_isRevalidating = false;
16605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorStyleSheet::originalStyleSheetText(String* result) const
16635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool success = inlineStyleSheetText(result);
16655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!success)
16665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        success = resourceStyleSheetText(result);
16675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return success;
16685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorStyleSheet::resourceStyleSheetText(String* result) const
16715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_origin == TypeBuilder::CSS::StyleSheetOrigin::User || m_origin == TypeBuilder::CSS::StyleSheetOrigin::User_agent)
16735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
16745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_pageStyleSheet || !ownerDocument() || !ownerDocument()->frame())
16765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
16775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String error;
16795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool base64Encoded;
16805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InspectorPageAgent::resourceContent(&error, ownerDocument()->frame(), KURL(ParsedURLString, m_pageStyleSheet->href()), result, &base64Encoded);
16815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return error.isEmpty() && !base64Encoded;
16825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorStyleSheet::inlineStyleSheetText(String* result) const
16855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_pageStyleSheet)
16875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
16885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* ownerNode = m_pageStyleSheet->ownerNode();
16905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!ownerNode || ownerNode->nodeType() != Node::ELEMENT_NODE)
16915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
1692926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Element* ownerElement = toElement(ownerNode);
16935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
169493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!ownerElement->hasTagName(HTMLNames::styleTag) && !ownerElement->hasTagName(SVGNames::styleTag))
16955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
16965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    *result = ownerElement->textContent();
16975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
16985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<InspectorStyleSheetForInlineStyle> InspectorStyleSheetForInlineStyle::create(InspectorPageAgent* pageAgent, const String& id, PassRefPtr<Element> element, TypeBuilder::CSS::StyleSheetOrigin::Enum origin, Listener* listener)
17015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return adoptRef(new InspectorStyleSheetForInlineStyle(pageAgent, id, element, origin, listener));
17035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(InspectorPageAgent* pageAgent, const String& id, PassRefPtr<Element> element, TypeBuilder::CSS::StyleSheetOrigin::Enum origin, Listener* listener)
17065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : InspectorStyleSheet(pageAgent, id, 0, origin, "", listener)
17075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_element(element)
17085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_ruleSourceData(0)
17095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_isStyleTextValid(false)
17105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_element);
17125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_inspectorStyle = InspectorStyle::create(InspectorCSSId(id, 0), inlineStyle(), this);
17135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_styleText = m_element->isStyledElement() ? m_element->getAttribute("style").string() : String();
17145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorStyleSheetForInlineStyle::didModifyElementAttribute()
17175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_isStyleTextValid = false;
17195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_element->isStyledElement() && m_element->style() != m_inspectorStyle->cssStyle())
17205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_inspectorStyle = InspectorStyle::create(InspectorCSSId(id(), 0), inlineStyle(), this);
17215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_ruleSourceData.clear();
17225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorStyleSheetForInlineStyle::getText(String* result) const
17255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_isStyleTextValid) {
17275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_styleText = elementStyleText();
17285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_isStyleTextValid = true;
17295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
17305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    *result = m_styleText;
17315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
17325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorStyleSheetForInlineStyle::setStyleText(CSSStyleDeclaration* style, const String& text)
17355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_UNUSED(style, style == inlineStyle());
1737df95704c49daea886ddad70775bda23618d6274dBen Murdoch    TrackExceptionState es;
17385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
17405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        InspectorCSSAgent::InlineStyleOverrideScope overrideScope(m_element->ownerDocument());
1741df95704c49daea886ddad70775bda23618d6274dBen Murdoch        m_element->setAttribute("style", text, es);
17425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
17435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_styleText = text;
17455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_isStyleTextValid = true;
17465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_ruleSourceData.clear();
1747df95704c49daea886ddad70775bda23618d6274dBen Murdoch    return !es.hadException();
17485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1750591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochPassOwnPtr<Vector<unsigned> > InspectorStyleSheetForInlineStyle::lineEndings() const
1751926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
1752591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    return WTF::lineEndings(elementStyleText());
1753926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
1754926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
17555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Document* InspectorStyleSheetForInlineStyle::ownerDocument() const
17565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_element->document();
17585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorStyleSheetForInlineStyle::ensureParsedDataReady()
17615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The "style" property value can get changed indirectly, e.g. via element.style.borderWidth = "2px".
17635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const String& currentStyleText = elementStyleText();
17645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_styleText != currentStyleText) {
17655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_ruleSourceData.clear();
17665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_styleText = currentStyleText;
17675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_isStyleTextValid = true;
17685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
17695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_ruleSourceData)
17715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
17725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
177353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_ruleSourceData = getStyleAttributeData();
177453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
177553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    bool success = !!m_ruleSourceData;
177653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!success) {
177753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_ruleSourceData = CSSRuleSourceData::create(CSSRuleSourceData::STYLE_RULE);
17785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
177953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
17805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
17825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<InspectorStyle> InspectorStyleSheetForInlineStyle::inspectorStyleForId(const InspectorCSSId& id)
17855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_UNUSED(id, !id.ordinal());
17875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_inspectorStyle;
17885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CSSStyleDeclaration* InspectorStyleSheetForInlineStyle::inlineStyle() const
17915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_element->style();
17935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const String& InspectorStyleSheetForInlineStyle::elementStyleText() const
17965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_element->getAttribute("style").string();
17985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
180053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)PassRefPtr<CSSRuleSourceData> InspectorStyleSheetForInlineStyle::getStyleAttributeData() const
18015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
18025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_element->isStyledElement())
180353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return 0;
18045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_styleText.isEmpty()) {
180653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        RefPtr<CSSRuleSourceData> result = CSSRuleSourceData::create(CSSRuleSourceData::STYLE_RULE);
18075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result->ruleBodyRange.start = 0;
18085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result->ruleBodyRange.end = 0;
180953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return result.release();
18105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
18115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
181293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    RefPtr<MutableStylePropertySet> tempDeclaration = MutableStylePropertySet::create();
181353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    RuleSourceDataList ruleSourceDataResult;
181453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    StyleSheetHandler handler(m_styleText, m_element->document(), m_element->document()->elementSheet()->contents(), &ruleSourceDataResult);
181553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    createCSSParser(m_element->document())->parseDeclaration(tempDeclaration.get(), m_styleText, &handler, m_element->document()->elementSheet()->contents());
181653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return ruleSourceDataResult.first().release();
18175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore
18205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1821