1a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch/*
2a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * Copyright (C) 2010, Google Inc. All rights reserved.
3a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *
4a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * Redistribution and use in source and binary forms, with or without
5a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * modification, are permitted provided that the following conditions
6a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * are met:
7a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * 1.  Redistributions of source code must retain the above copyright
8a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *     notice, this list of conditions and the following disclaimer.
9a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * 2.  Redistributions in binary form must reproduce the above copyright
10a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *     notice, this list of conditions and the following disclaimer in the
11a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *     documentation and/or other materials provided with the distribution.
12a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *
13a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch */
24a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
25a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "config.h"
26a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "InspectorStyleSheet.h"
27a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
28a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#if ENABLE(INSPECTOR)
29a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
304576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#include "CSSImportRule.h"
314576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#include "CSSMediaRule.h"
32a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "CSSParser.h"
33a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "CSSPropertySourceData.h"
34a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "CSSRule.h"
35a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "CSSRuleList.h"
36a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "CSSStyleRule.h"
37a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "CSSStyleSelector.h"
38a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "CSSStyleSheet.h"
39a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "Document.h"
40a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "Element.h"
41a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "HTMLHeadElement.h"
426b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "HTMLParserIdioms.h"
43a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "InspectorCSSAgent.h"
44a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "InspectorResourceAgent.h"
45a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "InspectorValues.h"
46a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "Node.h"
47a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "StyleSheetList.h"
484576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#include "WebKitCSSKeyframesRule.h"
49a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
50a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include <wtf/OwnPtr.h>
51a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include <wtf/PassOwnPtr.h>
52a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include <wtf/Vector.h>
53a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
54a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochclass ParsedStyleSheet {
55a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochpublic:
56a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    typedef Vector<RefPtr<WebCore::CSSRuleSourceData> > SourceData;
57a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ParsedStyleSheet();
58a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
59a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    WebCore::CSSStyleSheet* cssStyleSheet() const { return m_parserOutput; }
60a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    const String& text() const { return m_text; }
61a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void setText(const String& text);
62a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool hasText() const { return m_hasText; }
63a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    SourceData* sourceData() const { return m_sourceData.get(); }
64a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void setSourceData(PassOwnPtr<SourceData> sourceData);
65a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool hasSourceData() const { return m_sourceData; }
66a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<WebCore::CSSRuleSourceData> ruleSourceDataAt(unsigned index) const;
67a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
68a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochprivate:
69a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
70a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // StyleSheet constructed while parsing m_text.
71a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    WebCore::CSSStyleSheet* m_parserOutput;
72a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    String m_text;
73a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool m_hasText;
74a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    OwnPtr<SourceData> m_sourceData;
75a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch};
76a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
77a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochParsedStyleSheet::ParsedStyleSheet()
78a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    : m_parserOutput(0)
79a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_hasText(false)
80a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
81a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
82a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
83a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid ParsedStyleSheet::setText(const String& text)
84a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
85a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_hasText = true;
86a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_text = text;
87a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setSourceData(0);
88a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
89a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
90a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid ParsedStyleSheet::setSourceData(PassOwnPtr<SourceData> sourceData)
91a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
92a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_sourceData = sourceData;
93a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
94a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
95a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochRefPtr<WebCore::CSSRuleSourceData> ParsedStyleSheet::ruleSourceDataAt(unsigned index) const
96a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
97a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!hasSourceData() || index >= m_sourceData->size())
98a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return 0;
99a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
100a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return m_sourceData->at(index);
101a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
102a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
103a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochnamespace WebCore {
104a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic PassRefPtr<InspectorObject> buildSourceRangeObject(const SourceRange& range)
1062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
1072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    RefPtr<InspectorObject> result = InspectorObject::create();
1082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    result->setNumber("start", range.start);
1092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    result->setNumber("end", range.end);
1102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return result.release();
1112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
1122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1134576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangstatic PassRefPtr<CSSRuleList> asCSSRuleList(StyleBase* styleBase)
1144576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang{
1154576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    if (!styleBase)
1164576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        return 0;
1174576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
1184576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    if (styleBase->isCSSStyleSheet())
1194576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        return CSSRuleList::create(static_cast<CSSStyleSheet*>(styleBase), true);
1204576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    if (styleBase->isRule()) {
1214576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        unsigned ruleType = static_cast<CSSRule*>(styleBase)->type();
1224576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        RefPtr<CSSRuleList> result = 0;
1234576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
1244576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        switch (ruleType) {
1254576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        case CSSRule::MEDIA_RULE:
1264576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            result = static_cast<CSSMediaRule*>(styleBase)->cssRules();
1274576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            break;
1284576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        case CSSRule::WEBKIT_KEYFRAMES_RULE:
1294576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            result = static_cast<WebKitCSSKeyframesRule*>(styleBase)->cssRules();
1304576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            break;
1314576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        case CSSRule::IMPORT_RULE:
1324576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        case CSSRule::PAGE_RULE:
1334576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        default:
1344576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            return 0;
1354576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        }
1364576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
1374576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        return result.release();
1384576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    }
1394576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    return 0;
1404576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang}
1414576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
142cad810f21b803229eb11403f9209855525a25d57Steve BlockPassRefPtr<InspectorStyle> InspectorStyle::create(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet)
143cad810f21b803229eb11403f9209855525a25d57Steve Block{
144cad810f21b803229eb11403f9209855525a25d57Steve Block    return adoptRef(new InspectorStyle(styleId, style, parentStyleSheet));
145cad810f21b803229eb11403f9209855525a25d57Steve Block}
146cad810f21b803229eb11403f9209855525a25d57Steve Block
147cad810f21b803229eb11403f9209855525a25d57Steve BlockInspectorStyle::InspectorStyle(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet)
148cad810f21b803229eb11403f9209855525a25d57Steve Block    : m_styleId(styleId)
149cad810f21b803229eb11403f9209855525a25d57Steve Block    , m_style(style)
150cad810f21b803229eb11403f9209855525a25d57Steve Block    , m_parentStyleSheet(parentStyleSheet)
151cad810f21b803229eb11403f9209855525a25d57Steve Block{
152cad810f21b803229eb11403f9209855525a25d57Steve Block    ASSERT(m_style);
153cad810f21b803229eb11403f9209855525a25d57Steve Block}
154cad810f21b803229eb11403f9209855525a25d57Steve Block
155cad810f21b803229eb11403f9209855525a25d57Steve BlockInspectorStyle::~InspectorStyle()
156cad810f21b803229eb11403f9209855525a25d57Steve Block{
157cad810f21b803229eb11403f9209855525a25d57Steve Block}
158cad810f21b803229eb11403f9209855525a25d57Steve Block
159e14391e94c850b8bd03680c23b38978db68687a8John ReckPassRefPtr<InspectorObject> InspectorStyle::buildObjectForStyle() const
160e14391e94c850b8bd03680c23b38978db68687a8John Reck{
161e14391e94c850b8bd03680c23b38978db68687a8John Reck    RefPtr<InspectorObject> result = InspectorObject::create();
162e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (!m_styleId.isEmpty())
1634576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        result->setValue("styleId", m_styleId.asInspectorValue());
164e14391e94c850b8bd03680c23b38978db68687a8John Reck
1652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    result->setString("width", m_style->getPropertyValue("width"));
1662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    result->setString("height", m_style->getPropertyValue("height"));
167e14391e94c850b8bd03680c23b38978db68687a8John Reck
168cad810f21b803229eb11403f9209855525a25d57Steve Block    RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet ? m_parentStyleSheet->ruleSourceDataFor(m_style.get()) : 0;
1692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (sourceData)
1702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        result->setObject("range", buildSourceRangeObject(sourceData->styleSourceData->styleBodyRange));
171e14391e94c850b8bd03680c23b38978db68687a8John Reck
172e14391e94c850b8bd03680c23b38978db68687a8John Reck    populateObjectWithStyleProperties(result.get());
173e14391e94c850b8bd03680c23b38978db68687a8John Reck
174e14391e94c850b8bd03680c23b38978db68687a8John Reck    return result.release();
175e14391e94c850b8bd03680c23b38978db68687a8John Reck}
176e14391e94c850b8bd03680c23b38978db68687a8John Reck
1776b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// This method does the following preprocessing of |propertyText| with |overwrite| == false and |index| past the last active property:
1786b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// - If the last property (if present) has no subsequent whitespace in the style declaration, a space is prepended to |propertyText|.
1796b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// - If the last property (if present) has no closing ";", the ";" is prepended to the current |propertyText| value.
1806b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner//
1816b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// The propertyText (if not empty) is checked to be a valid style declaration (containing at least one property). If not,
1826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// the method returns false (denoting an error).
1832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool InspectorStyle::setPropertyText(ErrorString* errorString, unsigned index, const String& propertyText, bool overwrite)
184e14391e94c850b8bd03680c23b38978db68687a8John Reck{
185e14391e94c850b8bd03680c23b38978db68687a8John Reck    ASSERT(m_parentStyleSheet);
1862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!m_parentStyleSheet->ensureParsedDataReady()) {
1872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        *errorString = "Internal error: no stylesheet parsed data available";
188e14391e94c850b8bd03680c23b38978db68687a8John Reck        return false;
1892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
190e14391e94c850b8bd03680c23b38978db68687a8John Reck
191e14391e94c850b8bd03680c23b38978db68687a8John Reck    Vector<InspectorStyleProperty> allProperties;
192e14391e94c850b8bd03680c23b38978db68687a8John Reck    populateAllProperties(&allProperties);
193e14391e94c850b8bd03680c23b38978db68687a8John Reck
194e14391e94c850b8bd03680c23b38978db68687a8John Reck    unsigned propertyStart = 0; // Need to initialize to make the compiler happy.
195e14391e94c850b8bd03680c23b38978db68687a8John Reck    long propertyLengthDelta;
196e14391e94c850b8bd03680c23b38978db68687a8John Reck
1976b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (propertyText.stripWhiteSpace().length()) {
1986b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        RefPtr<CSSMutableStyleDeclaration> tempMutableStyle = CSSMutableStyleDeclaration::create();
1996b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        CSSParser p;
2006b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        RefPtr<CSSStyleSourceData> sourceData = CSSStyleSourceData::create();
2016b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        p.parseDeclaration(tempMutableStyle.get(), propertyText + " -webkit-boguz-propertee: none", &sourceData);
2026b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        Vector<CSSPropertySourceData>& propertyData = sourceData->propertyData;
2036b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        unsigned propertyCount = propertyData.size();
204f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
205f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // At least one property + the bogus property added just above should be present.
2062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (propertyCount < 2) {
2072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            *errorString = "Invalid property value";
2086b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            return false;
2092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
2106b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
2116b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        // Check for a proper propertyText termination (the parser could at least restore to the PROPERTY_NAME state).
2122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (propertyData.at(propertyCount - 1).name != "-webkit-boguz-propertee") {
2132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            *errorString = "Invalid property value";
2146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            return false;
2152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
2166b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    }
2176b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
218e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (overwrite) {
219e14391e94c850b8bd03680c23b38978db68687a8John Reck        ASSERT(index < allProperties.size());
220e14391e94c850b8bd03680c23b38978db68687a8John Reck        InspectorStyleProperty& property = allProperties.at(index);
221e14391e94c850b8bd03680c23b38978db68687a8John Reck        propertyStart = property.sourceData.range.start;
222e14391e94c850b8bd03680c23b38978db68687a8John Reck        unsigned propertyEnd = property.sourceData.range.end;
223e14391e94c850b8bd03680c23b38978db68687a8John Reck        unsigned oldLength = propertyEnd - propertyStart;
224e14391e94c850b8bd03680c23b38978db68687a8John Reck        unsigned newLength = propertyText.length();
225e14391e94c850b8bd03680c23b38978db68687a8John Reck        propertyLengthDelta = newLength - oldLength;
226e14391e94c850b8bd03680c23b38978db68687a8John Reck
227e14391e94c850b8bd03680c23b38978db68687a8John Reck        if (!property.disabled) {
228e14391e94c850b8bd03680c23b38978db68687a8John Reck            bool success = replacePropertyInStyleText(property, propertyText);
2292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (!success) {
2302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                *errorString = "Internal error: could not replace property value";
231e14391e94c850b8bd03680c23b38978db68687a8John Reck                return false;
2322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            }
233e14391e94c850b8bd03680c23b38978db68687a8John Reck        } else {
2346b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            unsigned textLength = propertyText.length();
2356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            unsigned disabledIndex = disabledIndexByOrdinal(index, false, allProperties);
2366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            if (!textLength) {
2376b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                // Delete disabled property.
2386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                m_disabledProperties.remove(disabledIndex);
2396b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            } else {
2406b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                // Patch disabled property text.
2416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                m_disabledProperties.at(disabledIndex).rawText = propertyText;
242e14391e94c850b8bd03680c23b38978db68687a8John Reck            }
2436b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
2446b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            // We should not shift subsequent disabled properties when altering a disabled property.
2456b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            return true;
246e14391e94c850b8bd03680c23b38978db68687a8John Reck        }
247e14391e94c850b8bd03680c23b38978db68687a8John Reck    } else {
248e14391e94c850b8bd03680c23b38978db68687a8John Reck        // Insert at index.
249cad810f21b803229eb11403f9209855525a25d57Steve Block        RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style.get());
2502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!sourceData) {
2512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            *errorString = "Internal error: no CSS rule source found";
252e14391e94c850b8bd03680c23b38978db68687a8John Reck            return false;
2532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
254e14391e94c850b8bd03680c23b38978db68687a8John Reck        String text;
255e14391e94c850b8bd03680c23b38978db68687a8John Reck        bool success = styleText(&text);
2562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!success) {
2572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            *errorString = "Internal error: could not fetch style text";
258e14391e94c850b8bd03680c23b38978db68687a8John Reck            return false;
2592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
260e14391e94c850b8bd03680c23b38978db68687a8John Reck        propertyLengthDelta = propertyText.length();
261e14391e94c850b8bd03680c23b38978db68687a8John Reck
262e14391e94c850b8bd03680c23b38978db68687a8John Reck        bool insertLast = true;
263e14391e94c850b8bd03680c23b38978db68687a8John Reck        if (index < allProperties.size()) {
264e14391e94c850b8bd03680c23b38978db68687a8John Reck            InspectorStyleProperty& property = allProperties.at(index);
265e14391e94c850b8bd03680c23b38978db68687a8John Reck            if (property.hasSource) {
266e14391e94c850b8bd03680c23b38978db68687a8John Reck                propertyStart = property.sourceData.range.start;
267e14391e94c850b8bd03680c23b38978db68687a8John Reck                // If inserting before a disabled property, it should be shifted, too.
268e14391e94c850b8bd03680c23b38978db68687a8John Reck                insertLast = false;
269e14391e94c850b8bd03680c23b38978db68687a8John Reck            }
270e14391e94c850b8bd03680c23b38978db68687a8John Reck        }
271e14391e94c850b8bd03680c23b38978db68687a8John Reck
2726b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        String textToSet = propertyText;
2736b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (insertLast) {
2746b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            propertyStart = sourceData->styleSourceData->styleBodyRange.end - sourceData->styleSourceData->styleBodyRange.start;
2756b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            if (propertyStart && propertyText.length()) {
2766b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                const UChar* characters = text.characters();
2776b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
2786b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                unsigned curPos = propertyStart - 1; // The last position of style declaration, since propertyStart points past one.
2796b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                while (curPos && isHTMLSpace(characters[curPos]))
2806b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    --curPos;
2816b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                if (curPos && characters[curPos] != ';') {
2826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    // Prepend a ";" to the property text if appending to a style declaration where
2836b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    // the last property has no trailing ";".
2846b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    textToSet.insert("; ", 0);
2856b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                } else if (!isHTMLSpace(characters[propertyStart - 1])) {
2866b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    // Prepend a " " if the last declaration character is not an HTML space.
2876b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    textToSet.insert(" ", 0);
2886b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                }
2896b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            }
2906b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        }
2916b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
2926b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        text.insert(textToSet, propertyStart);
293cad810f21b803229eb11403f9209855525a25d57Steve Block        m_parentStyleSheet->setStyleText(m_style.get(), text);
294e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
295e14391e94c850b8bd03680c23b38978db68687a8John Reck
2966b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // Recompute subsequent disabled property ranges if acting on a non-disabled property.
297e14391e94c850b8bd03680c23b38978db68687a8John Reck    shiftDisabledProperties(disabledIndexByOrdinal(index, true, allProperties), propertyLengthDelta);
298e14391e94c850b8bd03680c23b38978db68687a8John Reck
299e14391e94c850b8bd03680c23b38978db68687a8John Reck    return true;
300e14391e94c850b8bd03680c23b38978db68687a8John Reck}
301e14391e94c850b8bd03680c23b38978db68687a8John Reck
3022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool InspectorStyle::toggleProperty(ErrorString* errorString, unsigned index, bool disable)
303e14391e94c850b8bd03680c23b38978db68687a8John Reck{
304e14391e94c850b8bd03680c23b38978db68687a8John Reck    ASSERT(m_parentStyleSheet);
3052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!m_parentStyleSheet->ensureParsedDataReady()) {
3062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        *errorString = "Can toggle only source-based properties";
3072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return false;
3082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
309cad810f21b803229eb11403f9209855525a25d57Steve Block    RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style.get());
3102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!sourceData) {
3112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        *errorString = "Internal error: No source data for the style found";
3122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return false;
3132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
314e14391e94c850b8bd03680c23b38978db68687a8John Reck
315e14391e94c850b8bd03680c23b38978db68687a8John Reck    Vector<InspectorStyleProperty> allProperties;
316e14391e94c850b8bd03680c23b38978db68687a8John Reck    populateAllProperties(&allProperties);
3172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (index >= allProperties.size()) {
3182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        *errorString = "Property index is outside of property range";
3192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return false;
3202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
321e14391e94c850b8bd03680c23b38978db68687a8John Reck
322e14391e94c850b8bd03680c23b38978db68687a8John Reck    InspectorStyleProperty& property = allProperties.at(index);
323e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (property.disabled == disable)
324e14391e94c850b8bd03680c23b38978db68687a8John Reck        return true; // Idempotent operation.
325e14391e94c850b8bd03680c23b38978db68687a8John Reck
326e14391e94c850b8bd03680c23b38978db68687a8John Reck    bool success;
327e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (!disable)
328e14391e94c850b8bd03680c23b38978db68687a8John Reck        success = enableProperty(index, allProperties);
329e14391e94c850b8bd03680c23b38978db68687a8John Reck    else
330e14391e94c850b8bd03680c23b38978db68687a8John Reck        success = disableProperty(index, allProperties);
331e14391e94c850b8bd03680c23b38978db68687a8John Reck
332e14391e94c850b8bd03680c23b38978db68687a8John Reck    return success;
333e14391e94c850b8bd03680c23b38978db68687a8John Reck}
334e14391e94c850b8bd03680c23b38978db68687a8John Reck
335e14391e94c850b8bd03680c23b38978db68687a8John Reck// static
336e14391e94c850b8bd03680c23b38978db68687a8John Reckunsigned InspectorStyle::disabledIndexByOrdinal(unsigned ordinal, bool canUseSubsequent, Vector<InspectorStyleProperty>& allProperties)
337e14391e94c850b8bd03680c23b38978db68687a8John Reck{
338e14391e94c850b8bd03680c23b38978db68687a8John Reck    unsigned disabledIndex = 0;
339e14391e94c850b8bd03680c23b38978db68687a8John Reck    for (unsigned i = 0, size = allProperties.size(); i < size; ++i) {
340e14391e94c850b8bd03680c23b38978db68687a8John Reck        InspectorStyleProperty& property = allProperties.at(i);
341e14391e94c850b8bd03680c23b38978db68687a8John Reck        if (property.disabled) {
342e14391e94c850b8bd03680c23b38978db68687a8John Reck            if (i == ordinal || (canUseSubsequent && i > ordinal))
343e14391e94c850b8bd03680c23b38978db68687a8John Reck                return disabledIndex;
344e14391e94c850b8bd03680c23b38978db68687a8John Reck            ++disabledIndex;
345e14391e94c850b8bd03680c23b38978db68687a8John Reck        }
346e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
347e14391e94c850b8bd03680c23b38978db68687a8John Reck
348e14391e94c850b8bd03680c23b38978db68687a8John Reck    return UINT_MAX;
349e14391e94c850b8bd03680c23b38978db68687a8John Reck}
350e14391e94c850b8bd03680c23b38978db68687a8John Reck
3516b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerbool InspectorStyle::styleText(String* result) const
352e14391e94c850b8bd03680c23b38978db68687a8John Reck{
353e14391e94c850b8bd03680c23b38978db68687a8John Reck    // Precondition: m_parentStyleSheet->ensureParsedDataReady() has been called successfully.
354cad810f21b803229eb11403f9209855525a25d57Steve Block    RefPtr<CSSRuleSourceData> sourceData = m_parentStyleSheet->ruleSourceDataFor(m_style.get());
355e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (!sourceData)
356e14391e94c850b8bd03680c23b38978db68687a8John Reck        return false;
357e14391e94c850b8bd03680c23b38978db68687a8John Reck
358e14391e94c850b8bd03680c23b38978db68687a8John Reck    String styleSheetText;
359e14391e94c850b8bd03680c23b38978db68687a8John Reck    bool success = m_parentStyleSheet->text(&styleSheetText);
360e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (!success)
361e14391e94c850b8bd03680c23b38978db68687a8John Reck        return false;
362e14391e94c850b8bd03680c23b38978db68687a8John Reck
363e14391e94c850b8bd03680c23b38978db68687a8John Reck    SourceRange& bodyRange = sourceData->styleSourceData->styleBodyRange;
364e14391e94c850b8bd03680c23b38978db68687a8John Reck    *result = styleSheetText.substring(bodyRange.start, bodyRange.end - bodyRange.start);
365e14391e94c850b8bd03680c23b38978db68687a8John Reck    return true;
366e14391e94c850b8bd03680c23b38978db68687a8John Reck}
367e14391e94c850b8bd03680c23b38978db68687a8John Reck
368e14391e94c850b8bd03680c23b38978db68687a8John Reckbool InspectorStyle::disableProperty(unsigned indexToDisable, Vector<InspectorStyleProperty>& allProperties)
369e14391e94c850b8bd03680c23b38978db68687a8John Reck{
370e14391e94c850b8bd03680c23b38978db68687a8John Reck    // Precondition: |indexToEnable| points to an enabled property.
371e14391e94c850b8bd03680c23b38978db68687a8John Reck    const InspectorStyleProperty& property = allProperties.at(indexToDisable);
372e14391e94c850b8bd03680c23b38978db68687a8John Reck    unsigned propertyStart = property.sourceData.range.start;
3736b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    InspectorStyleProperty disabledProperty(property);
374e14391e94c850b8bd03680c23b38978db68687a8John Reck    String oldStyleText;
375e14391e94c850b8bd03680c23b38978db68687a8John Reck    bool success = styleText(&oldStyleText);
376e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (!success)
377e14391e94c850b8bd03680c23b38978db68687a8John Reck        return false;
3786b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    disabledProperty.setRawTextFromStyleDeclaration(oldStyleText);
3796b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    disabledProperty.disabled = true;
3806b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    disabledProperty.sourceData.range.end = propertyStart;
3816b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // This may have to be negated below.
3826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    long propertyLength = property.sourceData.range.end - propertyStart;
383e14391e94c850b8bd03680c23b38978db68687a8John Reck    success = replacePropertyInStyleText(property, "");
384e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (!success)
385e14391e94c850b8bd03680c23b38978db68687a8John Reck        return false;
386e14391e94c850b8bd03680c23b38978db68687a8John Reck
387e14391e94c850b8bd03680c23b38978db68687a8John Reck    // Add disabled property at correct position.
388e14391e94c850b8bd03680c23b38978db68687a8John Reck    unsigned insertionIndex = disabledIndexByOrdinal(indexToDisable, true, allProperties);
389e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (insertionIndex == UINT_MAX)
390e14391e94c850b8bd03680c23b38978db68687a8John Reck        m_disabledProperties.append(disabledProperty);
391e14391e94c850b8bd03680c23b38978db68687a8John Reck    else {
392e14391e94c850b8bd03680c23b38978db68687a8John Reck        m_disabledProperties.insert(insertionIndex, disabledProperty);
393e14391e94c850b8bd03680c23b38978db68687a8John Reck        shiftDisabledProperties(insertionIndex + 1, -propertyLength); // Property removed from text - shift these back.
394e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
395e14391e94c850b8bd03680c23b38978db68687a8John Reck    return true;
396e14391e94c850b8bd03680c23b38978db68687a8John Reck}
397e14391e94c850b8bd03680c23b38978db68687a8John Reck
398e14391e94c850b8bd03680c23b38978db68687a8John Reckbool InspectorStyle::enableProperty(unsigned indexToEnable, Vector<InspectorStyleProperty>& allProperties)
399e14391e94c850b8bd03680c23b38978db68687a8John Reck{
400e14391e94c850b8bd03680c23b38978db68687a8John Reck    // Precondition: |indexToEnable| points to a disabled property.
401e14391e94c850b8bd03680c23b38978db68687a8John Reck    unsigned disabledIndex = disabledIndexByOrdinal(indexToEnable, false, allProperties);
402e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (disabledIndex == UINT_MAX)
403e14391e94c850b8bd03680c23b38978db68687a8John Reck        return false;
404e14391e94c850b8bd03680c23b38978db68687a8John Reck
405e14391e94c850b8bd03680c23b38978db68687a8John Reck    InspectorStyleProperty disabledProperty = m_disabledProperties.at(disabledIndex);
406e14391e94c850b8bd03680c23b38978db68687a8John Reck    m_disabledProperties.remove(disabledIndex);
407e14391e94c850b8bd03680c23b38978db68687a8John Reck    bool success = replacePropertyInStyleText(disabledProperty, disabledProperty.rawText);
408e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (success)
409e14391e94c850b8bd03680c23b38978db68687a8John Reck        shiftDisabledProperties(disabledIndex, disabledProperty.rawText.length());
410e14391e94c850b8bd03680c23b38978db68687a8John Reck    return success;
411e14391e94c850b8bd03680c23b38978db68687a8John Reck}
412e14391e94c850b8bd03680c23b38978db68687a8John Reck
413e14391e94c850b8bd03680c23b38978db68687a8John Reckbool InspectorStyle::populateAllProperties(Vector<InspectorStyleProperty>* result) const
414e14391e94c850b8bd03680c23b38978db68687a8John Reck{
415e14391e94c850b8bd03680c23b38978db68687a8John Reck    HashSet<String> foundShorthands;
416e14391e94c850b8bd03680c23b38978db68687a8John Reck    HashSet<String> sourcePropertyNames;
417e14391e94c850b8bd03680c23b38978db68687a8John Reck    unsigned disabledIndex = 0;
418e14391e94c850b8bd03680c23b38978db68687a8John Reck    unsigned disabledLength = m_disabledProperties.size();
419e14391e94c850b8bd03680c23b38978db68687a8John Reck    InspectorStyleProperty disabledProperty;
420e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (disabledIndex < disabledLength)
421e14391e94c850b8bd03680c23b38978db68687a8John Reck        disabledProperty = m_disabledProperties.at(disabledIndex);
422e14391e94c850b8bd03680c23b38978db68687a8John Reck
423cad810f21b803229eb11403f9209855525a25d57Steve Block    RefPtr<CSSRuleSourceData> sourceData = (m_parentStyleSheet && m_parentStyleSheet->ensureParsedDataReady()) ? m_parentStyleSheet->ruleSourceDataFor(m_style.get()) : 0;
424e14391e94c850b8bd03680c23b38978db68687a8John Reck    Vector<CSSPropertySourceData>* sourcePropertyData = sourceData ? &(sourceData->styleSourceData->propertyData) : 0;
425e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (sourcePropertyData) {
4266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        String styleDeclaration;
4276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        bool isStyleTextKnown = styleText(&styleDeclaration);
4286b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        ASSERT_UNUSED(isStyleTextKnown, isStyleTextKnown);
429e14391e94c850b8bd03680c23b38978db68687a8John Reck        for (Vector<CSSPropertySourceData>::const_iterator it = sourcePropertyData->begin(); it != sourcePropertyData->end(); ++it) {
430e14391e94c850b8bd03680c23b38978db68687a8John Reck            while (disabledIndex < disabledLength && disabledProperty.sourceData.range.start <= it->range.start) {
431e14391e94c850b8bd03680c23b38978db68687a8John Reck                result->append(disabledProperty);
432e14391e94c850b8bd03680c23b38978db68687a8John Reck                if (++disabledIndex < disabledLength)
433e14391e94c850b8bd03680c23b38978db68687a8John Reck                    disabledProperty = m_disabledProperties.at(disabledIndex);
434e14391e94c850b8bd03680c23b38978db68687a8John Reck            }
4356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            InspectorStyleProperty p(*it, true, false);
4366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            p.setRawTextFromStyleDeclaration(styleDeclaration);
4376b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            result->append(p);
4382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            sourcePropertyNames.add(it->name.lower());
439e14391e94c850b8bd03680c23b38978db68687a8John Reck        }
440e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
441e14391e94c850b8bd03680c23b38978db68687a8John Reck
442e14391e94c850b8bd03680c23b38978db68687a8John Reck    while (disabledIndex < disabledLength) {
443e14391e94c850b8bd03680c23b38978db68687a8John Reck        disabledProperty = m_disabledProperties.at(disabledIndex++);
444e14391e94c850b8bd03680c23b38978db68687a8John Reck        result->append(disabledProperty);
445e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
446e14391e94c850b8bd03680c23b38978db68687a8John Reck
447e14391e94c850b8bd03680c23b38978db68687a8John Reck    for (int i = 0, size = m_style->length(); i < size; ++i) {
448e14391e94c850b8bd03680c23b38978db68687a8John Reck        String name = m_style->item(i);
4492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (sourcePropertyNames.contains(name.lower()))
450e14391e94c850b8bd03680c23b38978db68687a8John Reck            continue;
451e14391e94c850b8bd03680c23b38978db68687a8John Reck
4522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        sourcePropertyNames.add(name.lower());
453e14391e94c850b8bd03680c23b38978db68687a8John Reck        result->append(InspectorStyleProperty(CSSPropertySourceData(name, m_style->getPropertyValue(name), !m_style->getPropertyPriority(name).isEmpty(), true, SourceRange()), false, false));
454e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
455e14391e94c850b8bd03680c23b38978db68687a8John Reck
456e14391e94c850b8bd03680c23b38978db68687a8John Reck    return true;
457e14391e94c850b8bd03680c23b38978db68687a8John Reck}
458e14391e94c850b8bd03680c23b38978db68687a8John Reck
459e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid InspectorStyle::populateObjectWithStyleProperties(InspectorObject* result) const
460e14391e94c850b8bd03680c23b38978db68687a8John Reck{
461e14391e94c850b8bd03680c23b38978db68687a8John Reck    Vector<InspectorStyleProperty> properties;
462e14391e94c850b8bd03680c23b38978db68687a8John Reck    populateAllProperties(&properties);
463e14391e94c850b8bd03680c23b38978db68687a8John Reck
464e14391e94c850b8bd03680c23b38978db68687a8John Reck    RefPtr<InspectorArray> propertiesObject = InspectorArray::create();
4652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    RefPtr<InspectorArray> shorthandEntries = InspectorArray::create();
466e14391e94c850b8bd03680c23b38978db68687a8John Reck    HashMap<String, RefPtr<InspectorObject> > propertyNameToPreviousActiveProperty;
467e14391e94c850b8bd03680c23b38978db68687a8John Reck    HashSet<String> foundShorthands;
468e14391e94c850b8bd03680c23b38978db68687a8John Reck
469e14391e94c850b8bd03680c23b38978db68687a8John Reck    for (Vector<InspectorStyleProperty>::iterator it = properties.begin(), itEnd = properties.end(); it != itEnd; ++it) {
470e14391e94c850b8bd03680c23b38978db68687a8John Reck        const CSSPropertySourceData& propertyEntry = it->sourceData;
471e14391e94c850b8bd03680c23b38978db68687a8John Reck        const String& name = propertyEntry.name;
472e14391e94c850b8bd03680c23b38978db68687a8John Reck
473e14391e94c850b8bd03680c23b38978db68687a8John Reck        RefPtr<InspectorObject> property = InspectorObject::create();
474e14391e94c850b8bd03680c23b38978db68687a8John Reck        propertiesObject->pushObject(property);
4752bde8e466a4451c7319e3a072d118917957d6554Steve Block        String status = it->disabled ? "disabled" : "active";
4762bde8e466a4451c7319e3a072d118917957d6554Steve Block
4772bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Default "parsedOk" == true.
4782bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!propertyEntry.parsedOk)
4792bde8e466a4451c7319e3a072d118917957d6554Steve Block            property->setBoolean("parsedOk", false);
4806b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (it->hasRawText())
4816b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            property->setString("text", it->rawText);
4826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        property->setString("name", name);
4836b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        property->setString("value", propertyEntry.value);
4842bde8e466a4451c7319e3a072d118917957d6554Steve Block
4852bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Default "priority" == "".
4862bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (propertyEntry.important)
4872bde8e466a4451c7319e3a072d118917957d6554Steve Block            property->setString("priority", "important");
488e14391e94c850b8bd03680c23b38978db68687a8John Reck        if (!it->disabled) {
489e14391e94c850b8bd03680c23b38978db68687a8John Reck            if (it->hasSource) {
490e14391e94c850b8bd03680c23b38978db68687a8John Reck                property->setBoolean("implicit", false);
4912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                property->setObject("range", buildSourceRangeObject(propertyEntry.range));
492e14391e94c850b8bd03680c23b38978db68687a8John Reck
4934576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                // Parsed property overrides any property with the same name. Non-parsed property overrides
4944576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                // previous non-parsed property with the same name (if any).
4954576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                bool shouldInactivate = false;
496e14391e94c850b8bd03680c23b38978db68687a8John Reck                HashMap<String, RefPtr<InspectorObject> >::iterator activeIt = propertyNameToPreviousActiveProperty.find(name);
497e14391e94c850b8bd03680c23b38978db68687a8John Reck                if (activeIt != propertyNameToPreviousActiveProperty.end()) {
4984576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                    if (propertyEntry.parsedOk)
4994576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                        shouldInactivate = true;
5004576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                    else {
5014576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                        bool previousParsedOk;
5024576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                        bool success = activeIt->second->getBoolean("parsedOk", &previousParsedOk);
5034576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                        if (success && !previousParsedOk)
5044576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                            shouldInactivate = true;
5054576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                    }
5064576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                } else
5074576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                    propertyNameToPreviousActiveProperty.set(name, property);
5084576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
5094576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                if (shouldInactivate) {
510e14391e94c850b8bd03680c23b38978db68687a8John Reck                    activeIt->second->setString("status", "inactive");
5112bde8e466a4451c7319e3a072d118917957d6554Steve Block                    activeIt->second->remove("shorthandName");
5124576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                    propertyNameToPreviousActiveProperty.set(name, property);
513e14391e94c850b8bd03680c23b38978db68687a8John Reck                }
514e14391e94c850b8bd03680c23b38978db68687a8John Reck            } else {
5152bde8e466a4451c7319e3a072d118917957d6554Steve Block                bool implicit = m_style->isPropertyImplicit(name);
5162bde8e466a4451c7319e3a072d118917957d6554Steve Block                // Default "implicit" == false.
5172bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (implicit)
5182bde8e466a4451c7319e3a072d118917957d6554Steve Block                    property->setBoolean("implicit", true);
5192bde8e466a4451c7319e3a072d118917957d6554Steve Block                status = "";
520e14391e94c850b8bd03680c23b38978db68687a8John Reck            }
5216b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        }
522e14391e94c850b8bd03680c23b38978db68687a8John Reck
5232bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Default "status" == "style".
5242bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!status.isEmpty())
5252bde8e466a4451c7319e3a072d118917957d6554Steve Block            property->setString("status", status);
5262bde8e466a4451c7319e3a072d118917957d6554Steve Block
527e14391e94c850b8bd03680c23b38978db68687a8John Reck        if (propertyEntry.parsedOk) {
528e14391e94c850b8bd03680c23b38978db68687a8John Reck            // Both for style-originated and parsed source properties.
529e14391e94c850b8bd03680c23b38978db68687a8John Reck            String shorthand = m_style->getPropertyShorthand(name);
5302bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (!shorthand.isEmpty()) {
5312bde8e466a4451c7319e3a072d118917957d6554Steve Block                // Default "shorthandName" == "".
5322bde8e466a4451c7319e3a072d118917957d6554Steve Block                property->setString("shorthandName", shorthand);
5332bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (!foundShorthands.contains(shorthand)) {
5342bde8e466a4451c7319e3a072d118917957d6554Steve Block                    foundShorthands.add(shorthand);
5352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    RefPtr<InspectorObject> shorthandEntry = InspectorObject::create();
5362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    shorthandEntry->setString("name", shorthand);
5372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    shorthandEntry->setString("value", shorthandValue(shorthand));
5382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    shorthandEntries->pushObject(shorthandEntry.release());
5392bde8e466a4451c7319e3a072d118917957d6554Steve Block                }
540e14391e94c850b8bd03680c23b38978db68687a8John Reck            }
5412bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
5422bde8e466a4451c7319e3a072d118917957d6554Steve Block        // else shorthandName is not set
543e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
544e14391e94c850b8bd03680c23b38978db68687a8John Reck
545e14391e94c850b8bd03680c23b38978db68687a8John Reck    result->setArray("cssProperties", propertiesObject);
5462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    result->setArray("shorthandEntries", shorthandEntries);
547e14391e94c850b8bd03680c23b38978db68687a8John Reck}
548e14391e94c850b8bd03680c23b38978db68687a8John Reck
549e14391e94c850b8bd03680c23b38978db68687a8John Reck
550e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid InspectorStyle::shiftDisabledProperties(unsigned fromIndex, long delta)
551e14391e94c850b8bd03680c23b38978db68687a8John Reck{
552e14391e94c850b8bd03680c23b38978db68687a8John Reck    for (unsigned i = fromIndex, size = m_disabledProperties.size(); i < size; ++i) {
553e14391e94c850b8bd03680c23b38978db68687a8John Reck        SourceRange& range = m_disabledProperties.at(i).sourceData.range;
554e14391e94c850b8bd03680c23b38978db68687a8John Reck        range.start += delta;
555e14391e94c850b8bd03680c23b38978db68687a8John Reck        range.end += delta;
556e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
557e14391e94c850b8bd03680c23b38978db68687a8John Reck}
558e14391e94c850b8bd03680c23b38978db68687a8John Reck
559e14391e94c850b8bd03680c23b38978db68687a8John Reckbool InspectorStyle::replacePropertyInStyleText(const InspectorStyleProperty& property, const String& newText)
560e14391e94c850b8bd03680c23b38978db68687a8John Reck{
561e14391e94c850b8bd03680c23b38978db68687a8John Reck    // Precondition: m_parentStyleSheet->ensureParsedDataReady() has been called successfully.
562e14391e94c850b8bd03680c23b38978db68687a8John Reck    String text;
563e14391e94c850b8bd03680c23b38978db68687a8John Reck    bool success = styleText(&text);
564e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (!success)
565e14391e94c850b8bd03680c23b38978db68687a8John Reck        return false;
566e14391e94c850b8bd03680c23b38978db68687a8John Reck    const SourceRange& range = property.sourceData.range;
567e14391e94c850b8bd03680c23b38978db68687a8John Reck    text.replace(range.start, range.end - range.start, newText);
568cad810f21b803229eb11403f9209855525a25d57Steve Block    success = m_parentStyleSheet->setStyleText(m_style.get(), text);
569e14391e94c850b8bd03680c23b38978db68687a8John Reck    return success;
570e14391e94c850b8bd03680c23b38978db68687a8John Reck}
571e14391e94c850b8bd03680c23b38978db68687a8John Reck
572e14391e94c850b8bd03680c23b38978db68687a8John ReckString InspectorStyle::shorthandValue(const String& shorthandProperty) const
573e14391e94c850b8bd03680c23b38978db68687a8John Reck{
574e14391e94c850b8bd03680c23b38978db68687a8John Reck    String value = m_style->getPropertyValue(shorthandProperty);
575e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (value.isEmpty()) {
576e14391e94c850b8bd03680c23b38978db68687a8John Reck        for (unsigned i = 0; i < m_style->length(); ++i) {
577e14391e94c850b8bd03680c23b38978db68687a8John Reck            String individualProperty = m_style->item(i);
578e14391e94c850b8bd03680c23b38978db68687a8John Reck            if (m_style->getPropertyShorthand(individualProperty) != shorthandProperty)
579e14391e94c850b8bd03680c23b38978db68687a8John Reck                continue;
580e14391e94c850b8bd03680c23b38978db68687a8John Reck            if (m_style->isPropertyImplicit(individualProperty))
581e14391e94c850b8bd03680c23b38978db68687a8John Reck                continue;
582e14391e94c850b8bd03680c23b38978db68687a8John Reck            String individualValue = m_style->getPropertyValue(individualProperty);
583e14391e94c850b8bd03680c23b38978db68687a8John Reck            if (individualValue == "initial")
584e14391e94c850b8bd03680c23b38978db68687a8John Reck                continue;
585e14391e94c850b8bd03680c23b38978db68687a8John Reck            if (value.length())
586e14391e94c850b8bd03680c23b38978db68687a8John Reck                value.append(" ");
587e14391e94c850b8bd03680c23b38978db68687a8John Reck            value.append(individualValue);
588e14391e94c850b8bd03680c23b38978db68687a8John Reck        }
589e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
590e14391e94c850b8bd03680c23b38978db68687a8John Reck    return value;
591e14391e94c850b8bd03680c23b38978db68687a8John Reck}
592e14391e94c850b8bd03680c23b38978db68687a8John Reck
593e14391e94c850b8bd03680c23b38978db68687a8John ReckString InspectorStyle::shorthandPriority(const String& shorthandProperty) const
594e14391e94c850b8bd03680c23b38978db68687a8John Reck{
595e14391e94c850b8bd03680c23b38978db68687a8John Reck    String priority = m_style->getPropertyPriority(shorthandProperty);
596e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (priority.isEmpty()) {
597e14391e94c850b8bd03680c23b38978db68687a8John Reck        for (unsigned i = 0; i < m_style->length(); ++i) {
598e14391e94c850b8bd03680c23b38978db68687a8John Reck            String individualProperty = m_style->item(i);
599e14391e94c850b8bd03680c23b38978db68687a8John Reck            if (m_style->getPropertyShorthand(individualProperty) != shorthandProperty)
600e14391e94c850b8bd03680c23b38978db68687a8John Reck                continue;
601e14391e94c850b8bd03680c23b38978db68687a8John Reck            priority = m_style->getPropertyPriority(individualProperty);
602e14391e94c850b8bd03680c23b38978db68687a8John Reck            break;
603e14391e94c850b8bd03680c23b38978db68687a8John Reck        }
604e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
605e14391e94c850b8bd03680c23b38978db68687a8John Reck    return priority;
606e14391e94c850b8bd03680c23b38978db68687a8John Reck}
607e14391e94c850b8bd03680c23b38978db68687a8John Reck
608e14391e94c850b8bd03680c23b38978db68687a8John ReckVector<String> InspectorStyle::longhandProperties(const String& shorthandProperty) const
609e14391e94c850b8bd03680c23b38978db68687a8John Reck{
610e14391e94c850b8bd03680c23b38978db68687a8John Reck    Vector<String> properties;
611e14391e94c850b8bd03680c23b38978db68687a8John Reck    HashSet<String> foundProperties;
612e14391e94c850b8bd03680c23b38978db68687a8John Reck    for (unsigned i = 0; i < m_style->length(); ++i) {
613e14391e94c850b8bd03680c23b38978db68687a8John Reck        String individualProperty = m_style->item(i);
614e14391e94c850b8bd03680c23b38978db68687a8John Reck        if (foundProperties.contains(individualProperty) || m_style->getPropertyShorthand(individualProperty) != shorthandProperty)
615e14391e94c850b8bd03680c23b38978db68687a8John Reck            continue;
616e14391e94c850b8bd03680c23b38978db68687a8John Reck
617e14391e94c850b8bd03680c23b38978db68687a8John Reck        foundProperties.add(individualProperty);
618e14391e94c850b8bd03680c23b38978db68687a8John Reck        properties.append(individualProperty);
619e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
620e14391e94c850b8bd03680c23b38978db68687a8John Reck    return properties;
621e14391e94c850b8bd03680c23b38978db68687a8John Reck}
622e14391e94c850b8bd03680c23b38978db68687a8John Reck
623cad810f21b803229eb11403f9209855525a25d57Steve BlockPassRefPtr<InspectorStyleSheet> InspectorStyleSheet::create(const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, const String& origin, const String& documentURL)
624cad810f21b803229eb11403f9209855525a25d57Steve Block{
625cad810f21b803229eb11403f9209855525a25d57Steve Block    return adoptRef(new InspectorStyleSheet(id, pageStyleSheet, origin, documentURL));
626cad810f21b803229eb11403f9209855525a25d57Steve Block}
627cad810f21b803229eb11403f9209855525a25d57Steve Block
628cad810f21b803229eb11403f9209855525a25d57Steve BlockInspectorStyleSheet::InspectorStyleSheet(const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, const String& origin, const String& documentURL)
629a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    : m_id(id)
630a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_pageStyleSheet(pageStyleSheet)
631a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_origin(origin)
632a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_documentURL(documentURL)
633a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_isRevalidating(false)
634a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
635a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_parsedStyleSheet = new ParsedStyleSheet();
636a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
637a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
638a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochInspectorStyleSheet::~InspectorStyleSheet()
639a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
640a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    delete m_parsedStyleSheet;
641a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
642a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
6434576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) WangString InspectorStyleSheet::finalURL() const
6444576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang{
6454576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    if (m_pageStyleSheet && !m_pageStyleSheet->finalURL().isEmpty())
6464576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        return m_pageStyleSheet->finalURL().string();
6474576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    return m_documentURL;
6484576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang}
6494576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
6504576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangvoid InspectorStyleSheet::reparseStyleSheet(const String& text)
6514576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang{
6524576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    for (unsigned i = 0, size = m_pageStyleSheet->length(); i < size; ++i)
6534a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        m_pageStyleSheet->remove(0);
6544576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    m_pageStyleSheet->parseString(text, m_pageStyleSheet->useStrictParsing());
6554a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    m_pageStyleSheet->styleSheetChanged();
6564576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    m_inspectorStyles.clear();
6574576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang}
6584576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
659a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochbool InspectorStyleSheet::setText(const String& text)
660a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
661a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!m_parsedStyleSheet)
662a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
663a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
664a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_parsedStyleSheet->setText(text);
6654576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    m_flatRules.clear();
666a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
667a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return true;
668a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
669a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
670e14391e94c850b8bd03680c23b38978db68687a8John Reckbool InspectorStyleSheet::setRuleSelector(const InspectorCSSId& id, const String& selector)
671a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
672e14391e94c850b8bd03680c23b38978db68687a8John Reck    CSSStyleRule* rule = ruleForId(id);
673a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!rule)
674a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
675a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    CSSStyleSheet* styleSheet = InspectorCSSAgent::parentStyleSheet(rule);
676a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!styleSheet || !ensureParsedDataReady())
677a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
678a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
679a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    rule->setSelectorText(selector);
680a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<CSSRuleSourceData> sourceData = ruleSourceDataFor(rule->style());
681a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!sourceData)
682a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
683a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
684e14391e94c850b8bd03680c23b38978db68687a8John Reck    String sheetText = m_parsedStyleSheet->text();
685e14391e94c850b8bd03680c23b38978db68687a8John Reck    sheetText.replace(sourceData->selectorListRange.start, sourceData->selectorListRange.end - sourceData->selectorListRange.start, selector);
686e14391e94c850b8bd03680c23b38978db68687a8John Reck    m_parsedStyleSheet->setText(sheetText);
687a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return true;
688a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
689a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
690a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochCSSStyleRule* InspectorStyleSheet::addRule(const String& selector)
691a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
692e14391e94c850b8bd03680c23b38978db68687a8John Reck    String styleSheetText;
693e14391e94c850b8bd03680c23b38978db68687a8John Reck    bool success = text(&styleSheetText);
694a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!success)
695a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return 0;
696a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
697a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ExceptionCode ec = 0;
698a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_pageStyleSheet->addRule(selector, "", ec);
699a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (ec)
700a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return 0;
701a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<CSSRuleList> rules = m_pageStyleSheet->cssRules();
702a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT(rules->length());
703a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    CSSStyleRule* rule = InspectorCSSAgent::asCSSStyleRule(rules->item(rules->length() - 1));
704a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT(rule);
705a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
706e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (styleSheetText.length())
707e14391e94c850b8bd03680c23b38978db68687a8John Reck        styleSheetText += "\n";
708a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
709e14391e94c850b8bd03680c23b38978db68687a8John Reck    styleSheetText += selector;
710e14391e94c850b8bd03680c23b38978db68687a8John Reck    styleSheetText += " {}";
7114576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    // Using setText() as this operation changes the style sheet rule set.
7124576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    setText(styleSheetText);
713a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
714a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return rule;
715a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
716a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
717e14391e94c850b8bd03680c23b38978db68687a8John ReckCSSStyleRule* InspectorStyleSheet::ruleForId(const InspectorCSSId& id) const
718a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
719a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!m_pageStyleSheet)
720a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return 0;
721a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
722e14391e94c850b8bd03680c23b38978db68687a8John Reck    ASSERT(!id.isEmpty());
7234576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    ensureFlatRules();
7244576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    return id.ordinal() >= m_flatRules.size() ? 0 : m_flatRules.at(id.ordinal());
725a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
726a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
727a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
728a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochPassRefPtr<InspectorObject> InspectorStyleSheet::buildObjectForStyleSheet()
729a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
730a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    CSSStyleSheet* styleSheet = pageStyleSheet();
731a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!styleSheet)
732a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return 0;
733a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
734a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<InspectorObject> result = InspectorObject::create();
7352bde8e466a4451c7319e3a072d118917957d6554Steve Block    result->setString("styleSheetId", id());
736a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<CSSRuleList> cssRuleList = CSSRuleList::create(styleSheet, true);
737a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<InspectorArray> cssRules = buildArrayForRuleList(cssRuleList.get());
738e14391e94c850b8bd03680c23b38978db68687a8John Reck    result->setArray("rules", cssRules.release());
739a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
740a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    String styleSheetText;
741a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool success = text(&styleSheetText);
742a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (success)
743a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        result->setString("text", styleSheetText);
744a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
7452bde8e466a4451c7319e3a072d118917957d6554Steve Block    return result.release();
7462bde8e466a4451c7319e3a072d118917957d6554Steve Block}
7472bde8e466a4451c7319e3a072d118917957d6554Steve Block
7482bde8e466a4451c7319e3a072d118917957d6554Steve BlockPassRefPtr<InspectorObject> InspectorStyleSheet::buildObjectForStyleSheetInfo()
7492bde8e466a4451c7319e3a072d118917957d6554Steve Block{
7502bde8e466a4451c7319e3a072d118917957d6554Steve Block    CSSStyleSheet* styleSheet = pageStyleSheet();
7512bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!styleSheet)
7522bde8e466a4451c7319e3a072d118917957d6554Steve Block        return 0;
753e14391e94c850b8bd03680c23b38978db68687a8John Reck
7542bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<InspectorObject> result = InspectorObject::create();
7552bde8e466a4451c7319e3a072d118917957d6554Steve Block    result->setString("styleSheetId", id());
7562bde8e466a4451c7319e3a072d118917957d6554Steve Block    result->setBoolean("disabled", styleSheet->disabled());
7572bde8e466a4451c7319e3a072d118917957d6554Steve Block    result->setString("sourceURL", finalURL());
7582bde8e466a4451c7319e3a072d118917957d6554Steve Block    result->setString("title", styleSheet->title());
759a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return result.release();
760a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
761a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
762a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochPassRefPtr<InspectorObject> InspectorStyleSheet::buildObjectForRule(CSSStyleRule* rule)
763a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
764a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    CSSStyleSheet* styleSheet = pageStyleSheet();
765a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!styleSheet)
766a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return 0;
767a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
768a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<InspectorObject> result = InspectorObject::create();
769a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    result->setString("selectorText", rule->selectorText());
7706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // "sourceURL" is present only for regular rules, otherwise "origin" should be used in the frontend.
7716b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (!m_origin.length())
7724576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        result->setString("sourceURL", finalURL());
773a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    result->setNumber("sourceLine", rule->sourceLine());
774a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    result->setString("origin", m_origin);
775a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
776a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    result->setObject("style", buildObjectForStyle(rule->style()));
7774576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    if (canBind()) {
7784576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        InspectorCSSId id(ruleId(rule));
7794576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        if (!id.isEmpty())
7804576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            result->setValue("ruleId", id.asInspectorValue());
7814576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    }
782a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
7836b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    RefPtr<CSSRuleSourceData> sourceData;
7846b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (ensureParsedDataReady())
7856b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        sourceData = ruleSourceDataFor(rule->style());
7866b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (sourceData) {
7876b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        RefPtr<InspectorObject> selectorRange = InspectorObject::create();
7886b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        selectorRange->setNumber("start", sourceData->selectorListRange.start);
7896b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        selectorRange->setNumber("end", sourceData->selectorListRange.end);
7906b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        result->setObject("selectorRange", selectorRange.release());
7916b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    }
7926b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
793a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return result.release();
794a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
795a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
796a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochPassRefPtr<InspectorObject> InspectorStyleSheet::buildObjectForStyle(CSSStyleDeclaration* style)
797a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
798a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<CSSRuleSourceData> sourceData;
799a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (ensureParsedDataReady())
800a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        sourceData = ruleSourceDataFor(style);
801a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
8024576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    InspectorCSSId id = ruleOrStyleId(style);
8034576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    if (id.isEmpty()) {
8044576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        RefPtr<InspectorObject> bogusStyle = InspectorObject::create();
8054576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        bogusStyle->setArray("cssProperties", InspectorArray::create());
8064576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        bogusStyle->setObject("shorthandValues", InspectorObject::create());
8074576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        bogusStyle->setObject("properties", InspectorObject::create());
8084576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        return bogusStyle.release();
8094576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    }
8104576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
811e14391e94c850b8bd03680c23b38978db68687a8John Reck    RefPtr<InspectorObject> result = inspectorStyle->buildObjectForStyle();
812e14391e94c850b8bd03680c23b38978db68687a8John Reck
813e14391e94c850b8bd03680c23b38978db68687a8John Reck    // Style text cannot be retrieved without stylesheet, so set cssText here.
814e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (sourceData) {
815e14391e94c850b8bd03680c23b38978db68687a8John Reck        String sheetText;
816e14391e94c850b8bd03680c23b38978db68687a8John Reck        bool success = text(&sheetText);
817e14391e94c850b8bd03680c23b38978db68687a8John Reck        if (success) {
818e14391e94c850b8bd03680c23b38978db68687a8John Reck            const SourceRange& bodyRange = sourceData->styleSourceData->styleBodyRange;
819e14391e94c850b8bd03680c23b38978db68687a8John Reck            result->setString("cssText", sheetText.substring(bodyRange.start, bodyRange.end - bodyRange.start));
820e14391e94c850b8bd03680c23b38978db68687a8John Reck        }
821e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
822e14391e94c850b8bd03680c23b38978db68687a8John Reck
823a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return result.release();
824a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
825a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
8262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool InspectorStyleSheet::setPropertyText(ErrorString* errorString, const InspectorCSSId& id, unsigned propertyIndex, const String& text, bool overwrite)
827e14391e94c850b8bd03680c23b38978db68687a8John Reck{
828e14391e94c850b8bd03680c23b38978db68687a8John Reck    RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
8292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!inspectorStyle) {
8302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        *errorString = "No style found for given id";
831e14391e94c850b8bd03680c23b38978db68687a8John Reck        return false;
8322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
833e14391e94c850b8bd03680c23b38978db68687a8John Reck
8342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return inspectorStyle->setPropertyText(errorString, propertyIndex, text, overwrite);
835e14391e94c850b8bd03680c23b38978db68687a8John Reck}
836e14391e94c850b8bd03680c23b38978db68687a8John Reck
8372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool InspectorStyleSheet::toggleProperty(ErrorString* errorString, const InspectorCSSId& id, unsigned propertyIndex, bool disable)
838e14391e94c850b8bd03680c23b38978db68687a8John Reck{
839e14391e94c850b8bd03680c23b38978db68687a8John Reck    RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
8402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!inspectorStyle) {
8412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        *errorString = "No style found for given id";
842e14391e94c850b8bd03680c23b38978db68687a8John Reck        return false;
8432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
844e14391e94c850b8bd03680c23b38978db68687a8John Reck
8452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    bool success = inspectorStyle->toggleProperty(errorString, propertyIndex, disable);
846e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (success) {
847e14391e94c850b8bd03680c23b38978db68687a8John Reck        if (disable)
848e14391e94c850b8bd03680c23b38978db68687a8John Reck            rememberInspectorStyle(inspectorStyle);
849e14391e94c850b8bd03680c23b38978db68687a8John Reck        else if (!inspectorStyle->hasDisabledProperties())
850e14391e94c850b8bd03680c23b38978db68687a8John Reck            forgetInspectorStyle(inspectorStyle->cssStyle());
851e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
852e14391e94c850b8bd03680c23b38978db68687a8John Reck    return success;
853e14391e94c850b8bd03680c23b38978db68687a8John Reck}
854e14391e94c850b8bd03680c23b38978db68687a8John Reck
8554576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangbool InspectorStyleSheet::text(String* result) const
8564576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang{
8574576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    if (!ensureText())
8584576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        return false;
8594576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    *result = m_parsedStyleSheet->text();
8604576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    return true;
8614576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang}
8624576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
863e14391e94c850b8bd03680c23b38978db68687a8John ReckCSSStyleDeclaration* InspectorStyleSheet::styleForId(const InspectorCSSId& id) const
864a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
865a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    CSSStyleRule* rule = ruleForId(id);
866a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!rule)
867a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return 0;
868a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
869a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return rule->style();
870a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
871a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
872e14391e94c850b8bd03680c23b38978db68687a8John ReckPassRefPtr<InspectorStyle> InspectorStyleSheet::inspectorStyleForId(const InspectorCSSId& id)
873a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
874e14391e94c850b8bd03680c23b38978db68687a8John Reck    CSSStyleDeclaration* style = styleForId(id);
875a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!style)
876e14391e94c850b8bd03680c23b38978db68687a8John Reck        return 0;
877e14391e94c850b8bd03680c23b38978db68687a8John Reck
878e14391e94c850b8bd03680c23b38978db68687a8John Reck    InspectorStyleMap::iterator it = m_inspectorStyles.find(style);
879e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (it == m_inspectorStyles.end()) {
880e14391e94c850b8bd03680c23b38978db68687a8John Reck        RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(id, style, this);
881e14391e94c850b8bd03680c23b38978db68687a8John Reck        return inspectorStyle.release();
882e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
883e14391e94c850b8bd03680c23b38978db68687a8John Reck    return it->second;
884e14391e94c850b8bd03680c23b38978db68687a8John Reck}
885a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
886e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid InspectorStyleSheet::rememberInspectorStyle(RefPtr<InspectorStyle> inspectorStyle)
887e14391e94c850b8bd03680c23b38978db68687a8John Reck{
888e14391e94c850b8bd03680c23b38978db68687a8John Reck    m_inspectorStyles.set(inspectorStyle->cssStyle(), inspectorStyle);
889e14391e94c850b8bd03680c23b38978db68687a8John Reck}
890e14391e94c850b8bd03680c23b38978db68687a8John Reck
891e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid InspectorStyleSheet::forgetInspectorStyle(CSSStyleDeclaration* style)
892e14391e94c850b8bd03680c23b38978db68687a8John Reck{
893e14391e94c850b8bd03680c23b38978db68687a8John Reck    m_inspectorStyles.remove(style);
894e14391e94c850b8bd03680c23b38978db68687a8John Reck}
895e14391e94c850b8bd03680c23b38978db68687a8John Reck
896e14391e94c850b8bd03680c23b38978db68687a8John ReckInspectorCSSId InspectorStyleSheet::ruleOrStyleId(CSSStyleDeclaration* style) const
897e14391e94c850b8bd03680c23b38978db68687a8John Reck{
898e14391e94c850b8bd03680c23b38978db68687a8John Reck    unsigned index = ruleIndexByStyle(style);
899e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (index != UINT_MAX)
9004576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        return InspectorCSSId(id(), index);
901e14391e94c850b8bd03680c23b38978db68687a8John Reck    return InspectorCSSId();
902a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
903a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
904a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochDocument* InspectorStyleSheet::ownerDocument() const
905a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
906a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return m_pageStyleSheet->document();
907a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
908a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
909a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochRefPtr<CSSRuleSourceData> InspectorStyleSheet::ruleSourceDataFor(CSSStyleDeclaration* style) const
910a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
911a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return m_parsedStyleSheet->ruleSourceDataAt(ruleIndexByStyle(style));
912a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
913a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
914a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochunsigned InspectorStyleSheet::ruleIndexByStyle(CSSStyleDeclaration* pageStyle) const
915a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
9164576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    ensureFlatRules();
917a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    unsigned index = 0;
9184576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    for (unsigned i = 0, size = m_flatRules.size(); i < size; ++i) {
9194576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        if (m_flatRules.at(i)->style() == pageStyle)
920a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            return index;
921a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
922a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        ++index;
923a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
924a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return UINT_MAX;
925a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
926a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
927a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochbool InspectorStyleSheet::ensureParsedDataReady()
928a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
9294576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    return ensureText() && ensureSourceData();
930a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
931a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
932a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochbool InspectorStyleSheet::ensureText() const
933a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
934a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!m_parsedStyleSheet)
935a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
936a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (m_parsedStyleSheet->hasText())
937a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return true;
938a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
939a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    String text;
940e14391e94c850b8bd03680c23b38978db68687a8John Reck    bool success = originalStyleSheetText(&text);
941a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (success)
942a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_parsedStyleSheet->setText(text);
9434576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    // No need to clear m_flatRules here - it's empty.
944a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
945a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return success;
946a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
947a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
9484576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangbool InspectorStyleSheet::ensureSourceData()
949a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
950a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (m_parsedStyleSheet->hasSourceData())
951a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return true;
952a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
953a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!m_parsedStyleSheet->hasText())
954a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
955a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
9564576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    RefPtr<CSSStyleSheet> newStyleSheet = CSSStyleSheet::create();
957a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    CSSParser p;
958a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    StyleRuleRangeMap ruleRangeMap;
959a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    p.parseSheet(newStyleSheet.get(), m_parsedStyleSheet->text(), 0, &ruleRangeMap);
960a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    OwnPtr<ParsedStyleSheet::SourceData> rangesVector(new ParsedStyleSheet::SourceData());
961a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
9624576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    Vector<CSSStyleRule*> rules;
9634576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    RefPtr<CSSRuleList> ruleList = asCSSRuleList(newStyleSheet.get());
9644576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    collectFlatRules(ruleList, &rules);
9654576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    for (unsigned i = 0, size = rules.size(); i < size; ++i) {
9664576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        StyleRuleRangeMap::iterator it = ruleRangeMap.find(rules.at(i));
9676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (it != ruleRangeMap.end()) {
9686b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            fixUnparsedPropertyRanges(it->second.get(), m_parsedStyleSheet->text());
969a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            rangesVector->append(it->second);
9706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        }
971a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
972a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
973a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_parsedStyleSheet->setSourceData(rangesVector.release());
974a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return m_parsedStyleSheet->hasSourceData();
975a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
976a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
9774576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangvoid InspectorStyleSheet::ensureFlatRules() const
9784576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang{
9794576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    // We are fine with redoing this for empty stylesheets as this will run fast.
9804576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    if (m_flatRules.isEmpty())
9814576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        collectFlatRules(asCSSRuleList(pageStyleSheet()), &m_flatRules);
9824576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang}
9834576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
984e14391e94c850b8bd03680c23b38978db68687a8John Reckbool InspectorStyleSheet::setStyleText(CSSStyleDeclaration* style, const String& text)
985a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
986a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!pageStyleSheet())
987a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
988a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!ensureParsedDataReady())
989a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
990a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
991a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    String patchedStyleSheetText;
992a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool success = styleSheetTextWithChangedStyle(style, text, &patchedStyleSheetText);
993a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!success)
994a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
995a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
996e14391e94c850b8bd03680c23b38978db68687a8John Reck    InspectorCSSId id = ruleOrStyleId(style);
997a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (id.isEmpty())
998a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
999a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1000a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ExceptionCode ec = 0;
1001a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    style->setCssText(text, ec);
1002a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!ec)
1003e14391e94c850b8bd03680c23b38978db68687a8John Reck        m_parsedStyleSheet->setText(patchedStyleSheetText);
1004a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1005a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return !ec;
1006a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1007a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1008a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochbool InspectorStyleSheet::styleSheetTextWithChangedStyle(CSSStyleDeclaration* style, const String& newStyleText, String* result)
1009a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1010a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!style)
1011a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
1012a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1013a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!ensureParsedDataReady())
1014a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
1015a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1016a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<CSSRuleSourceData> sourceData = ruleSourceDataFor(style);
1017a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    unsigned bodyStart = sourceData->styleSourceData->styleBodyRange.start;
1018a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    unsigned bodyEnd = sourceData->styleSourceData->styleBodyRange.end;
1019a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT(bodyStart <= bodyEnd);
1020a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1021a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    String text = m_parsedStyleSheet->text();
1022a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT(bodyEnd <= text.length()); // bodyEnd is exclusive
1023a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1024e14391e94c850b8bd03680c23b38978db68687a8John Reck    text.replace(bodyStart, bodyEnd - bodyStart, newStyleText);
1025e14391e94c850b8bd03680c23b38978db68687a8John Reck    *result = text;
1026a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return true;
1027a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1028a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1029e14391e94c850b8bd03680c23b38978db68687a8John ReckInspectorCSSId InspectorStyleSheet::ruleId(CSSStyleRule* rule) const
1030a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1031e14391e94c850b8bd03680c23b38978db68687a8John Reck    return ruleOrStyleId(rule->style());
1032a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1033a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1034a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid InspectorStyleSheet::revalidateStyle(CSSStyleDeclaration* pageStyle)
1035a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1036a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (m_isRevalidating)
1037a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
1038a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1039a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_isRevalidating = true;
10404576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    ensureFlatRules();
10414576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    for (unsigned i = 0, size = m_flatRules.size(); i < size; ++i) {
10424576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        CSSStyleRule* parsedRule = m_flatRules.at(i);
1043a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (parsedRule->style() == pageStyle) {
1044e14391e94c850b8bd03680c23b38978db68687a8John Reck            if (parsedRule->style()->cssText() != pageStyle->cssText()) {
1045e14391e94c850b8bd03680c23b38978db68687a8John Reck                // Clear the disabled properties for the invalid style here.
1046e14391e94c850b8bd03680c23b38978db68687a8John Reck                m_inspectorStyles.remove(pageStyle);
1047e14391e94c850b8bd03680c23b38978db68687a8John Reck                setStyleText(pageStyle, pageStyle->cssText());
1048e14391e94c850b8bd03680c23b38978db68687a8John Reck            }
1049a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            break;
1050a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
1051a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1052a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_isRevalidating = false;
1053a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1054a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1055e14391e94c850b8bd03680c23b38978db68687a8John Reckbool InspectorStyleSheet::originalStyleSheetText(String* result) const
1056a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1057a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    String text;
1058a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool success = inlineStyleSheetText(&text);
1059a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!success)
1060a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        success = resourceStyleSheetText(&text);
1061a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (success)
1062a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        *result = text;
1063a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return success;
1064a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1065a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1066a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochbool InspectorStyleSheet::resourceStyleSheetText(String* result) const
1067a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
10684a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch    if (m_origin == "user" || m_origin == "user-agent")
10694a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch        return false;
10704a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch
1071e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (!m_pageStyleSheet || !ownerDocument())
1072a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
1073a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
10742bde8e466a4451c7319e3a072d118917957d6554Steve Block    String error;
10752bde8e466a4451c7319e3a072d118917957d6554Steve Block    InspectorResourceAgent::resourceContent(&error, ownerDocument()->frame(), m_pageStyleSheet->finalURL(), result);
10762bde8e466a4451c7319e3a072d118917957d6554Steve Block    return error.isEmpty();
1077a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1078a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1079a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochbool InspectorStyleSheet::inlineStyleSheetText(String* result) const
1080a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1081a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!m_pageStyleSheet)
1082a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
1083a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1084a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    Node* ownerNode = m_pageStyleSheet->ownerNode();
1085a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!ownerNode || ownerNode->nodeType() != Node::ELEMENT_NODE)
1086a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
1087a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    Element* ownerElement = static_cast<Element*>(ownerNode);
1088a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (ownerElement->tagName().lower() != "style")
1089a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
1090a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    *result = ownerElement->innerText();
1091a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return true;
1092a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1093a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1094a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochPassRefPtr<InspectorArray> InspectorStyleSheet::buildArrayForRuleList(CSSRuleList* ruleList)
1095a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1096a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<InspectorArray> result = InspectorArray::create();
1097a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!ruleList)
1098a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return result.release();
1099a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
11004576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    RefPtr<CSSRuleList> refRuleList = ruleList;
11014576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    Vector<CSSStyleRule*> rules;
11024576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    collectFlatRules(refRuleList, &rules);
11034576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
11044576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    for (unsigned i = 0, size = rules.size(); i < size; ++i)
11054576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        result->pushObject(buildObjectForRule(rules.at(i)));
11064576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
11074576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    return result.release();
11084576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang}
11094576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
11104576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangvoid InspectorStyleSheet::fixUnparsedPropertyRanges(CSSRuleSourceData* ruleData, const String& styleSheetText)
11114576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang{
11124576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    Vector<CSSPropertySourceData>& propertyData = ruleData->styleSourceData->propertyData;
11134576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    unsigned size = propertyData.size();
11144576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    if (!size)
11154576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        return;
11164576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
11174576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    unsigned styleStart = ruleData->styleSourceData->styleBodyRange.start;
11184576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    const UChar* characters = styleSheetText.characters();
11194576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    CSSPropertySourceData* nextData = &(propertyData.at(0));
11204576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    for (unsigned i = 0; i < size; ++i) {
11214576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        CSSPropertySourceData* currentData = nextData;
11224576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        nextData = i < size - 1 ? &(propertyData.at(i + 1)) : 0;
11234576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
11244576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        if (currentData->parsedOk)
11254576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            continue;
11264576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        if (currentData->range.end > 0 && characters[styleStart + currentData->range.end - 1] == ';')
1127a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            continue;
1128a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
11294576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        unsigned propertyEndInStyleSheet;
11304576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        if (!nextData)
11314576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            propertyEndInStyleSheet = ruleData->styleSourceData->styleBodyRange.end - 1;
11324576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        else
11334576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            propertyEndInStyleSheet = styleStart + nextData->range.start - 1;
11344576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
11354576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        while (isHTMLSpace(characters[propertyEndInStyleSheet]))
11364576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            --propertyEndInStyleSheet;
11374576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
11384576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        // propertyEndInStyleSheet points at the last property text character.
11394576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        unsigned newPropertyEnd = propertyEndInStyleSheet - styleStart + 1; // Exclusive of the last property text character.
11404576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        if (currentData->range.end != newPropertyEnd) {
11414576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            currentData->range.end = newPropertyEnd;
11424576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            unsigned valueStartInStyleSheet = styleStart + currentData->range.start + currentData->name.length();
11434576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            while (valueStartInStyleSheet < propertyEndInStyleSheet && characters[valueStartInStyleSheet] != ':')
11444576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                ++valueStartInStyleSheet;
11454576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            if (valueStartInStyleSheet < propertyEndInStyleSheet)
11464576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                ++valueStartInStyleSheet; // Shift past the ':'.
11474576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            while (valueStartInStyleSheet < propertyEndInStyleSheet && isHTMLSpace(characters[valueStartInStyleSheet]))
11484576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                ++valueStartInStyleSheet;
11494576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            // Need to exclude the trailing ';' from the property value.
11504576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            currentData->value = styleSheetText.substring(valueStartInStyleSheet, propertyEndInStyleSheet - valueStartInStyleSheet + (characters[propertyEndInStyleSheet] == ';' ? 0 : 1));
11514576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        }
1152a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1153a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1154a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
11554576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangvoid InspectorStyleSheet::collectFlatRules(PassRefPtr<CSSRuleList> ruleList, Vector<CSSStyleRule*>* result)
11564576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang{
11574576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    if (!ruleList)
11584576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        return;
11594576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
11604576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    for (unsigned i = 0, size = ruleList->length(); i < size; ++i) {
11614576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        CSSRule* rule = ruleList->item(i);
11624576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        CSSStyleRule* styleRule = InspectorCSSAgent::asCSSStyleRule(rule);
11634576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        if (styleRule)
11644576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            result->append(styleRule);
11654576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        else {
11664576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            RefPtr<CSSRuleList> childRuleList = asCSSRuleList(rule);
11674576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            if (childRuleList)
11684576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang                collectFlatRules(childRuleList, result);
11694576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        }
11704576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    }
11714576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang}
1172a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1173cad810f21b803229eb11403f9209855525a25d57Steve BlockPassRefPtr<InspectorStyleSheetForInlineStyle> InspectorStyleSheetForInlineStyle::create(const String& id, PassRefPtr<Element> element, const String& origin)
1174cad810f21b803229eb11403f9209855525a25d57Steve Block{
1175cad810f21b803229eb11403f9209855525a25d57Steve Block    return adoptRef(new InspectorStyleSheetForInlineStyle(id, element, origin));
1176cad810f21b803229eb11403f9209855525a25d57Steve Block}
1177cad810f21b803229eb11403f9209855525a25d57Steve Block
1178cad810f21b803229eb11403f9209855525a25d57Steve BlockInspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(const String& id, PassRefPtr<Element> element, const String& origin)
1179a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    : InspectorStyleSheet(id, 0, origin, "")
1180a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_element(element)
1181a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_ruleSourceData(0)
1182a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1183cad810f21b803229eb11403f9209855525a25d57Steve Block    ASSERT(m_element);
11844576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    m_inspectorStyle = InspectorStyle::create(InspectorCSSId(id, 0), inlineStyle(), this);
1185cad810f21b803229eb11403f9209855525a25d57Steve Block    m_styleText = m_element->isStyledElement() ? m_element->getAttribute("style").string() : String();
1186cad810f21b803229eb11403f9209855525a25d57Steve Block}
1187cad810f21b803229eb11403f9209855525a25d57Steve Block
1188cad810f21b803229eb11403f9209855525a25d57Steve Blockvoid InspectorStyleSheetForInlineStyle::didModifyElementAttribute()
1189cad810f21b803229eb11403f9209855525a25d57Steve Block{
119081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    String newStyleText = elementStyleText();
1191cad810f21b803229eb11403f9209855525a25d57Steve Block    bool shouldDropSourceData = false;
1192cad810f21b803229eb11403f9209855525a25d57Steve Block    if (m_element->isStyledElement() && m_element->style() != m_inspectorStyle->cssStyle()) {
1193cad810f21b803229eb11403f9209855525a25d57Steve Block        m_inspectorStyle = InspectorStyle::create(InspectorCSSId(id(), 0), inlineStyle(), this);
1194cad810f21b803229eb11403f9209855525a25d57Steve Block        shouldDropSourceData = true;
1195cad810f21b803229eb11403f9209855525a25d57Steve Block    }
1196cad810f21b803229eb11403f9209855525a25d57Steve Block    if (newStyleText != m_styleText) {
1197cad810f21b803229eb11403f9209855525a25d57Steve Block        m_styleText = newStyleText;
1198cad810f21b803229eb11403f9209855525a25d57Steve Block        shouldDropSourceData = true;
1199cad810f21b803229eb11403f9209855525a25d57Steve Block    }
1200cad810f21b803229eb11403f9209855525a25d57Steve Block    if (shouldDropSourceData)
1201cad810f21b803229eb11403f9209855525a25d57Steve Block        m_ruleSourceData.clear();
12024576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang}
12034576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
12044576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangbool InspectorStyleSheetForInlineStyle::text(String* result) const
12054576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang{
1206cad810f21b803229eb11403f9209855525a25d57Steve Block    *result = m_styleText;
12074576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    return true;
1208a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1209a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1210e14391e94c850b8bd03680c23b38978db68687a8John Reckbool InspectorStyleSheetForInlineStyle::setStyleText(CSSStyleDeclaration* style, const String& text)
1211a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1212e14391e94c850b8bd03680c23b38978db68687a8John Reck    ASSERT_UNUSED(style, style == inlineStyle());
1213a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ExceptionCode ec = 0;
1214a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_element->setAttribute("style", text, ec);
1215cad810f21b803229eb11403f9209855525a25d57Steve Block    m_styleText = text;
1216a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_ruleSourceData.clear();
1217a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return !ec;
1218a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1219a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1220a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochDocument* InspectorStyleSheetForInlineStyle::ownerDocument() const
1221a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1222a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return m_element->document();
1223a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1224a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1225a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochbool InspectorStyleSheetForInlineStyle::ensureParsedDataReady()
1226a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
122781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // The "style" property value can get changed indirectly, e.g. via element.style.borderWidth = "2px".
122881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const String& currentStyleText = elementStyleText();
122981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_styleText != currentStyleText) {
123081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_ruleSourceData.clear();
123181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_styleText = currentStyleText;
123281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
123381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1234a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (m_ruleSourceData)
1235a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return true;
1236a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1237a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_ruleSourceData = CSSRuleSourceData::create();
1238a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<CSSStyleSourceData> sourceData = CSSStyleSourceData::create();
1239a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool success = getStyleAttributeRanges(&sourceData);
1240a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!success)
1241a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
1242a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1243a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_ruleSourceData->styleSourceData = sourceData.release();
1244a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return true;
1245a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1246a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1247e14391e94c850b8bd03680c23b38978db68687a8John ReckPassRefPtr<InspectorStyle> InspectorStyleSheetForInlineStyle::inspectorStyleForId(const InspectorCSSId& id)
1248e14391e94c850b8bd03680c23b38978db68687a8John Reck{
12494576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    ASSERT_UNUSED(id, !id.ordinal());
1250e14391e94c850b8bd03680c23b38978db68687a8John Reck    return m_inspectorStyle;
1251e14391e94c850b8bd03680c23b38978db68687a8John Reck}
1252e14391e94c850b8bd03680c23b38978db68687a8John Reck
1253a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochCSSStyleDeclaration* InspectorStyleSheetForInlineStyle::inlineStyle() const
1254a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1255a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return m_element->style();
1256a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1257a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
125881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochconst String& InspectorStyleSheetForInlineStyle::elementStyleText() const
125981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
126081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return m_element->getAttribute("style").string();
126181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
126281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1263a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochbool InspectorStyleSheetForInlineStyle::getStyleAttributeRanges(RefPtr<CSSStyleSourceData>* result)
1264a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1265a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!m_element->isStyledElement())
1266a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return false;
1267a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1268cad810f21b803229eb11403f9209855525a25d57Steve Block    if (m_styleText.isEmpty()) {
1269a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        (*result)->styleBodyRange.start = 0;
1270a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        (*result)->styleBodyRange.end = 0;
1271a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return true;
1272a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1273a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1274a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<CSSMutableStyleDeclaration> tempDeclaration = CSSMutableStyleDeclaration::create();
1275a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    CSSParser p;
1276cad810f21b803229eb11403f9209855525a25d57Steve Block    p.parseDeclaration(tempDeclaration.get(), m_styleText, result);
1277a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return true;
1278a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1279a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1280a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} // namespace WebCore
1281a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1282a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#endif // ENABLE(INSPECTOR)
1283