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