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 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
337 | 348 |
338 bool StyleSheetContents::isLoading() const | 349 bool StyleSheetContents::isLoading() const |
339 { | 350 { |
340 for (unsigned i = 0; i < m_importRules.size(); ++i) { | 351 for (unsigned i = 0; i < m_importRules.size(); ++i) { |
341 if (m_importRules[i]->isLoading()) | 352 if (m_importRules[i]->isLoading()) |
342 return true; | 353 return true; |
343 } | 354 } |
344 return false; | 355 return false; |
345 } | 356 } |
346 | 357 |
358 bool StyleSheetContents::loadCompleted() const | |
359 { | |
360 StyleSheetContents* parentSheet = parentStyleSheet(); | |
361 if (parentSheet) | |
362 return parentSheet->loadCompleted(); | |
363 | |
364 StyleSheetContents* root = rootStyleSheet(); | |
365 for (unsigned i = 0; i < root->m_clients.size(); ++i) { | |
366 if (!m_clients[i]->loadCompleted()) | |
367 return false; | |
368 } | |
369 return true; | |
370 } | |
371 | |
347 void StyleSheetContents::checkLoaded() | 372 void StyleSheetContents::checkLoaded() |
348 { | 373 { |
349 if (isLoading()) | 374 if (isLoading()) |
350 return; | 375 return; |
351 | 376 |
352 // Avoid |this| being deleted by scripts that run via | 377 // Avoid |this| being deleted by scripts that run via |
353 // ScriptableDocumentParser::executeScriptsWaitingForResources(). | 378 // ScriptableDocumentParser::executeScriptsWaitingForResources(). |
354 // See https://bugs.webkit.org/show_bug.cgi?id=95106 | 379 // See https://bugs.webkit.org/show_bug.cgi?id=95106 |
355 RefPtr<StyleSheetContents> protect(this); | 380 RefPtr<StyleSheetContents> protect(this); |
356 | 381 |
357 StyleSheetContents* parentSheet = parentStyleSheet(); | 382 StyleSheetContents* parentSheet = parentStyleSheet(); |
358 if (parentSheet) { | 383 if (parentSheet) { |
359 parentSheet->checkLoaded(); | 384 parentSheet->checkLoaded(); |
360 m_loadCompleted = true; | |
361 return; | 385 return; |
362 } | 386 } |
363 RefPtr<Node> ownerNode = singleOwnerNode(); | 387 |
364 if (!ownerNode) { | 388 StyleSheetContents* root = rootStyleSheet(); |
365 m_loadCompleted = true; | 389 if (root->m_clients.isEmpty()) |
366 return; | 390 return; |
391 | |
392 Vector<CSSStyleSheet*> clients(root->m_clients); | |
393 for (unsigned i = 0; i < clients.size(); ++i) { | |
394 CSSStyleSheet* client = clients[i]; | |
395 if (client->loadCompleted()) | |
396 continue; | |
397 | |
398 RefPtr<Node> ownerNode = client->ownerNode(); | |
399 if (ownerNode->sheetLoaded()) { | |
400 // Need to check whether the client is registered or not after sheet Loaded. | |
401 // Because sheetLoaded() might destroy CSSStyleSheet. | |
esprehn
2014/01/09 10:05:32
How does this happen?
tasak
2014/01/09 11:59:05
This is the same reason above (i.e. "RefPtr<StyleS
| |
402 if (root->m_clients.contains(client)) | |
403 client->completeLoading(); | |
404 ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErro rOccur); | |
405 } | |
367 } | 406 } |
368 m_loadCompleted = ownerNode->sheetLoaded(); | |
369 if (m_loadCompleted) | |
370 ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOcc ur); | |
371 } | 407 } |
372 | 408 |
373 void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) | 409 void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) |
374 { | 410 { |
375 ASSERT(sheet); | 411 ASSERT(sheet); |
376 m_didLoadErrorOccur |= sheet->errorOccurred(); | 412 m_didLoadErrorOccur |= sheet->errorOccurred(); |
377 // updateLayoutIgnorePendingStyleSheets can cause us to create the RuleSet o n this | 413 // updateLayoutIgnorePendingStyleSheets can cause us to create the RuleSet o n this |
378 // sheet before its imports have loaded. So clear the RuleSet when the impor ts | 414 // sheet before its imports have loaded. So clear the RuleSet when the impor ts |
379 // load since the import's subrules are flattened into its parent sheet's Ru leSet. | 415 // load since the import's subrules are flattened into its parent sheet's Ru leSet. |
380 clearRuleSet(); | 416 clearRuleSet(); |
381 } | 417 } |
382 | 418 |
383 void StyleSheetContents::startLoadingDynamicSheet() | 419 void StyleSheetContents::startLoadingDynamicSheet() |
384 { | 420 { |
385 if (Node* owner = singleOwnerNode()) | 421 StyleSheetContents* root = rootStyleSheet(); |
386 owner->startLoadingDynamicSheet(); | 422 for (unsigned i = 0; i < root->m_clients.size(); ++i) |
423 root->m_clients[i]->startLoadingDynamicSheet(); | |
387 } | 424 } |
388 | 425 |
389 StyleSheetContents* StyleSheetContents::rootStyleSheet() const | 426 StyleSheetContents* StyleSheetContents::rootStyleSheet() const |
390 { | 427 { |
391 const StyleSheetContents* root = this; | 428 const StyleSheetContents* root = this; |
392 while (root->parentStyleSheet()) | 429 while (root->parentStyleSheet()) |
393 root = root->parentStyleSheet(); | 430 root = root->parentStyleSheet(); |
394 return const_cast<StyleSheetContents*>(root); | 431 return const_cast<StyleSheetContents*>(root); |
395 } | 432 } |
396 | 433 |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
566 for (unsigned i = 0; i < m_importRules.size(); ++i) { | 603 for (unsigned i = 0; i < m_importRules.size(); ++i) { |
567 if (!m_importRules[i]->styleSheet()) | 604 if (!m_importRules[i]->styleSheet()) |
568 continue; | 605 continue; |
569 m_importRules[i]->styleSheet()->findFontFaceRules(fontFaceRules); | 606 m_importRules[i]->styleSheet()->findFontFaceRules(fontFaceRules); |
570 } | 607 } |
571 | 608 |
572 findFontFaceRulesFromRules(childRules(), fontFaceRules); | 609 findFontFaceRulesFromRules(childRules(), fontFaceRules); |
573 } | 610 } |
574 | 611 |
575 } | 612 } |
OLD | NEW |