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 (unsigned i = 0; i < root->m_clients.size(); ++i) { | 377 for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end (); ++it) { |
| 378 if (!root->m_clients[i]->loadCompleted()) | 378 if (!(*it)->loadCompleted()) |
| 379 return false; | 379 return false; |
| 380 } | 380 } |
| 381 return true; | 381 return true; |
| 382 } | 382 } |
| 383 | 383 |
| 384 void StyleSheetContents::checkLoaded() | 384 void StyleSheetContents::checkLoaded() |
| 385 { | 385 { |
| 386 if (isLoading()) | 386 if (isLoading()) |
| 387 return; | 387 return; |
| 388 | 388 |
| 389 // Avoid |this| being deleted by scripts that run via | 389 // Avoid |this| being deleted by scripts that run via |
| 390 // ScriptableDocumentParser::executeScriptsWaitingForResources(). | 390 // ScriptableDocumentParser::executeScriptsWaitingForResources(). |
| 391 // See https://bugs.webkit.org/show_bug.cgi?id=95106 | 391 // See https://bugs.webkit.org/show_bug.cgi?id=95106 |
| 392 RefPtrWillBeRawPtr<StyleSheetContents> protect(this); | 392 RefPtrWillBeRawPtr<StyleSheetContents> protect(this); |
| 393 | 393 |
| 394 StyleSheetContents* parentSheet = parentStyleSheet(); | 394 StyleSheetContents* parentSheet = parentStyleSheet(); |
| 395 if (parentSheet) { | 395 if (parentSheet) { |
| 396 parentSheet->checkLoaded(); | 396 parentSheet->checkLoaded(); |
| 397 return; | 397 return; |
| 398 } | 398 } |
| 399 | 399 |
| 400 StyleSheetContents* root = rootStyleSheet(); | 400 StyleSheetContents* root = rootStyleSheet(); |
| 401 if (root->m_clients.isEmpty()) | 401 if (root->m_clients.isEmpty()) |
| 402 return; | 402 return; |
| 403 | 403 |
| 404 Vector<CSSStyleSheet*> clients(root->m_clients); | 404 // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via |
| 405 for (unsigned i = 0; i < clients.size(); ++i) { | 405 // ScriptableDocumentParser::executeScriptsWaitingForResources(). Also prote ct |
|
haraken
2014/03/05 14:21:22
FYI, I'm planning to make a change that moves Scri
Mads Ager (chromium)
2014/03/05 14:51:16
The protection here is not only because of execute
| |
| 406 // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via | 406 // the |CSSStyleSheet| from being deleted during iteration via the |sheetLoa ded| |
| 407 // ScriptableDocumentParser::executeScriptsWaitingForResources(). | 407 // method. |
| 408 RefPtr<CSSStyleSheet> protectClient(clients[i]); | 408 // |
| 409 // FIXME: oilpan: with oilpan we do not need to protect the CSSStyleSheets | |
| 410 // explicitly during the iteration. The iterator will make the pointers | |
| 411 // strong during iteration so we can just directly iterate root->m_clients. | |
| 412 WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet>, 5> protectedClients; | |
| 413 for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end (); ++it) | |
| 414 protectedClients.append(*it); | |
| 409 | 415 |
| 410 if (clients[i]->loadCompleted()) | 416 for (unsigned i = 0; i < protectedClients.size(); ++i) { |
| 417 if (protectedClients[i]->loadCompleted()) | |
| 411 continue; | 418 continue; |
| 412 | 419 |
| 413 // sheetLoaded might be invoked after its owner node is removed from doc ument. | 420 // sheetLoaded might be invoked after its owner node is removed from doc ument. |
| 414 if (RefPtr<Node> ownerNode = clients[i]->ownerNode()) { | 421 if (RefPtr<Node> ownerNode = protectedClients[i]->ownerNode()) { |
| 415 if (clients[i]->sheetLoaded()) | 422 if (protectedClients[i]->sheetLoaded()) |
| 416 ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoad ErrorOccur); | 423 ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoad ErrorOccur); |
| 417 } | 424 } |
| 418 } | 425 } |
| 419 } | 426 } |
| 420 | 427 |
| 421 void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) | 428 void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) |
| 422 { | 429 { |
| 423 ASSERT(sheet); | 430 ASSERT(sheet); |
| 424 m_didLoadErrorOccur |= sheet->errorOccurred(); | 431 m_didLoadErrorOccur |= sheet->errorOccurred(); |
| 425 // updateLayoutIgnorePendingStyleSheets can cause us to create the RuleSet o n this | 432 // updateLayoutIgnorePendingStyleSheets can cause us to create the RuleSet o n this |
| 426 // sheet before its imports have loaded. So clear the RuleSet when the impor ts | 433 // sheet before its imports have loaded. So clear the RuleSet when the impor ts |
| 427 // load since the import's subrules are flattened into its parent sheet's Ru leSet. | 434 // load since the import's subrules are flattened into its parent sheet's Ru leSet. |
| 428 clearRuleSet(); | 435 clearRuleSet(); |
| 429 } | 436 } |
| 430 | 437 |
| 431 void StyleSheetContents::startLoadingDynamicSheet() | 438 void StyleSheetContents::startLoadingDynamicSheet() |
| 432 { | 439 { |
| 433 StyleSheetContents* root = rootStyleSheet(); | 440 StyleSheetContents* root = rootStyleSheet(); |
| 434 for (unsigned i = 0; i < root->m_clients.size(); ++i) | 441 for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end (); ++it) |
| 435 root->m_clients[i]->startLoadingDynamicSheet(); | 442 (*it)->startLoadingDynamicSheet(); |
| 436 } | 443 } |
| 437 | 444 |
| 438 StyleSheetContents* StyleSheetContents::rootStyleSheet() const | 445 StyleSheetContents* StyleSheetContents::rootStyleSheet() const |
| 439 { | 446 { |
| 440 const StyleSheetContents* root = this; | 447 const StyleSheetContents* root = this; |
| 441 while (root->parentStyleSheet()) | 448 while (root->parentStyleSheet()) |
| 442 root = root->parentStyleSheet(); | 449 root = root->parentStyleSheet(); |
| 443 return const_cast<StyleSheetContents*>(root); | 450 return const_cast<StyleSheetContents*>(root); |
| 444 } | 451 } |
| 445 | 452 |
| 446 bool StyleSheetContents::hasSingleOwnerNode() const | 453 bool StyleSheetContents::hasSingleOwnerNode() const |
| 447 { | 454 { |
| 448 StyleSheetContents* root = rootStyleSheet(); | 455 StyleSheetContents* root = rootStyleSheet(); |
| 449 if (root->m_clients.isEmpty()) | 456 if (root->m_clients.isEmpty()) |
| 450 return false; | 457 return false; |
| 451 return root->m_clients.size() == 1; | 458 return root->m_clients.size() == 1; |
| 452 } | 459 } |
| 453 | 460 |
| 454 Node* StyleSheetContents::singleOwnerNode() const | 461 Node* StyleSheetContents::singleOwnerNode() const |
| 455 { | 462 { |
| 456 StyleSheetContents* root = rootStyleSheet(); | 463 StyleSheetContents* root = rootStyleSheet(); |
| 457 if (root->m_clients.isEmpty()) | 464 if (root->m_clients.isEmpty()) |
| 458 return 0; | 465 return 0; |
| 459 ASSERT(root->m_clients.size() == 1); | 466 ASSERT(root->m_clients.size() == 1); |
| 460 return root->m_clients[0]->ownerNode(); | 467 return (*root->m_clients.begin())->ownerNode(); |
| 461 } | 468 } |
| 462 | 469 |
| 463 Document* StyleSheetContents::singleOwnerDocument() const | 470 Document* StyleSheetContents::singleOwnerDocument() const |
| 464 { | 471 { |
| 465 Node* ownerNode = singleOwnerNode(); | 472 Node* ownerNode = singleOwnerNode(); |
| 466 return ownerNode ? &ownerNode->document() : 0; | 473 return ownerNode ? &ownerNode->document() : 0; |
| 467 } | 474 } |
| 468 | 475 |
| 469 KURL StyleSheetContents::completeURL(const String& url) const | 476 KURL StyleSheetContents::completeURL(const String& url) const |
| 470 { | 477 { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 512 } | 519 } |
| 513 | 520 |
| 514 StyleSheetContents* StyleSheetContents::parentStyleSheet() const | 521 StyleSheetContents* StyleSheetContents::parentStyleSheet() const |
| 515 { | 522 { |
| 516 return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0; | 523 return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0; |
| 517 } | 524 } |
| 518 | 525 |
| 519 void StyleSheetContents::registerClient(CSSStyleSheet* sheet) | 526 void StyleSheetContents::registerClient(CSSStyleSheet* sheet) |
| 520 { | 527 { |
| 521 ASSERT(!m_clients.contains(sheet)); | 528 ASSERT(!m_clients.contains(sheet)); |
| 522 m_clients.append(sheet); | 529 m_clients.add(sheet); |
| 523 } | 530 } |
| 524 | 531 |
| 525 void StyleSheetContents::unregisterClient(CSSStyleSheet* sheet) | 532 void StyleSheetContents::unregisterClient(CSSStyleSheet* sheet) |
| 526 { | 533 { |
| 527 size_t position = m_clients.find(sheet); | 534 ASSERT(m_clients.contains(sheet)); |
| 528 ASSERT(position != kNotFound); | 535 m_clients.remove(sheet); |
| 529 m_clients.remove(position); | |
| 530 } | 536 } |
| 531 | 537 |
| 532 void StyleSheetContents::addedToMemoryCache() | 538 void StyleSheetContents::addedToMemoryCache() |
| 533 { | 539 { |
| 534 ASSERT(!m_isInMemoryCache); | 540 ASSERT(!m_isInMemoryCache); |
| 535 ASSERT(isCacheable()); | 541 ASSERT(isCacheable()); |
| 536 m_isInMemoryCache = true; | 542 m_isInMemoryCache = true; |
| 537 } | 543 } |
| 538 | 544 |
| 539 void StyleSheetContents::removedFromMemoryCache() | 545 void StyleSheetContents::removedFromMemoryCache() |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 564 parentSheet->clearRuleSet(); | 570 parentSheet->clearRuleSet(); |
| 565 | 571 |
| 566 // Don't want to clear the StyleResolver if the RuleSet hasn't been created | 572 // Don't want to clear the StyleResolver if the RuleSet hasn't been created |
| 567 // since we only clear the StyleResolver so that it's members are properly | 573 // since we only clear the StyleResolver so that it's members are properly |
| 568 // updated in ScopedStyleResolver::addRulesFromSheet. | 574 // updated in ScopedStyleResolver::addRulesFromSheet. |
| 569 if (!m_ruleSet) | 575 if (!m_ruleSet) |
| 570 return; | 576 return; |
| 571 | 577 |
| 572 // Clearing the ruleSet means we need to recreate the styleResolver data str uctures. | 578 // Clearing the ruleSet means we need to recreate the styleResolver data str uctures. |
| 573 // See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet. | 579 // See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet. |
| 574 for (size_t i = 0; i < m_clients.size(); ++i) { | 580 for (ClientsIterator it = m_clients.begin(); it != m_clients.end(); ++it) { |
| 575 if (Document* document = m_clients[i]->ownerDocument()) | 581 if (Document* document = (*it)->ownerDocument()) |
| 576 document->styleEngine()->clearResolver(); | 582 document->styleEngine()->clearResolver(); |
| 577 } | 583 } |
| 578 m_ruleSet.clear(); | 584 m_ruleSet.clear(); |
| 579 } | 585 } |
| 580 | 586 |
| 581 void StyleSheetContents::notifyRemoveFontFaceRule(const StyleRuleFontFace* fontF aceRule) | 587 void StyleSheetContents::notifyRemoveFontFaceRule(const StyleRuleFontFace* fontF aceRule) |
| 582 { | 588 { |
| 583 StyleSheetContents* root = rootStyleSheet(); | 589 StyleSheetContents* root = rootStyleSheet(); |
| 584 | 590 |
| 585 for (unsigned i = 0; i < root->m_clients.size(); ++i) { | 591 for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end (); ++it) { |
| 586 if (Node* ownerNode = root->m_clients[0]->ownerNode()) | 592 if (Node* ownerNode = (*it)->ownerNode()) |
| 587 ownerNode->document().styleEngine()->removeFontFaceRules(WillBeHeapV ector<RawPtrWillBeMember<const StyleRuleFontFace> >(1, fontFaceRule)); | 593 ownerNode->document().styleEngine()->removeFontFaceRules(WillBeHeapV ector<RawPtrWillBeMember<const StyleRuleFontFace> >(1, fontFaceRule)); |
| 588 } | 594 } |
| 589 } | 595 } |
| 590 | 596 |
| 591 static void findFontFaceRulesFromRules(const WillBeHeapVector<RefPtrWillBeMember <StyleRuleBase> >& rules, WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFon tFace> >& fontFaceRules) | 597 static void findFontFaceRulesFromRules(const WillBeHeapVector<RefPtrWillBeMember <StyleRuleBase> >& rules, WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFon tFace> >& fontFaceRules) |
| 592 { | 598 { |
| 593 for (unsigned i = 0; i < rules.size(); ++i) { | 599 for (unsigned i = 0; i < rules.size(); ++i) { |
| 594 StyleRuleBase* rule = rules[i].get(); | 600 StyleRuleBase* rule = rules[i].get(); |
| 595 | 601 |
| 596 if (rule->isFontFaceRule()) { | 602 if (rule->isFontFaceRule()) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 613 } | 619 } |
| 614 | 620 |
| 615 findFontFaceRulesFromRules(childRules(), fontFaceRules); | 621 findFontFaceRulesFromRules(childRules(), fontFaceRules); |
| 616 } | 622 } |
| 617 | 623 |
| 618 void StyleSheetContents::trace(Visitor* visitor) | 624 void StyleSheetContents::trace(Visitor* visitor) |
| 619 { | 625 { |
| 620 visitor->trace(m_ownerRule); | 626 visitor->trace(m_ownerRule); |
| 621 visitor->trace(m_importRules); | 627 visitor->trace(m_importRules); |
| 622 visitor->trace(m_childRules); | 628 visitor->trace(m_childRules); |
| 629 visitor->trace(m_clients); | |
| 623 } | 630 } |
| 624 | 631 |
| 625 } | 632 } |
| OLD | NEW |