OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010, Google Inc. All rights reserved. | 2 * Copyright (C) 2010, Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 #include "core/inspector/InspectorPageAgent.h" | 50 #include "core/inspector/InspectorPageAgent.h" |
51 #include "core/inspector/InspectorResourceAgent.h" | 51 #include "core/inspector/InspectorResourceAgent.h" |
52 #include "wtf/OwnPtr.h" | 52 #include "wtf/OwnPtr.h" |
53 #include "wtf/PassOwnPtr.h" | 53 #include "wtf/PassOwnPtr.h" |
54 #include "wtf/text/StringBuilder.h" | 54 #include "wtf/text/StringBuilder.h" |
55 #include "wtf/text/TextPosition.h" | 55 #include "wtf/text/TextPosition.h" |
56 | 56 |
57 using WebCore::TypeBuilder::Array; | 57 using WebCore::TypeBuilder::Array; |
58 using WebCore::RuleSourceDataList; | 58 using WebCore::RuleSourceDataList; |
59 using WebCore::CSSRuleSourceData; | 59 using WebCore::CSSRuleSourceData; |
| 60 using WebCore::CSSStyleSheet; |
60 | 61 |
61 class ParsedStyleSheet { | 62 static PassOwnPtr<WebCore::BisonCSSParser> createCSSParser(WebCore::Document* do
cument) |
62 WTF_MAKE_FAST_ALLOCATED; | |
63 public: | |
64 ParsedStyleSheet(); | |
65 | |
66 const String& text() const { ASSERT(m_hasText); return m_text; } | |
67 void setText(const String& text); | |
68 bool hasText() const { return m_hasText; } | |
69 void setSourceData(PassOwnPtr<RuleSourceDataList>); | |
70 bool hasSourceData() const { return m_sourceData; } | |
71 PassRefPtr<WebCore::CSSRuleSourceData> ruleSourceDataAt(unsigned) const; | |
72 | |
73 private: | |
74 void flattenSourceData(RuleSourceDataList*); | |
75 | |
76 String m_text; | |
77 bool m_hasText; | |
78 OwnPtr<RuleSourceDataList> m_sourceData; | |
79 }; | |
80 | |
81 ParsedStyleSheet::ParsedStyleSheet() | |
82 : m_hasText(false) | |
83 { | 63 { |
84 } | 64 return adoptPtr(new WebCore::BisonCSSParser(document ? WebCore::CSSParserCon
text(*document, 0) : WebCore::strictCSSParserContext())); |
85 | |
86 void ParsedStyleSheet::setText(const String& text) | |
87 { | |
88 m_hasText = true; | |
89 m_text = text; | |
90 setSourceData(nullptr); | |
91 } | |
92 | |
93 void ParsedStyleSheet::flattenSourceData(RuleSourceDataList* dataList) | |
94 { | |
95 for (size_t i = 0; i < dataList->size(); ++i) { | |
96 RefPtr<CSSRuleSourceData>& data = dataList->at(i); | |
97 if (data->type == CSSRuleSourceData::STYLE_RULE) { | |
98 m_sourceData->append(data); | |
99 } else if (data->type == CSSRuleSourceData::IMPORT_RULE) { | |
100 m_sourceData->append(data); | |
101 } else if (data->type == CSSRuleSourceData::MEDIA_RULE) { | |
102 m_sourceData->append(data); | |
103 flattenSourceData(&data->childRules); | |
104 } else if (data->type == CSSRuleSourceData::SUPPORTS_RULE) { | |
105 flattenSourceData(&data->childRules); | |
106 } | |
107 } | |
108 } | |
109 | |
110 void ParsedStyleSheet::setSourceData(PassOwnPtr<RuleSourceDataList> sourceData) | |
111 { | |
112 if (!sourceData) { | |
113 m_sourceData.clear(); | |
114 return; | |
115 } | |
116 | |
117 m_sourceData = adoptPtr(new RuleSourceDataList()); | |
118 | |
119 // FIXME: This is a temporary solution to retain the original flat sourceDat
a structure | |
120 // containing only style rules, even though BisonCSSParser now provides the
full rule source data tree. | |
121 // Normally, we should just assign m_sourceData = sourceData; | |
122 flattenSourceData(sourceData.get()); | |
123 } | |
124 | |
125 PassRefPtr<WebCore::CSSRuleSourceData> ParsedStyleSheet::ruleSourceDataAt(unsign
ed index) const | |
126 { | |
127 if (!hasSourceData() || index >= m_sourceData->size()) | |
128 return nullptr; | |
129 | |
130 return m_sourceData->at(index); | |
131 } | |
132 | |
133 namespace WebCore { | |
134 | |
135 static PassOwnPtr<BisonCSSParser> createCSSParser(Document* document) | |
136 { | |
137 return adoptPtr(new BisonCSSParser(document ? CSSParserContext(*document, 0)
: strictCSSParserContext())); | |
138 } | 65 } |
139 | 66 |
140 namespace { | 67 namespace { |
141 | 68 |
| 69 using namespace WebCore; |
| 70 |
142 class StyleSheetHandler FINAL : public CSSParserObserver { | 71 class StyleSheetHandler FINAL : public CSSParserObserver { |
143 public: | 72 public: |
144 StyleSheetHandler(const String& parsedText, Document* document, StyleSheetCo
ntents* styleSheetContents, RuleSourceDataList* result) | 73 StyleSheetHandler(const String& parsedText, Document* document, StyleSheetCo
ntents* styleSheetContents, RuleSourceDataList* result) |
145 : m_parsedText(parsedText) | 74 : m_parsedText(parsedText) |
146 , m_document(document) | 75 , m_document(document) |
147 , m_styleSheetContents(styleSheetContents) | 76 , m_styleSheetContents(styleSheetContents) |
148 , m_result(result) | 77 , m_result(result) |
149 , m_propertyRangeStart(UINT_MAX) | 78 , m_propertyRangeStart(UINT_MAX) |
150 , m_selectorRangeStart(UINT_MAX) | 79 , m_selectorRangeStart(UINT_MAX) |
151 , m_commentRangeStart(UINT_MAX) | 80 , m_commentRangeStart(UINT_MAX) |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 if (propertyData.range.length() != commentText.length()) | 349 if (propertyData.range.length() != commentText.length()) |
421 return; | 350 return; |
422 | 351 |
423 unsigned topRuleBodyRangeStart = m_currentRuleDataStack.last()->ruleBodyRang
e.start; | 352 unsigned topRuleBodyRangeStart = m_currentRuleDataStack.last()->ruleBodyRang
e.start; |
424 m_currentRuleDataStack.last()->styleSourceData->propertyData.append( | 353 m_currentRuleDataStack.last()->styleSourceData->propertyData.append( |
425 CSSPropertySourceData(propertyData.name, propertyData.value, false, true
, true, SourceRange(startOffset - topRuleBodyRangeStart, offset - topRuleBodyRan
geStart))); | 354 CSSPropertySourceData(propertyData.name, propertyData.value, false, true
, true, SourceRange(startOffset - topRuleBodyRangeStart, offset - topRuleBodyRan
geStart))); |
426 } | 355 } |
427 | 356 |
428 } // namespace | 357 } // namespace |
429 | 358 |
| 359 class ParsedStyleSheet { |
| 360 WTF_MAKE_FAST_ALLOCATED; |
| 361 public: |
| 362 ParsedStyleSheet(CSSStyleSheet* pageStyleSheet); |
| 363 |
| 364 const String& text() const { ASSERT(m_hasText); return m_text; } |
| 365 void setText(const String&); |
| 366 bool hasText() const { return m_hasText; } |
| 367 bool ensureSourceData(); |
| 368 bool hasSourceData() const { return m_sourceData; } |
| 369 PassRefPtr<WebCore::CSSRuleSourceData> ruleSourceDataAt(unsigned) const; |
| 370 |
| 371 private: |
| 372 void flattenSourceData(RuleSourceDataList*); |
| 373 void setSourceData(PassOwnPtr<RuleSourceDataList>); |
| 374 |
| 375 String m_text; |
| 376 bool m_hasText; |
| 377 OwnPtr<RuleSourceDataList> m_sourceData; |
| 378 RefPtr<CSSStyleSheet> m_pageStyleSheet; |
| 379 }; |
| 380 |
| 381 ParsedStyleSheet::ParsedStyleSheet(CSSStyleSheet* pageStyleSheet) |
| 382 : m_hasText(false) |
| 383 , m_pageStyleSheet(pageStyleSheet) |
| 384 { |
| 385 } |
| 386 |
| 387 void ParsedStyleSheet::setText(const String& text) |
| 388 { |
| 389 m_hasText = true; |
| 390 m_text = text; |
| 391 setSourceData(nullptr); |
| 392 } |
| 393 |
| 394 void ParsedStyleSheet::flattenSourceData(RuleSourceDataList* dataList) |
| 395 { |
| 396 for (size_t i = 0; i < dataList->size(); ++i) { |
| 397 RefPtr<CSSRuleSourceData>& data = dataList->at(i); |
| 398 if (data->type == CSSRuleSourceData::STYLE_RULE) { |
| 399 m_sourceData->append(data); |
| 400 } else if (data->type == CSSRuleSourceData::IMPORT_RULE) { |
| 401 m_sourceData->append(data); |
| 402 } else if (data->type == CSSRuleSourceData::MEDIA_RULE) { |
| 403 m_sourceData->append(data); |
| 404 flattenSourceData(&data->childRules); |
| 405 } else if (data->type == CSSRuleSourceData::SUPPORTS_RULE) { |
| 406 flattenSourceData(&data->childRules); |
| 407 } |
| 408 } |
| 409 } |
| 410 |
| 411 bool ParsedStyleSheet::ensureSourceData() |
| 412 { |
| 413 if (hasSourceData()) |
| 414 return true; |
| 415 |
| 416 if (!hasText()) |
| 417 return false; |
| 418 |
| 419 RefPtrWillBeRawPtr<StyleSheetContents> newStyleSheet = StyleSheetContents::c
reate(strictCSSParserContext()); |
| 420 OwnPtr<RuleSourceDataList> result = adoptPtr(new RuleSourceDataList()); |
| 421 StyleSheetHandler handler(text(), m_pageStyleSheet->ownerDocument(), newStyl
eSheet.get(), result.get()); |
| 422 createCSSParser(m_pageStyleSheet->ownerDocument())->parseSheet(newStyleSheet
.get(), text(), TextPosition::minimumPosition(), &handler); |
| 423 setSourceData(result.release()); |
| 424 return hasSourceData(); |
| 425 } |
| 426 |
| 427 void ParsedStyleSheet::setSourceData(PassOwnPtr<RuleSourceDataList> sourceData) |
| 428 { |
| 429 if (!sourceData) { |
| 430 m_sourceData.clear(); |
| 431 return; |
| 432 } |
| 433 |
| 434 m_sourceData = adoptPtr(new RuleSourceDataList()); |
| 435 |
| 436 // FIXME: This is a temporary solution to retain the original flat sourceDat
a structure |
| 437 // containing only style rules, even though BisonCSSParser now provides the
full rule source data tree. |
| 438 // Normally, we should just assign m_sourceData = sourceData; |
| 439 flattenSourceData(sourceData.get()); |
| 440 } |
| 441 |
| 442 PassRefPtr<WebCore::CSSRuleSourceData> ParsedStyleSheet::ruleSourceDataAt(unsign
ed index) const |
| 443 { |
| 444 if (!hasSourceData() || index >= m_sourceData->size()) |
| 445 return nullptr; |
| 446 |
| 447 return m_sourceData->at(index); |
| 448 } |
| 449 |
| 450 namespace WebCore { |
| 451 |
430 enum MediaListSource { | 452 enum MediaListSource { |
431 MediaListSourceLinkedSheet, | 453 MediaListSourceLinkedSheet, |
432 MediaListSourceInlineSheet, | 454 MediaListSourceInlineSheet, |
433 MediaListSourceMediaRule, | 455 MediaListSourceMediaRule, |
434 MediaListSourceImportRule | 456 MediaListSourceImportRule |
435 }; | 457 }; |
436 | 458 |
437 static PassRefPtr<TypeBuilder::CSS::SourceRange> buildSourceRangeObject(const So
urceRange& range, Vector<unsigned>* lineEndings) | 459 static PassRefPtr<TypeBuilder::CSS::SourceRange> buildSourceRangeObject(const So
urceRange& range, Vector<unsigned>* lineEndings) |
438 { | 460 { |
439 if (!lineEndings) | 461 if (!lineEndings) |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
884 InspectorStyleSheet::InspectorStyleSheet(InspectorPageAgent* pageAgent, Inspecto
rResourceAgent* resourceAgent, const String& id, PassRefPtr<CSSStyleSheet> pageS
tyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum origin, const String& docume
ntURL, Listener* listener) | 906 InspectorStyleSheet::InspectorStyleSheet(InspectorPageAgent* pageAgent, Inspecto
rResourceAgent* resourceAgent, const String& id, PassRefPtr<CSSStyleSheet> pageS
tyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum origin, const String& docume
ntURL, Listener* listener) |
885 : m_pageAgent(pageAgent) | 907 : m_pageAgent(pageAgent) |
886 , m_resourceAgent(resourceAgent) | 908 , m_resourceAgent(resourceAgent) |
887 , m_id(id) | 909 , m_id(id) |
888 , m_pageStyleSheet(pageStyleSheet) | 910 , m_pageStyleSheet(pageStyleSheet) |
889 , m_origin(origin) | 911 , m_origin(origin) |
890 , m_documentURL(documentURL) | 912 , m_documentURL(documentURL) |
891 , m_isRevalidating(false) | 913 , m_isRevalidating(false) |
892 , m_listener(listener) | 914 , m_listener(listener) |
893 { | 915 { |
894 m_parsedStyleSheet = new ParsedStyleSheet(); | 916 m_parsedStyleSheet = new ParsedStyleSheet(m_pageStyleSheet.get()); |
895 } | 917 } |
896 | 918 |
897 InspectorStyleSheet::~InspectorStyleSheet() | 919 InspectorStyleSheet::~InspectorStyleSheet() |
898 { | 920 { |
899 delete m_parsedStyleSheet; | 921 delete m_parsedStyleSheet; |
900 } | 922 } |
901 | 923 |
902 String InspectorStyleSheet::finalURL() const | 924 String InspectorStyleSheet::finalURL() const |
903 { | 925 { |
904 String url = styleSheetURL(m_pageStyleSheet.get()); | 926 String url = styleSheetURL(m_pageStyleSheet.get()); |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1412 { | 1434 { |
1413 if (!m_pageStyleSheet) { | 1435 if (!m_pageStyleSheet) { |
1414 exceptionState.throwDOMException(NotSupportedError, "No stylesheet is av
ailable."); | 1436 exceptionState.throwDOMException(NotSupportedError, "No stylesheet is av
ailable."); |
1415 return false; | 1437 return false; |
1416 } | 1438 } |
1417 return true; | 1439 return true; |
1418 } | 1440 } |
1419 | 1441 |
1420 bool InspectorStyleSheet::ensureParsedDataReady() | 1442 bool InspectorStyleSheet::ensureParsedDataReady() |
1421 { | 1443 { |
1422 return ensureText() && ensureSourceData(); | 1444 return ensureText() && m_parsedStyleSheet->ensureSourceData(); |
1423 } | 1445 } |
1424 | 1446 |
1425 bool InspectorStyleSheet::ensureText() const | 1447 bool InspectorStyleSheet::ensureText() const |
1426 { | 1448 { |
1427 if (!m_parsedStyleSheet) | 1449 if (!m_parsedStyleSheet) |
1428 return false; | 1450 return false; |
1429 if (m_parsedStyleSheet->hasText()) | 1451 if (m_parsedStyleSheet->hasText()) |
1430 return true; | 1452 return true; |
1431 | 1453 |
1432 String text; | 1454 String text; |
1433 bool success = originalStyleSheetText(&text); | 1455 bool success = originalStyleSheetText(&text); |
1434 if (success) | 1456 if (success) |
1435 m_parsedStyleSheet->setText(text); | 1457 m_parsedStyleSheet->setText(text); |
1436 // No need to clear m_flatRules here - it's empty. | 1458 // No need to clear m_flatRules here - it's empty. |
1437 | 1459 |
1438 return success; | 1460 return success; |
1439 } | 1461 } |
1440 | 1462 |
1441 bool InspectorStyleSheet::ensureSourceData() | |
1442 { | |
1443 if (m_parsedStyleSheet->hasSourceData()) | |
1444 return true; | |
1445 | |
1446 if (!m_parsedStyleSheet->hasText()) | |
1447 return false; | |
1448 | |
1449 RefPtrWillBeRawPtr<StyleSheetContents> newStyleSheet = StyleSheetContents::c
reate(strictCSSParserContext()); | |
1450 OwnPtr<RuleSourceDataList> result = adoptPtr(new RuleSourceDataList()); | |
1451 StyleSheetHandler handler(m_parsedStyleSheet->text(), m_pageStyleSheet->owne
rDocument(), newStyleSheet.get(), result.get()); | |
1452 createCSSParser(m_pageStyleSheet->ownerDocument())->parseSheet(newStyleSheet
.get(), m_parsedStyleSheet->text(), TextPosition::minimumPosition(), &handler); | |
1453 m_parsedStyleSheet->setSourceData(result.release()); | |
1454 return m_parsedStyleSheet->hasSourceData(); | |
1455 } | |
1456 | |
1457 void InspectorStyleSheet::ensureFlatRules() const | 1463 void InspectorStyleSheet::ensureFlatRules() const |
1458 { | 1464 { |
1459 // We are fine with redoing this for empty stylesheets as this will run fast
. | 1465 // We are fine with redoing this for empty stylesheets as this will run fast
. |
1460 if (m_flatRules.isEmpty()) | 1466 if (m_flatRules.isEmpty()) |
1461 collectFlatRules(asCSSRuleList(pageStyleSheet()), &m_flatRules); | 1467 collectFlatRules(asCSSRuleList(pageStyleSheet()), &m_flatRules); |
1462 } | 1468 } |
1463 | 1469 |
1464 bool InspectorStyleSheet::setStyleText(CSSStyleDeclaration* style, const String&
text) | 1470 bool InspectorStyleSheet::setStyleText(CSSStyleDeclaration* style, const String&
text) |
1465 { | 1471 { |
1466 if (!m_pageStyleSheet) | 1472 if (!m_pageStyleSheet) |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1693 | 1699 |
1694 RefPtr<MutableStylePropertySet> tempDeclaration = MutableStylePropertySet::c
reate(); | 1700 RefPtr<MutableStylePropertySet> tempDeclaration = MutableStylePropertySet::c
reate(); |
1695 RuleSourceDataList ruleSourceDataResult; | 1701 RuleSourceDataList ruleSourceDataResult; |
1696 StyleSheetHandler handler(m_styleText, &m_element->document(), m_element->do
cument().elementSheet().contents(), &ruleSourceDataResult); | 1702 StyleSheetHandler handler(m_styleText, &m_element->document(), m_element->do
cument().elementSheet().contents(), &ruleSourceDataResult); |
1697 createCSSParser(&m_element->document())->parseDeclaration(tempDeclaration.ge
t(), m_styleText, &handler, m_element->document().elementSheet().contents()); | 1703 createCSSParser(&m_element->document())->parseDeclaration(tempDeclaration.ge
t(), m_styleText, &handler, m_element->document().elementSheet().contents()); |
1698 return ruleSourceDataResult.first().release(); | 1704 return ruleSourceDataResult.first().release(); |
1699 } | 1705 } |
1700 | 1706 |
1701 } // namespace WebCore | 1707 } // namespace WebCore |
1702 | 1708 |
OLD | NEW |