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 |