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