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; |
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); |
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(); |
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(); |
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); |
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 } | 657 } |
631 | 658 |
632 } | 659 } |
OLD | NEW |