Chromium Code Reviews| 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 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 367 return false; | 367 return false; |
| 368 } | 368 } |
| 369 | 369 |
| 370 bool StyleSheetContents::loadCompleted() const | 370 bool StyleSheetContents::loadCompleted() const |
| 371 { | 371 { |
| 372 StyleSheetContents* parentSheet = parentStyleSheet(); | 372 StyleSheetContents* parentSheet = parentStyleSheet(); |
| 373 if (parentSheet) | 373 if (parentSheet) |
| 374 return parentSheet->loadCompleted(); | 374 return parentSheet->loadCompleted(); |
| 375 | 375 |
| 376 StyleSheetContents* root = rootStyleSheet(); | 376 StyleSheetContents* root = rootStyleSheet(); |
| 377 for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end (); ++it) { | 377 if (root->m_loadingClients.size()) |
| 378 if (!(*it)->loadCompleted()) | 378 return false; |
| 379 return false; | |
| 380 } | |
| 381 return true; | 379 return true; |
|
esprehn
2014/03/13 19:56:28
return rootStyleSheet()->m_loadingClients.isEmpty(
Mads Ager (chromium)
2014/03/14 09:30:18
Heh, yes, thanks!
| |
| 382 } | 380 } |
| 383 | 381 |
| 384 void StyleSheetContents::checkLoaded() | 382 void StyleSheetContents::checkLoaded() |
| 385 { | 383 { |
| 386 if (isLoading()) | 384 if (isLoading()) |
| 387 return; | 385 return; |
| 388 | 386 |
| 389 // Avoid |this| being deleted by scripts that run via | 387 // Avoid |this| being deleted by scripts that run via |
| 390 // ScriptableDocumentParser::executeScriptsWaitingForResources(). | 388 // ScriptableDocumentParser::executeScriptsWaitingForResources(). |
| 391 // See https://bugs.webkit.org/show_bug.cgi?id=95106 | 389 // See https://bugs.webkit.org/show_bug.cgi?id=95106 |
| 392 RefPtrWillBeRawPtr<StyleSheetContents> protect(this); | 390 RefPtrWillBeRawPtr<StyleSheetContents> protect(this); |
| 393 | 391 |
| 394 StyleSheetContents* parentSheet = parentStyleSheet(); | 392 StyleSheetContents* parentSheet = parentStyleSheet(); |
| 395 if (parentSheet) { | 393 if (parentSheet) { |
| 396 parentSheet->checkLoaded(); | 394 parentSheet->checkLoaded(); |
| 397 return; | 395 return; |
| 398 } | 396 } |
| 399 | 397 |
| 400 StyleSheetContents* root = rootStyleSheet(); | 398 StyleSheetContents* root = rootStyleSheet(); |
| 401 if (root->m_clients.isEmpty()) | 399 if (root->m_loadingClients.isEmpty()) |
| 402 return; | 400 return; |
| 403 | 401 |
| 404 // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via | 402 // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via |
| 405 // ScriptableDocumentParser::executeScriptsWaitingForResources(). Also prote ct | 403 // ScriptableDocumentParser::executeScriptsWaitingForResources(). Also prote ct |
| 406 // the |CSSStyleSheet| from being deleted during iteration via the |sheetLoa ded| | 404 // the |CSSStyleSheet| from being deleted during iteration via the |sheetLoa ded| |
| 407 // method. | 405 // method. |
| 408 // | 406 // |
| 409 // FIXME: oilpan: with oilpan we do not need to protect the CSSStyleSheets | 407 // FIXME: oilpan: with oilpan we do not need to protect the CSSStyleSheets |
| 410 // explicitly during the iteration. The iterator will make the pointers | 408 // explicitly during the iteration. The iterator will make the pointers |
| 411 // strong during iteration so we can just directly iterate root->m_clients. | 409 // strong during iteration so we can just directly iterate root->m_clients. |
| 412 WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet>, 5> protectedClients; | 410 WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > protectedClients; |
| 413 for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end (); ++it) | 411 protectedClients.reserveInitialCapacity(root->m_loadingClients.size()); |
| 412 for (ClientsIterator it = root->m_loadingClients.begin(); it != root->m_load ingClients.end(); ++it) | |
| 414 protectedClients.append(*it); | 413 protectedClients.append(*it); |
|
esprehn
2014/03/13 19:56:28
This should just use copyToVector()
Mads Ager (chromium)
2014/03/14 09:30:18
Oh, I didn't know about copyToVector. Much better!
| |
| 415 | 414 |
| 416 for (unsigned i = 0; i < protectedClients.size(); ++i) { | 415 for (unsigned i = 0; i < protectedClients.size(); ++i) { |
| 417 if (protectedClients[i]->loadCompleted()) | 416 if (protectedClients[i]->loadCompleted()) |
| 418 continue; | 417 continue; |
| 419 | 418 |
| 420 // sheetLoaded might be invoked after its owner node is removed from doc ument. | 419 // sheetLoaded might be invoked after its owner node is removed from doc ument. |
| 421 if (RefPtr<Node> ownerNode = protectedClients[i]->ownerNode()) { | 420 if (RefPtr<Node> ownerNode = protectedClients[i]->ownerNode()) { |
| 422 if (protectedClients[i]->sheetLoaded()) | 421 if (protectedClients[i]->sheetLoaded()) |
| 423 ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoad ErrorOccur); | 422 ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoad ErrorOccur); |
| 424 } | 423 } |
| 425 } | 424 } |
| 426 } | 425 } |
| 427 | 426 |
| 428 void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) | 427 void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) |
| 429 { | 428 { |
| 430 ASSERT(sheet); | 429 ASSERT(sheet); |
| 431 m_didLoadErrorOccur |= sheet->errorOccurred(); | 430 m_didLoadErrorOccur |= sheet->errorOccurred(); |
| 432 // updateLayoutIgnorePendingStyleSheets can cause us to create the RuleSet o n this | 431 // updateLayoutIgnorePendingStyleSheets can cause us to create the RuleSet o n this |
| 433 // sheet before its imports have loaded. So clear the RuleSet when the impor ts | 432 // sheet before its imports have loaded. So clear the RuleSet when the impor ts |
| 434 // load since the import's subrules are flattened into its parent sheet's Ru leSet. | 433 // load since the import's subrules are flattened into its parent sheet's Ru leSet. |
| 435 clearRuleSet(); | 434 clearRuleSet(); |
| 436 } | 435 } |
| 437 | 436 |
| 438 void StyleSheetContents::startLoadingDynamicSheet() | 437 void StyleSheetContents::startLoadingDynamicSheet() |
| 439 { | 438 { |
| 440 StyleSheetContents* root = rootStyleSheet(); | 439 StyleSheetContents* root = rootStyleSheet(); |
| 441 for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end (); ++it) | 440 for (ClientsIterator it = root->m_loadingClients.begin(); it != root->m_load ingClients.end(); ++it) |
| 441 (*it)->startLoadingDynamicSheet(); | |
| 442 for (ClientsIterator it = root->m_completedClients.begin(); it != root->m_co mpletedClients.end(); ++it) | |
| 442 (*it)->startLoadingDynamicSheet(); | 443 (*it)->startLoadingDynamicSheet(); |
| 443 } | 444 } |
| 444 | 445 |
| 445 StyleSheetContents* StyleSheetContents::rootStyleSheet() const | 446 StyleSheetContents* StyleSheetContents::rootStyleSheet() const |
| 446 { | 447 { |
| 447 const StyleSheetContents* root = this; | 448 const StyleSheetContents* root = this; |
| 448 while (root->parentStyleSheet()) | 449 while (root->parentStyleSheet()) |
| 449 root = root->parentStyleSheet(); | 450 root = root->parentStyleSheet(); |
| 450 return const_cast<StyleSheetContents*>(root); | 451 return const_cast<StyleSheetContents*>(root); |
| 451 } | 452 } |
| 452 | 453 |
| 453 bool StyleSheetContents::hasSingleOwnerNode() const | 454 bool StyleSheetContents::hasSingleOwnerNode() const |
| 454 { | 455 { |
| 455 StyleSheetContents* root = rootStyleSheet(); | 456 StyleSheetContents* root = rootStyleSheet(); |
| 456 if (root->m_clients.isEmpty()) | 457 return root->hasOneClient(); |
|
esprehn
2014/03/13 19:56:28
rootStyleSheet()->hasOneClient()
Mads Ager (chromium)
2014/03/14 09:30:18
Done.
| |
| 457 return false; | |
| 458 return root->m_clients.size() == 1; | |
| 459 } | 458 } |
| 460 | 459 |
| 461 Node* StyleSheetContents::singleOwnerNode() const | 460 Node* StyleSheetContents::singleOwnerNode() const |
| 462 { | 461 { |
| 463 StyleSheetContents* root = rootStyleSheet(); | 462 StyleSheetContents* root = rootStyleSheet(); |
| 464 if (root->m_clients.isEmpty()) | 463 if (root->hasOneClient()) { |
| 465 return 0; | 464 return root->m_loadingClients.size() ? (*root->m_loadingClients.begin()) ->ownerNode() : (*root->m_completedClients.begin())->ownerNode(); |
|
esprehn
2014/03/13 19:56:28
Lets break this up since it's easier to read.
if
Mads Ager (chromium)
2014/03/14 09:30:18
Yes, much better, thanks.
| |
| 466 ASSERT(root->m_clients.size() == 1); | 465 } |
| 467 return (*root->m_clients.begin())->ownerNode(); | 466 ASSERT(root->m_loadingClients.isEmpty() && root->m_completedClients.isEmpty( )); |
| 467 return 0; | |
| 468 } | 468 } |
| 469 | 469 |
| 470 Document* StyleSheetContents::singleOwnerDocument() const | 470 Document* StyleSheetContents::singleOwnerDocument() const |
| 471 { | 471 { |
| 472 Node* ownerNode = singleOwnerNode(); | 472 Node* ownerNode = singleOwnerNode(); |
| 473 return ownerNode ? &ownerNode->document() : 0; | 473 return ownerNode ? &ownerNode->document() : 0; |
| 474 } | 474 } |
| 475 | 475 |
| 476 KURL StyleSheetContents::completeURL(const String& url) const | 476 KURL StyleSheetContents::completeURL(const String& url) const |
| 477 { | 477 { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 518 return childRulesHaveFailedOrCanceledSubresources(m_childRules); | 518 return childRulesHaveFailedOrCanceledSubresources(m_childRules); |
| 519 } | 519 } |
| 520 | 520 |
| 521 StyleSheetContents* StyleSheetContents::parentStyleSheet() const | 521 StyleSheetContents* StyleSheetContents::parentStyleSheet() const |
| 522 { | 522 { |
| 523 return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0; | 523 return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0; |
| 524 } | 524 } |
| 525 | 525 |
| 526 void StyleSheetContents::registerClient(CSSStyleSheet* sheet) | 526 void StyleSheetContents::registerClient(CSSStyleSheet* sheet) |
| 527 { | 527 { |
| 528 ASSERT(!m_clients.contains(sheet)); | 528 ASSERT(!m_loadingClients.contains(sheet) && !m_completedClients.contains(she et)); |
| 529 m_clients.add(sheet); | 529 m_loadingClients.add(sheet); |
|
esprehn
2014/03/13 19:56:28
Why is it a HashSet if you're just going to ASSERT
Mads Ager (chromium)
2014/03/14 09:30:18
The set of clients is a weak set. It does not keep
| |
| 530 } | 530 } |
| 531 | 531 |
| 532 void StyleSheetContents::unregisterClient(CSSStyleSheet* sheet) | 532 void StyleSheetContents::unregisterClient(CSSStyleSheet* sheet) |
| 533 { | 533 { |
| 534 ASSERT(m_clients.contains(sheet)); | 534 ASSERT(m_loadingClients.contains(sheet) || m_completedClients.contains(sheet )); |
| 535 m_clients.remove(sheet); | 535 m_loadingClients.remove(sheet); |
| 536 m_completedClients.remove(sheet); | |
| 537 } | |
| 538 | |
| 539 void StyleSheetContents::clientLoadCompleted(CSSStyleSheet* sheet) | |
| 540 { | |
| 541 ASSERT(m_loadingClients.contains(sheet)); | |
| 542 m_loadingClients.remove(sheet); | |
| 543 m_completedClients.add(sheet); | |
| 544 } | |
| 545 | |
| 546 void StyleSheetContents::clientLoadStarted(CSSStyleSheet* sheet) | |
| 547 { | |
| 548 ASSERT(m_completedClients.contains(sheet)); | |
| 549 m_completedClients.remove(sheet); | |
| 550 m_loadingClients.add(sheet); | |
| 536 } | 551 } |
| 537 | 552 |
| 538 void StyleSheetContents::addedToMemoryCache() | 553 void StyleSheetContents::addedToMemoryCache() |
| 539 { | 554 { |
| 540 ASSERT(!m_isInMemoryCache); | 555 ASSERT(!m_isInMemoryCache); |
| 541 ASSERT(isCacheable()); | 556 ASSERT(isCacheable()); |
| 542 m_isInMemoryCache = true; | 557 m_isInMemoryCache = true; |
| 543 } | 558 } |
| 544 | 559 |
| 545 void StyleSheetContents::removedFromMemoryCache() | 560 void StyleSheetContents::removedFromMemoryCache() |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 557 | 572 |
| 558 RuleSet& StyleSheetContents::ensureRuleSet(const MediaQueryEvaluator& medium, Ad dRuleFlags addRuleFlags) | 573 RuleSet& StyleSheetContents::ensureRuleSet(const MediaQueryEvaluator& medium, Ad dRuleFlags addRuleFlags) |
| 559 { | 574 { |
| 560 if (!m_ruleSet) { | 575 if (!m_ruleSet) { |
| 561 m_ruleSet = RuleSet::create(); | 576 m_ruleSet = RuleSet::create(); |
| 562 m_ruleSet->addRulesFromSheet(this, medium, addRuleFlags); | 577 m_ruleSet->addRulesFromSheet(this, medium, addRuleFlags); |
| 563 } | 578 } |
| 564 return *m_ruleSet.get(); | 579 return *m_ruleSet.get(); |
| 565 } | 580 } |
| 566 | 581 |
| 582 static void clearResolvers(WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleShee t> >& clients) | |
| 583 { | |
| 584 for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >::iterator it = clients.begin(); it != clients.end(); ++it) { | |
| 585 if (Document* document = (*it)->ownerDocument()) | |
| 586 document->styleEngine()->clearResolver(); | |
| 587 } | |
| 588 } | |
| 589 | |
| 567 void StyleSheetContents::clearRuleSet() | 590 void StyleSheetContents::clearRuleSet() |
| 568 { | 591 { |
| 569 if (StyleSheetContents* parentSheet = parentStyleSheet()) | 592 if (StyleSheetContents* parentSheet = parentStyleSheet()) |
| 570 parentSheet->clearRuleSet(); | 593 parentSheet->clearRuleSet(); |
| 571 | 594 |
| 572 // Don't want to clear the StyleResolver if the RuleSet hasn't been created | 595 // Don't want to clear the StyleResolver if the RuleSet hasn't been created |
| 573 // since we only clear the StyleResolver so that it's members are properly | 596 // since we only clear the StyleResolver so that it's members are properly |
| 574 // updated in ScopedStyleResolver::addRulesFromSheet. | 597 // updated in ScopedStyleResolver::addRulesFromSheet. |
| 575 if (!m_ruleSet) | 598 if (!m_ruleSet) |
| 576 return; | 599 return; |
| 577 | 600 |
| 578 // Clearing the ruleSet means we need to recreate the styleResolver data str uctures. | 601 // Clearing the ruleSet means we need to recreate the styleResolver data str uctures. |
| 579 // See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet. | 602 // See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet. |
| 580 for (ClientsIterator it = m_clients.begin(); it != m_clients.end(); ++it) { | 603 clearResolvers(m_loadingClients); |
| 581 if (Document* document = (*it)->ownerDocument()) | 604 clearResolvers(m_completedClients); |
| 582 document->styleEngine()->clearResolver(); | 605 m_ruleSet.clear(); |
| 606 } | |
| 607 | |
| 608 static void removeFontFaceRules(WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyl eSheet> >& clients, const StyleRuleFontFace* fontFaceRule) | |
| 609 { | |
| 610 for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >::iterator it = clients.begin(); it != clients.end(); ++it) { | |
| 611 if (Node* ownerNode = (*it)->ownerNode()) | |
| 612 ownerNode->document().styleEngine()->removeFontFaceRules(WillBeHeapV ector<RawPtrWillBeMember<const StyleRuleFontFace> >(1, fontFaceRule)); | |
| 583 } | 613 } |
| 584 m_ruleSet.clear(); | |
| 585 } | 614 } |
| 586 | 615 |
| 587 void StyleSheetContents::notifyRemoveFontFaceRule(const StyleRuleFontFace* fontF aceRule) | 616 void StyleSheetContents::notifyRemoveFontFaceRule(const StyleRuleFontFace* fontF aceRule) |
| 588 { | 617 { |
| 589 StyleSheetContents* root = rootStyleSheet(); | 618 StyleSheetContents* root = rootStyleSheet(); |
| 590 | 619 removeFontFaceRules(root->m_loadingClients, fontFaceRule); |
| 591 for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end (); ++it) { | 620 removeFontFaceRules(root->m_completedClients, fontFaceRule); |
| 592 if (Node* ownerNode = (*it)->ownerNode()) | |
| 593 ownerNode->document().styleEngine()->removeFontFaceRules(WillBeHeapV ector<RawPtrWillBeMember<const StyleRuleFontFace> >(1, fontFaceRule)); | |
| 594 } | |
| 595 } | 621 } |
| 596 | 622 |
| 597 static void findFontFaceRulesFromRules(const WillBeHeapVector<RefPtrWillBeMember <StyleRuleBase> >& rules, WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFon tFace> >& fontFaceRules) | 623 static void findFontFaceRulesFromRules(const WillBeHeapVector<RefPtrWillBeMember <StyleRuleBase> >& rules, WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFon tFace> >& fontFaceRules) |
| 598 { | 624 { |
| 599 for (unsigned i = 0; i < rules.size(); ++i) { | 625 for (unsigned i = 0; i < rules.size(); ++i) { |
| 600 StyleRuleBase* rule = rules[i].get(); | 626 StyleRuleBase* rule = rules[i].get(); |
| 601 | 627 |
| 602 if (rule->isFontFaceRule()) { | 628 if (rule->isFontFaceRule()) { |
| 603 fontFaceRules.append(toStyleRuleFontFace(rule)); | 629 fontFaceRules.append(toStyleRuleFontFace(rule)); |
| 604 } else if (rule->isMediaRule()) { | 630 } else if (rule->isMediaRule()) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 619 } | 645 } |
| 620 | 646 |
| 621 findFontFaceRulesFromRules(childRules(), fontFaceRules); | 647 findFontFaceRulesFromRules(childRules(), fontFaceRules); |
| 622 } | 648 } |
| 623 | 649 |
| 624 void StyleSheetContents::trace(Visitor* visitor) | 650 void StyleSheetContents::trace(Visitor* visitor) |
| 625 { | 651 { |
| 626 visitor->trace(m_ownerRule); | 652 visitor->trace(m_ownerRule); |
| 627 visitor->trace(m_importRules); | 653 visitor->trace(m_importRules); |
| 628 visitor->trace(m_childRules); | 654 visitor->trace(m_childRules); |
| 629 visitor->trace(m_clients); | 655 visitor->trace(m_loadingClients); |
| 656 visitor->trace(m_completedClients); | |
| 630 visitor->trace(m_ruleSet); | 657 visitor->trace(m_ruleSet); |
| 631 } | 658 } |
| 632 | 659 |
| 633 } | 660 } |
| OLD | NEW |