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