| 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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 // It is not the original sheet anymore. | 135 // It is not the original sheet anymore. |
| 136 if (m_isMutable) | 136 if (m_isMutable) |
| 137 return false; | 137 return false; |
| 138 // If the header is valid we are not going to need to check the SecurityOrig
in. | 138 // If the header is valid we are not going to need to check the SecurityOrig
in. |
| 139 // FIXME: Valid mime type avoids the check too. | 139 // FIXME: Valid mime type avoids the check too. |
| 140 if (!m_hasSyntacticallyValidCSSHeader) | 140 if (!m_hasSyntacticallyValidCSSHeader) |
| 141 return false; | 141 return false; |
| 142 return true; | 142 return true; |
| 143 } | 143 } |
| 144 | 144 |
| 145 void StyleSheetContents::parserAppendRule(PassRefPtrWillBeRawPtr<StyleRuleBase>
rule) | 145 void StyleSheetContents::parserAppendRule(RawPtr<StyleRuleBase> rule) |
| 146 { | 146 { |
| 147 if (rule->isImportRule()) { | 147 if (rule->isImportRule()) { |
| 148 // Parser enforces that @import rules come before anything else | 148 // Parser enforces that @import rules come before anything else |
| 149 ASSERT(m_childRules.isEmpty()); | 149 ASSERT(m_childRules.isEmpty()); |
| 150 StyleRuleImport* importRule = toStyleRuleImport(rule.get()); | 150 StyleRuleImport* importRule = toStyleRuleImport(rule.get()); |
| 151 if (importRule->mediaQueries()) | 151 if (importRule->mediaQueries()) |
| 152 setHasMediaQueries(); | 152 setHasMediaQueries(); |
| 153 m_importRules.append(importRule); | 153 m_importRules.append(importRule); |
| 154 m_importRules.last()->setParentStyleSheet(this); | 154 m_importRules.last()->setParentStyleSheet(this); |
| 155 m_importRules.last()->requestStyleSheet(); | 155 m_importRules.last()->requestStyleSheet(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 { | 205 { |
| 206 for (unsigned i = 0; i < m_importRules.size(); ++i) { | 206 for (unsigned i = 0; i < m_importRules.size(); ++i) { |
| 207 ASSERT(m_importRules.at(i)->parentStyleSheet() == this); | 207 ASSERT(m_importRules.at(i)->parentStyleSheet() == this); |
| 208 m_importRules[i]->clearParentStyleSheet(); | 208 m_importRules[i]->clearParentStyleSheet(); |
| 209 } | 209 } |
| 210 m_importRules.clear(); | 210 m_importRules.clear(); |
| 211 m_namespaceRules.clear(); | 211 m_namespaceRules.clear(); |
| 212 m_childRules.clear(); | 212 m_childRules.clear(); |
| 213 } | 213 } |
| 214 | 214 |
| 215 bool StyleSheetContents::wrapperInsertRule(PassRefPtrWillBeRawPtr<StyleRuleBase>
rule, unsigned index) | 215 bool StyleSheetContents::wrapperInsertRule(RawPtr<StyleRuleBase> rule, unsigned
index) |
| 216 { | 216 { |
| 217 ASSERT(m_isMutable); | 217 ASSERT(m_isMutable); |
| 218 ASSERT_WITH_SECURITY_IMPLICATION(index <= ruleCount()); | 218 ASSERT_WITH_SECURITY_IMPLICATION(index <= ruleCount()); |
| 219 | 219 |
| 220 if (index < m_importRules.size() || (index == m_importRules.size() && rule->
isImportRule())) { | 220 if (index < m_importRules.size() || (index == m_importRules.size() && rule->
isImportRule())) { |
| 221 // Inserting non-import rule before @import is not allowed. | 221 // Inserting non-import rule before @import is not allowed. |
| 222 if (!rule->isImportRule()) | 222 if (!rule->isImportRule()) |
| 223 return false; | 223 return false; |
| 224 | 224 |
| 225 StyleRuleImport* importRule = toStyleRuleImport(rule.get()); | 225 StyleRuleImport* importRule = toStyleRuleImport(rule.get()); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 } | 367 } |
| 368 | 368 |
| 369 void StyleSheetContents::checkLoaded() | 369 void StyleSheetContents::checkLoaded() |
| 370 { | 370 { |
| 371 if (isLoading()) | 371 if (isLoading()) |
| 372 return; | 372 return; |
| 373 | 373 |
| 374 // Avoid |this| being deleted by scripts that run via | 374 // Avoid |this| being deleted by scripts that run via |
| 375 // ScriptableDocumentParser::executeScriptsWaitingForResources(). | 375 // ScriptableDocumentParser::executeScriptsWaitingForResources(). |
| 376 // See https://bugs.webkit.org/show_bug.cgi?id=95106 | 376 // See https://bugs.webkit.org/show_bug.cgi?id=95106 |
| 377 RefPtrWillBeRawPtr<StyleSheetContents> protect(this); | 377 RawPtr<StyleSheetContents> protect(this); |
| 378 | 378 |
| 379 StyleSheetContents* parentSheet = parentStyleSheet(); | 379 StyleSheetContents* parentSheet = parentStyleSheet(); |
| 380 if (parentSheet) { | 380 if (parentSheet) { |
| 381 parentSheet->checkLoaded(); | 381 parentSheet->checkLoaded(); |
| 382 return; | 382 return; |
| 383 } | 383 } |
| 384 | 384 |
| 385 ASSERT(this == rootStyleSheet()); | 385 ASSERT(this == rootStyleSheet()); |
| 386 if (m_loadingClients.isEmpty()) | 386 if (m_loadingClients.isEmpty()) |
| 387 return; | 387 return; |
| 388 | 388 |
| 389 // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run
via | 389 // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run
via |
| 390 // ScriptableDocumentParser::executeScriptsWaitingForResources(). Also prote
ct | 390 // ScriptableDocumentParser::executeScriptsWaitingForResources(). Also prote
ct |
| 391 // the |CSSStyleSheet| from being deleted during iteration via the |sheetLoa
ded| | 391 // the |CSSStyleSheet| from being deleted during iteration via the |sheetLoa
ded| |
| 392 // method. | 392 // method. |
| 393 // | 393 // |
| 394 // When a sheet is loaded it is moved from the set of loading clients | 394 // When a sheet is loaded it is moved from the set of loading clients |
| 395 // to the set of completed clients. We therefore need the copy in order to | 395 // to the set of completed clients. We therefore need the copy in order to |
| 396 // not modify the set while iterating it. | 396 // not modify the set while iterating it. |
| 397 WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet>> loadingClients; | 397 HeapVector<Member<CSSStyleSheet>> loadingClients; |
| 398 copyToVector(m_loadingClients, loadingClients); | 398 copyToVector(m_loadingClients, loadingClients); |
| 399 | 399 |
| 400 for (unsigned i = 0; i < loadingClients.size(); ++i) { | 400 for (unsigned i = 0; i < loadingClients.size(); ++i) { |
| 401 if (loadingClients[i]->loadCompleted()) | 401 if (loadingClients[i]->loadCompleted()) |
| 402 continue; | 402 continue; |
| 403 | 403 |
| 404 // sheetLoaded might be invoked after its owner node is removed from doc
ument. | 404 // sheetLoaded might be invoked after its owner node is removed from doc
ument. |
| 405 if (RefPtrWillBeRawPtr<Node> ownerNode = loadingClients[i]->ownerNode())
{ | 405 if (RawPtr<Node> ownerNode = loadingClients[i]->ownerNode()) { |
| 406 if (loadingClients[i]->sheetLoaded()) | 406 if (loadingClients[i]->sheetLoaded()) |
| 407 ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoad
ErrorOccur ? Node::ErrorOccurredLoadingSubresource : Node::NoErrorLoadingSubreso
urce); | 407 ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoad
ErrorOccur ? Node::ErrorOccurredLoadingSubresource : Node::NoErrorLoadingSubreso
urce); |
| 408 } | 408 } |
| 409 } | 409 } |
| 410 } | 410 } |
| 411 | 411 |
| 412 void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) | 412 void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) |
| 413 { | 413 { |
| 414 ASSERT(sheet); | 414 ASSERT(sheet); |
| 415 m_didLoadErrorOccur |= sheet->errorOccurred(); | 415 m_didLoadErrorOccur |= sheet->errorOccurred(); |
| 416 // updateLayoutIgnorePendingStyleSheets can cause us to create the RuleSet o
n this | 416 // updateLayoutIgnorePendingStyleSheets can cause us to create the RuleSet o
n this |
| 417 // sheet before its imports have loaded. So clear the RuleSet when the impor
ts | 417 // sheet before its imports have loaded. So clear the RuleSet when the impor
ts |
| 418 // load since the import's subrules are flattened into its parent sheet's Ru
leSet. | 418 // load since the import's subrules are flattened into its parent sheet's Ru
leSet. |
| 419 clearRuleSet(); | 419 clearRuleSet(); |
| 420 } | 420 } |
| 421 | 421 |
| 422 void StyleSheetContents::startLoadingDynamicSheet() | 422 void StyleSheetContents::startLoadingDynamicSheet() |
| 423 { | 423 { |
| 424 StyleSheetContents* root = rootStyleSheet(); | 424 StyleSheetContents* root = rootStyleSheet(); |
| 425 for (const auto& client : root->m_loadingClients) | 425 for (const auto& client : root->m_loadingClients) |
| 426 client->startLoadingDynamicSheet(); | 426 client->startLoadingDynamicSheet(); |
| 427 // Copy the completed clients to a vector for iteration. | 427 // Copy the completed clients to a vector for iteration. |
| 428 // startLoadingDynamicSheet will move the style sheet from the | 428 // startLoadingDynamicSheet will move the style sheet from the |
| 429 // completed state to the loading state which modifies the set of | 429 // completed state to the loading state which modifies the set of |
| 430 // completed clients. We therefore need the copy in order to not | 430 // completed clients. We therefore need the copy in order to not |
| 431 // modify the set of completed clients while iterating it. | 431 // modify the set of completed clients while iterating it. |
| 432 WillBeHeapVector<RawPtrWillBeMember<CSSStyleSheet>> completedClients; | 432 HeapVector<Member<CSSStyleSheet>> completedClients; |
| 433 copyToVector(root->m_completedClients, completedClients); | 433 copyToVector(root->m_completedClients, completedClients); |
| 434 for (unsigned i = 0; i < completedClients.size(); ++i) | 434 for (unsigned i = 0; i < completedClients.size(); ++i) |
| 435 completedClients[i]->startLoadingDynamicSheet(); | 435 completedClients[i]->startLoadingDynamicSheet(); |
| 436 } | 436 } |
| 437 | 437 |
| 438 StyleSheetContents* StyleSheetContents::rootStyleSheet() const | 438 StyleSheetContents* StyleSheetContents::rootStyleSheet() const |
| 439 { | 439 { |
| 440 const StyleSheetContents* root = this; | 440 const StyleSheetContents* root = this; |
| 441 while (root->parentStyleSheet()) | 441 while (root->parentStyleSheet()) |
| 442 root = root->parentStyleSheet(); | 442 root = root->parentStyleSheet(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 457 return (*root->m_loadingClients.begin())->ownerNode(); | 457 return (*root->m_loadingClients.begin())->ownerNode(); |
| 458 return (*root->m_completedClients.begin())->ownerNode(); | 458 return (*root->m_completedClients.begin())->ownerNode(); |
| 459 } | 459 } |
| 460 | 460 |
| 461 Document* StyleSheetContents::singleOwnerDocument() const | 461 Document* StyleSheetContents::singleOwnerDocument() const |
| 462 { | 462 { |
| 463 StyleSheetContents* root = rootStyleSheet(); | 463 StyleSheetContents* root = rootStyleSheet(); |
| 464 return root->clientSingleOwnerDocument(); | 464 return root->clientSingleOwnerDocument(); |
| 465 } | 465 } |
| 466 | 466 |
| 467 static bool childRulesHaveFailedOrCanceledSubresources(const WillBeHeapVector<Re
fPtrWillBeMember<StyleRuleBase>>& rules) | 467 static bool childRulesHaveFailedOrCanceledSubresources(const HeapVector<Member<S
tyleRuleBase>>& rules) |
| 468 { | 468 { |
| 469 for (unsigned i = 0; i < rules.size(); ++i) { | 469 for (unsigned i = 0; i < rules.size(); ++i) { |
| 470 const StyleRuleBase* rule = rules[i].get(); | 470 const StyleRuleBase* rule = rules[i].get(); |
| 471 switch (rule->type()) { | 471 switch (rule->type()) { |
| 472 case StyleRuleBase::Style: | 472 case StyleRuleBase::Style: |
| 473 if (toStyleRule(rule)->properties().hasFailedOrCanceledSubresources(
)) | 473 if (toStyleRule(rule)->properties().hasFailedOrCanceledSubresources(
)) |
| 474 return true; | 474 return true; |
| 475 break; | 475 break; |
| 476 case StyleRuleBase::FontFace: | 476 case StyleRuleBase::FontFace: |
| 477 if (toStyleRuleFontFace(rule)->properties().hasFailedOrCanceledSubre
sources()) | 477 if (toStyleRuleFontFace(rule)->properties().hasFailedOrCanceledSubre
sources()) |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 | 585 |
| 586 RuleSet& StyleSheetContents::ensureRuleSet(const MediaQueryEvaluator& medium, Ad
dRuleFlags addRuleFlags) | 586 RuleSet& StyleSheetContents::ensureRuleSet(const MediaQueryEvaluator& medium, Ad
dRuleFlags addRuleFlags) |
| 587 { | 587 { |
| 588 if (!m_ruleSet) { | 588 if (!m_ruleSet) { |
| 589 m_ruleSet = RuleSet::create(); | 589 m_ruleSet = RuleSet::create(); |
| 590 m_ruleSet->addRulesFromSheet(this, medium, addRuleFlags); | 590 m_ruleSet->addRulesFromSheet(this, medium, addRuleFlags); |
| 591 } | 591 } |
| 592 return *m_ruleSet.get(); | 592 return *m_ruleSet.get(); |
| 593 } | 593 } |
| 594 | 594 |
| 595 static void clearResolvers(WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleShee
t>>& clients) | 595 static void clearResolvers(HeapHashSet<WeakMember<CSSStyleSheet>>& clients) |
| 596 { | 596 { |
| 597 for (const auto& sheet : clients) { | 597 for (const auto& sheet : clients) { |
| 598 if (Document* document = sheet->ownerDocument()) | 598 if (Document* document = sheet->ownerDocument()) |
| 599 document->styleEngine().clearResolver(); | 599 document->styleEngine().clearResolver(); |
| 600 } | 600 } |
| 601 } | 601 } |
| 602 | 602 |
| 603 void StyleSheetContents::clearRuleSet() | 603 void StyleSheetContents::clearRuleSet() |
| 604 { | 604 { |
| 605 if (StyleSheetContents* parentSheet = parentStyleSheet()) | 605 if (StyleSheetContents* parentSheet = parentStyleSheet()) |
| 606 parentSheet->clearRuleSet(); | 606 parentSheet->clearRuleSet(); |
| 607 | 607 |
| 608 // Don't want to clear the StyleResolver if the RuleSet hasn't been created | 608 // Don't want to clear the StyleResolver if the RuleSet hasn't been created |
| 609 // since we only clear the StyleResolver so that it's members are properly | 609 // since we only clear the StyleResolver so that it's members are properly |
| 610 // updated in ScopedStyleResolver::addRulesFromSheet. | 610 // updated in ScopedStyleResolver::addRulesFromSheet. |
| 611 if (!m_ruleSet) | 611 if (!m_ruleSet) |
| 612 return; | 612 return; |
| 613 | 613 |
| 614 // Clearing the ruleSet means we need to recreate the styleResolver data str
uctures. | 614 // Clearing the ruleSet means we need to recreate the styleResolver data str
uctures. |
| 615 // See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet. | 615 // See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet. |
| 616 clearResolvers(m_loadingClients); | 616 clearResolvers(m_loadingClients); |
| 617 clearResolvers(m_completedClients); | 617 clearResolvers(m_completedClients); |
| 618 m_ruleSet.clear(); | 618 m_ruleSet.clear(); |
| 619 } | 619 } |
| 620 | 620 |
| 621 static void removeFontFaceRules(WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyl
eSheet>>& clients, const StyleRuleFontFace* fontFaceRule) | 621 static void removeFontFaceRules(HeapHashSet<WeakMember<CSSStyleSheet>>& clients,
const StyleRuleFontFace* fontFaceRule) |
| 622 { | 622 { |
| 623 for (const auto& sheet : clients) { | 623 for (const auto& sheet : clients) { |
| 624 if (Node* ownerNode = sheet->ownerNode()) | 624 if (Node* ownerNode = sheet->ownerNode()) |
| 625 ownerNode->document().styleEngine().removeFontFaceRules(WillBeHeapVe
ctor<RawPtrWillBeMember<const StyleRuleFontFace>>(1, fontFaceRule)); | 625 ownerNode->document().styleEngine().removeFontFaceRules(HeapVector<M
ember<const StyleRuleFontFace>>(1, fontFaceRule)); |
| 626 } | 626 } |
| 627 } | 627 } |
| 628 | 628 |
| 629 void StyleSheetContents::notifyRemoveFontFaceRule(const StyleRuleFontFace* fontF
aceRule) | 629 void StyleSheetContents::notifyRemoveFontFaceRule(const StyleRuleFontFace* fontF
aceRule) |
| 630 { | 630 { |
| 631 StyleSheetContents* root = rootStyleSheet(); | 631 StyleSheetContents* root = rootStyleSheet(); |
| 632 removeFontFaceRules(root->m_loadingClients, fontFaceRule); | 632 removeFontFaceRules(root->m_loadingClients, fontFaceRule); |
| 633 removeFontFaceRules(root->m_completedClients, fontFaceRule); | 633 removeFontFaceRules(root->m_completedClients, fontFaceRule); |
| 634 } | 634 } |
| 635 | 635 |
| 636 static void findFontFaceRulesFromRules(const WillBeHeapVector<RefPtrWillBeMember
<StyleRuleBase>>& rules, WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFont
Face>>& fontFaceRules) | 636 static void findFontFaceRulesFromRules(const HeapVector<Member<StyleRuleBase>>&
rules, HeapVector<Member<const StyleRuleFontFace>>& fontFaceRules) |
| 637 { | 637 { |
| 638 for (unsigned i = 0; i < rules.size(); ++i) { | 638 for (unsigned i = 0; i < rules.size(); ++i) { |
| 639 StyleRuleBase* rule = rules[i].get(); | 639 StyleRuleBase* rule = rules[i].get(); |
| 640 | 640 |
| 641 if (rule->isFontFaceRule()) { | 641 if (rule->isFontFaceRule()) { |
| 642 fontFaceRules.append(toStyleRuleFontFace(rule)); | 642 fontFaceRules.append(toStyleRuleFontFace(rule)); |
| 643 } else if (rule->isMediaRule()) { | 643 } else if (rule->isMediaRule()) { |
| 644 StyleRuleMedia* mediaRule = toStyleRuleMedia(rule); | 644 StyleRuleMedia* mediaRule = toStyleRuleMedia(rule); |
| 645 // We cannot know whether the media rule matches or not, but | 645 // We cannot know whether the media rule matches or not, but |
| 646 // for safety, remove @font-face in the media rule (if exists). | 646 // for safety, remove @font-face in the media rule (if exists). |
| 647 findFontFaceRulesFromRules(mediaRule->childRules(), fontFaceRules); | 647 findFontFaceRulesFromRules(mediaRule->childRules(), fontFaceRules); |
| 648 } | 648 } |
| 649 } | 649 } |
| 650 } | 650 } |
| 651 | 651 |
| 652 void StyleSheetContents::findFontFaceRules(WillBeHeapVector<RawPtrWillBeMember<c
onst StyleRuleFontFace>>& fontFaceRules) | 652 void StyleSheetContents::findFontFaceRules(HeapVector<Member<const StyleRuleFont
Face>>& fontFaceRules) |
| 653 { | 653 { |
| 654 for (unsigned i = 0; i < m_importRules.size(); ++i) { | 654 for (unsigned i = 0; i < m_importRules.size(); ++i) { |
| 655 if (!m_importRules[i]->styleSheet()) | 655 if (!m_importRules[i]->styleSheet()) |
| 656 continue; | 656 continue; |
| 657 m_importRules[i]->styleSheet()->findFontFaceRules(fontFaceRules); | 657 m_importRules[i]->styleSheet()->findFontFaceRules(fontFaceRules); |
| 658 } | 658 } |
| 659 | 659 |
| 660 findFontFaceRulesFromRules(childRules(), fontFaceRules); | 660 findFontFaceRulesFromRules(childRules(), fontFaceRules); |
| 661 } | 661 } |
| 662 | 662 |
| 663 DEFINE_TRACE(StyleSheetContents) | 663 DEFINE_TRACE(StyleSheetContents) |
| 664 { | 664 { |
| 665 #if ENABLE(OILPAN) | 665 #if ENABLE(OILPAN) |
| 666 visitor->trace(m_ownerRule); | 666 visitor->trace(m_ownerRule); |
| 667 visitor->trace(m_importRules); | 667 visitor->trace(m_importRules); |
| 668 visitor->trace(m_namespaceRules); | 668 visitor->trace(m_namespaceRules); |
| 669 visitor->trace(m_childRules); | 669 visitor->trace(m_childRules); |
| 670 visitor->trace(m_loadingClients); | 670 visitor->trace(m_loadingClients); |
| 671 visitor->trace(m_completedClients); | 671 visitor->trace(m_completedClients); |
| 672 visitor->trace(m_ruleSet); | 672 visitor->trace(m_ruleSet); |
| 673 #endif | 673 #endif |
| 674 } | 674 } |
| 675 | 675 |
| 676 } // namespace blink | 676 } // namespace blink |
| OLD | NEW |