OLD | NEW |
1 /* | 1 /* |
2 * (C) 1999-2003 Lars Knoll (knoll@kde.org) | 2 * (C) 1999-2003 Lars Knoll (knoll@kde.org) |
3 * Copyright (C) 2004, 2006, 2007, 2012 Apple Inc. All rights reserved. | 3 * Copyright (C) 2004, 2006, 2007, 2012 Apple Inc. All rights reserved. |
4 * | 4 * |
5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
9 * | 9 * |
10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 for (unsigned i = 0; i < m_importRules.size(); ++i) { | 52 for (unsigned i = 0; i < m_importRules.size(); ++i) { |
53 if (StyleSheetContents* sheet = m_importRules[i]->styleSheet()) | 53 if (StyleSheetContents* sheet = m_importRules[i]->styleSheet()) |
54 size += sheet->estimatedSizeInBytes(); | 54 size += sheet->estimatedSizeInBytes(); |
55 } | 55 } |
56 return size; | 56 return size; |
57 } | 57 } |
58 | 58 |
59 StyleSheetContents::StyleSheetContents(StyleRuleImport* ownerRule, const String&
originalURL, const CSSParserContext& context) | 59 StyleSheetContents::StyleSheetContents(StyleRuleImport* ownerRule, const String&
originalURL, const CSSParserContext& context) |
60 : m_ownerRule(ownerRule) | 60 : m_ownerRule(ownerRule) |
61 , m_originalURL(originalURL) | 61 , m_originalURL(originalURL) |
62 , m_loadCompleted(false) | |
63 , m_hasSyntacticallyValidCSSHeader(true) | 62 , m_hasSyntacticallyValidCSSHeader(true) |
64 , m_didLoadErrorOccur(false) | 63 , m_didLoadErrorOccur(false) |
65 , m_usesRemUnits(false) | 64 , m_usesRemUnits(false) |
66 , m_isMutable(false) | 65 , m_isMutable(false) |
67 , m_isInMemoryCache(false) | 66 , m_isInMemoryCache(false) |
68 , m_hasFontFaceRule(false) | 67 , m_hasFontFaceRule(false) |
69 , m_hasMediaQueries(false) | 68 , m_hasMediaQueries(false) |
70 , m_parserContext(context) | 69 , m_parserContext(context) |
71 { | 70 { |
72 } | 71 } |
73 | 72 |
74 StyleSheetContents::StyleSheetContents(const StyleSheetContents& o) | 73 StyleSheetContents::StyleSheetContents(const StyleSheetContents& o) |
75 : RefCounted<StyleSheetContents>() | 74 : RefCounted<StyleSheetContents>() |
76 , m_ownerRule(0) | 75 , m_ownerRule(0) |
77 , m_originalURL(o.m_originalURL) | 76 , m_originalURL(o.m_originalURL) |
78 , m_encodingFromCharsetRule(o.m_encodingFromCharsetRule) | 77 , m_encodingFromCharsetRule(o.m_encodingFromCharsetRule) |
79 , m_importRules(o.m_importRules.size()) | 78 , m_importRules(o.m_importRules.size()) |
80 , m_childRules(o.m_childRules.size()) | 79 , m_childRules(o.m_childRules.size()) |
81 , m_namespaces(o.m_namespaces) | 80 , m_namespaces(o.m_namespaces) |
82 , m_loadCompleted(true) | |
83 , m_hasSyntacticallyValidCSSHeader(o.m_hasSyntacticallyValidCSSHeader) | 81 , m_hasSyntacticallyValidCSSHeader(o.m_hasSyntacticallyValidCSSHeader) |
84 , m_didLoadErrorOccur(false) | 82 , m_didLoadErrorOccur(false) |
85 , m_usesRemUnits(o.m_usesRemUnits) | 83 , m_usesRemUnits(o.m_usesRemUnits) |
86 , m_isMutable(false) | 84 , m_isMutable(false) |
87 , m_isInMemoryCache(false) | 85 , m_isInMemoryCache(false) |
88 , m_hasFontFaceRule(o.m_hasFontFaceRule) | 86 , m_hasFontFaceRule(o.m_hasFontFaceRule) |
89 , m_hasMediaQueries(o.m_hasMediaQueries) | 87 , m_hasMediaQueries(o.m_hasMediaQueries) |
90 , m_parserContext(o.m_parserContext) | 88 , m_parserContext(o.m_parserContext) |
91 { | 89 { |
92 ASSERT(o.isCacheable()); | 90 ASSERT(o.isCacheable()); |
93 | 91 |
94 // FIXME: Copy import rules. | 92 // FIXME: Copy import rules. |
95 ASSERT(o.m_importRules.isEmpty()); | 93 ASSERT(o.m_importRules.isEmpty()); |
96 | 94 |
97 for (unsigned i = 0; i < m_childRules.size(); ++i) | 95 for (unsigned i = 0; i < m_childRules.size(); ++i) |
98 m_childRules[i] = o.m_childRules[i]->copy(); | 96 m_childRules[i] = o.m_childRules[i]->copy(); |
99 } | 97 } |
100 | 98 |
101 StyleSheetContents::~StyleSheetContents() | 99 StyleSheetContents::~StyleSheetContents() |
102 { | 100 { |
| 101 StyleEngine::removeSheet(this); |
103 clearRules(); | 102 clearRules(); |
104 } | 103 } |
105 | 104 |
106 bool StyleSheetContents::isCacheable() const | 105 void StyleSheetContents::setHasSyntacticallyValidCSSHeader(bool isValidCss) |
| 106 { |
| 107 if (maybeCacheable() && !isValidCss) |
| 108 StyleEngine::removeSheet(this); |
| 109 m_hasSyntacticallyValidCSSHeader = isValidCss; |
| 110 } |
| 111 |
| 112 bool StyleSheetContents::maybeCacheable() const |
107 { | 113 { |
108 // FIXME: StyleSheets with media queries can't be cached because their RuleS
et | 114 // FIXME: StyleSheets with media queries can't be cached because their RuleS
et |
109 // is processed differently based off the media queries, which might resolve | 115 // is processed differently based off the media queries, which might resolve |
110 // differently depending on the context of the parent CSSStyleSheet (e.g. | 116 // differently depending on the context of the parent CSSStyleSheet (e.g. |
111 // if they are in differently sized iframes). Once RuleSets are media query | 117 // if they are in differently sized iframes). Once RuleSets are media query |
112 // agnostic, we can restore sharing of StyleSheetContents with medea queries
. | 118 // agnostic, we can restore sharing of StyleSheetContents with medea queries
. |
113 if (m_hasMediaQueries) | 119 if (m_hasMediaQueries) |
114 return false; | 120 return false; |
115 // FIXME: Support copying import rules. | 121 // FIXME: Support copying import rules. |
116 if (!m_importRules.isEmpty()) | 122 if (!m_importRules.isEmpty()) |
117 return false; | 123 return false; |
118 // FIXME: Support cached stylesheets in import rules. | 124 // FIXME: Support cached stylesheets in import rules. |
119 if (m_ownerRule) | 125 if (m_ownerRule) |
120 return false; | 126 return false; |
121 // This would require dealing with multiple clients for load callbacks. | |
122 if (!m_loadCompleted) | |
123 return false; | |
124 if (m_didLoadErrorOccur) | 127 if (m_didLoadErrorOccur) |
125 return false; | 128 return false; |
126 // It is not the original sheet anymore. | 129 // It is not the original sheet anymore. |
127 if (m_isMutable) | 130 if (m_isMutable) |
128 return false; | 131 return false; |
129 // If the header is valid we are not going to need to check the SecurityOrig
in. | 132 // If the header is valid we are not going to need to check the SecurityOrig
in. |
130 // FIXME: Valid mime type avoids the check too. | 133 // FIXME: Valid mime type avoids the check too. |
131 if (!m_hasSyntacticallyValidCSSHeader) | 134 if (!m_hasSyntacticallyValidCSSHeader) |
132 return false; | 135 return false; |
133 return true; | 136 return true; |
134 } | 137 } |
135 | 138 |
| 139 bool StyleSheetContents::isCacheable() const |
| 140 { |
| 141 // This would require dealing with multiple clients for load callbacks. |
| 142 if (!loadCompleted()) |
| 143 return false; |
| 144 return maybeCacheable(); |
| 145 } |
| 146 |
136 void StyleSheetContents::parserAppendRule(PassRefPtr<StyleRuleBase> rule) | 147 void StyleSheetContents::parserAppendRule(PassRefPtr<StyleRuleBase> rule) |
137 { | 148 { |
138 ASSERT(!rule->isCharsetRule()); | 149 ASSERT(!rule->isCharsetRule()); |
139 if (rule->isImportRule()) { | 150 if (rule->isImportRule()) { |
140 // Parser enforces that @import rules come before anything else except @
charset. | 151 // Parser enforces that @import rules come before anything else except @
charset. |
141 ASSERT(m_childRules.isEmpty()); | 152 ASSERT(m_childRules.isEmpty()); |
142 StyleRuleImport* importRule = toStyleRuleImport(rule.get()); | 153 StyleRuleImport* importRule = toStyleRuleImport(rule.get()); |
143 if (importRule->mediaQueries()) | 154 if (importRule->mediaQueries()) |
144 setHasMediaQueries(); | 155 setHasMediaQueries(); |
145 m_importRules.append(importRule); | 156 m_importRules.append(importRule); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 | 351 |
341 bool StyleSheetContents::isLoading() const | 352 bool StyleSheetContents::isLoading() const |
342 { | 353 { |
343 for (unsigned i = 0; i < m_importRules.size(); ++i) { | 354 for (unsigned i = 0; i < m_importRules.size(); ++i) { |
344 if (m_importRules[i]->isLoading()) | 355 if (m_importRules[i]->isLoading()) |
345 return true; | 356 return true; |
346 } | 357 } |
347 return false; | 358 return false; |
348 } | 359 } |
349 | 360 |
| 361 bool StyleSheetContents::loadCompleted() const |
| 362 { |
| 363 StyleSheetContents* parentSheet = parentStyleSheet(); |
| 364 if (parentSheet) |
| 365 return parentSheet->loadCompleted(); |
| 366 |
| 367 StyleSheetContents* root = rootStyleSheet(); |
| 368 for (unsigned i = 0; i < root->m_clients.size(); ++i) { |
| 369 if (!root->m_clients[i]->loadCompleted()) |
| 370 return false; |
| 371 } |
| 372 return true; |
| 373 } |
| 374 |
350 void StyleSheetContents::checkLoaded() | 375 void StyleSheetContents::checkLoaded() |
351 { | 376 { |
352 if (isLoading()) | 377 if (isLoading()) |
353 return; | 378 return; |
354 | 379 |
355 // Avoid |this| being deleted by scripts that run via | 380 // Avoid |this| being deleted by scripts that run via |
356 // ScriptableDocumentParser::executeScriptsWaitingForResources(). | 381 // ScriptableDocumentParser::executeScriptsWaitingForResources(). |
357 // See https://bugs.webkit.org/show_bug.cgi?id=95106 | 382 // See https://bugs.webkit.org/show_bug.cgi?id=95106 |
358 RefPtr<StyleSheetContents> protect(this); | 383 RefPtr<StyleSheetContents> protect(this); |
359 | 384 |
360 StyleSheetContents* parentSheet = parentStyleSheet(); | 385 StyleSheetContents* parentSheet = parentStyleSheet(); |
361 if (parentSheet) { | 386 if (parentSheet) { |
362 parentSheet->checkLoaded(); | 387 parentSheet->checkLoaded(); |
363 m_loadCompleted = true; | |
364 return; | 388 return; |
365 } | 389 } |
366 RefPtr<Node> ownerNode = singleOwnerNode(); | 390 |
367 if (!ownerNode) { | 391 StyleSheetContents* root = rootStyleSheet(); |
368 m_loadCompleted = true; | 392 if (root->m_clients.isEmpty()) |
369 return; | 393 return; |
| 394 |
| 395 Vector<CSSStyleSheet*> clients(root->m_clients); |
| 396 for (unsigned i = 0; i < clients.size(); ++i) { |
| 397 // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that
run via |
| 398 // ScriptableDocumentParser::executeScriptsWaitingForResources(). |
| 399 RefPtr<CSSStyleSheet> protectClient(clients[i]); |
| 400 |
| 401 if (clients[i]->loadCompleted()) |
| 402 continue; |
| 403 |
| 404 RefPtr<Node> ownerNode = clients[i]->ownerNode(); |
| 405 if (clients[i]->sheetLoaded()) |
| 406 ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErro
rOccur); |
370 } | 407 } |
371 m_loadCompleted = ownerNode->sheetLoaded(); | |
372 if (m_loadCompleted) | |
373 ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOcc
ur); | |
374 } | 408 } |
375 | 409 |
376 void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) | 410 void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) |
377 { | 411 { |
378 ASSERT(sheet); | 412 ASSERT(sheet); |
379 m_didLoadErrorOccur |= sheet->errorOccurred(); | 413 m_didLoadErrorOccur |= sheet->errorOccurred(); |
380 // updateLayoutIgnorePendingStyleSheets can cause us to create the RuleSet o
n this | 414 // updateLayoutIgnorePendingStyleSheets can cause us to create the RuleSet o
n this |
381 // sheet before its imports have loaded. So clear the RuleSet when the impor
ts | 415 // sheet before its imports have loaded. So clear the RuleSet when the impor
ts |
382 // load since the import's subrules are flattened into its parent sheet's Ru
leSet. | 416 // load since the import's subrules are flattened into its parent sheet's Ru
leSet. |
383 clearRuleSet(); | 417 clearRuleSet(); |
384 } | 418 } |
385 | 419 |
386 void StyleSheetContents::startLoadingDynamicSheet() | 420 void StyleSheetContents::startLoadingDynamicSheet() |
387 { | 421 { |
388 if (Node* owner = singleOwnerNode()) | 422 StyleSheetContents* root = rootStyleSheet(); |
389 owner->startLoadingDynamicSheet(); | 423 for (unsigned i = 0; i < root->m_clients.size(); ++i) |
| 424 root->m_clients[i]->startLoadingDynamicSheet(); |
390 } | 425 } |
391 | 426 |
392 StyleSheetContents* StyleSheetContents::rootStyleSheet() const | 427 StyleSheetContents* StyleSheetContents::rootStyleSheet() const |
393 { | 428 { |
394 const StyleSheetContents* root = this; | 429 const StyleSheetContents* root = this; |
395 while (root->parentStyleSheet()) | 430 while (root->parentStyleSheet()) |
396 root = root->parentStyleSheet(); | 431 root = root->parentStyleSheet(); |
397 return const_cast<StyleSheetContents*>(root); | 432 return const_cast<StyleSheetContents*>(root); |
398 } | 433 } |
399 | 434 |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 // See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet. | 566 // See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet. |
532 for (size_t i = 0; i < m_clients.size(); ++i) { | 567 for (size_t i = 0; i < m_clients.size(); ++i) { |
533 if (Document* document = m_clients[i]->ownerDocument()) | 568 if (Document* document = m_clients[i]->ownerDocument()) |
534 document->styleEngine()->clearResolver(); | 569 document->styleEngine()->clearResolver(); |
535 } | 570 } |
536 m_ruleSet.clear(); | 571 m_ruleSet.clear(); |
537 } | 572 } |
538 | 573 |
539 | 574 |
540 } | 575 } |
OLD | NEW |