Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(473)

Side by Side Diff: third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp

Issue 2613853002: Phase III Step 2: Call imageNotifyFinished() and image load event after SVG loading completes (Closed)
Patch Set: Rebase Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006 Eric Seidel <eric@webkit.org> 2 * Copyright (C) 2006 Eric Seidel <eric@webkit.org>
3 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
4 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 4 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 #include "platform/graphics/paint/ClipRecorder.h" 58 #include "platform/graphics/paint/ClipRecorder.h"
59 #include "platform/graphics/paint/CullRect.h" 59 #include "platform/graphics/paint/CullRect.h"
60 #include "platform/graphics/paint/DrawingRecorder.h" 60 #include "platform/graphics/paint/DrawingRecorder.h"
61 #include "platform/graphics/paint/PaintRecord.h" 61 #include "platform/graphics/paint/PaintRecord.h"
62 #include "platform/graphics/paint/PaintRecordBuilder.h" 62 #include "platform/graphics/paint/PaintRecordBuilder.h"
63 #include "platform/instrumentation/tracing/TraceEvent.h" 63 #include "platform/instrumentation/tracing/TraceEvent.h"
64 #include "platform/wtf/PassRefPtr.h" 64 #include "platform/wtf/PassRefPtr.h"
65 65
66 namespace blink { 66 namespace blink {
67 67
68 // SVGImageLocalFrameClient is used to wait until SVG document's load event
69 // in the case where there are subresources asynchronously loaded.
70 //
71 // Reference cycle: SVGImage -(Persistent)-> Page -(Member)-> Frame -(Member)->
72 // FrameClient == SVGImageLocalFrameClient -(raw)-> SVGImage.
73 class SVGImage::SVGImageLocalFrameClient : public EmptyLocalFrameClient {
74 public:
75 SVGImageLocalFrameClient(SVGImage* image) : image_(image) {}
76
77 void ClearImage() { image_ = nullptr; }
78
79 private:
80 void DispatchDidHandleOnloadEvents() override {
81 // The SVGImage was destructed before SVG load completion.
82 if (!image_)
83 return;
84
85 image_->LoadCompleted();
86 }
87
88 // Cleared manually by SVGImage's destructor when |image_| is destructed.
89 SVGImage* image_;
90 };
91
68 SVGImage::SVGImage(ImageObserver* observer) 92 SVGImage::SVGImage(ImageObserver* observer)
69 : Image(observer), 93 : Image(observer),
70 paint_controller_(PaintController::Create()), 94 paint_controller_(PaintController::Create()),
71 has_pending_timeline_rewind_(false) {} 95 has_pending_timeline_rewind_(false) {}
72 96
73 SVGImage::~SVGImage() { 97 SVGImage::~SVGImage() {
98 if (frame_client_)
99 frame_client_->ClearImage();
100
74 if (page_) { 101 if (page_) {
75 // Store m_page in a local variable, clearing m_page, so that 102 // Store m_page in a local variable, clearing m_page, so that
76 // SVGImageChromeClient knows we're destructed. 103 // SVGImageChromeClient knows we're destructed.
77 Page* current_page = page_.Release(); 104 Page* current_page = page_.Release();
78 // Break both the loader and view references to the frame 105 // Break both the loader and view references to the frame
79 current_page->WillBeDestroyed(); 106 current_page->WillBeDestroyed();
80 } 107 }
81 108
82 // Verify that page teardown destroyed the Chrome 109 // Verify that page teardown destroyed the Chrome
83 DCHECK(!chrome_client_ || !chrome_client_->GetImage()); 110 DCHECK(!chrome_client_ || !chrome_client_->GetImage());
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 } 625 }
599 626
600 void SVGImage::UpdateUseCounters(const Document& document) const { 627 void SVGImage::UpdateUseCounters(const Document& document) const {
601 if (SVGSVGElement* root_element = SvgRootElement(page_.Get())) { 628 if (SVGSVGElement* root_element = SvgRootElement(page_.Get())) {
602 if (root_element->TimeContainer()->HasAnimations()) 629 if (root_element->TimeContainer()->HasAnimations())
603 UseCounter::Count(document, 630 UseCounter::Count(document,
604 UseCounter::kSVGSMILAnimationInImageRegardlessOfCache); 631 UseCounter::kSVGSMILAnimationInImageRegardlessOfCache);
605 } 632 }
606 } 633 }
607 634
635 void SVGImage::LoadCompleted() {
636 switch (load_state_) {
637 case kInDataChanged:
638 load_state_ = kLoadCompleted;
639 break;
640
641 case kWaitingForAsyncLoadCompletion:
642 load_state_ = kLoadCompleted;
643 if (GetImageObserver())
644 GetImageObserver()->AsyncLoadCompleted(this);
645 break;
646
647 case kDataChangedNotStarted:
648 case kLoadCompleted:
649 CHECK(false);
650 break;
651 }
652 }
653
608 Image::SizeAvailability SVGImage::DataChanged(bool all_data_received) { 654 Image::SizeAvailability SVGImage::DataChanged(bool all_data_received) {
609 TRACE_EVENT0("blink", "SVGImage::dataChanged"); 655 TRACE_EVENT0("blink", "SVGImage::dataChanged");
610 656
611 // Don't do anything if is an empty image. 657 // Don't do anything if is an empty image.
612 if (!Data()->size()) 658 if (!Data()->size())
613 return kSizeAvailable; 659 return kSizeAvailable;
614 660
615 if (all_data_received) { 661 if (!all_data_received)
616 // SVGImage will fire events (and the default C++ handlers run) but doesn't 662 return page_ ? kSizeAvailable : kSizeUnavailable;
617 // actually allow script to run so it's fine to call into it. We allow this
618 // since it means an SVG data url can synchronously load like other image
619 // types.
620 EventDispatchForbiddenScope::AllowUserAgentEvents allow_user_agent_events;
621 663
622 DEFINE_STATIC_LOCAL(LocalFrameClient, dummy_local_frame_client, 664 CHECK(!page_);
623 (EmptyLocalFrameClient::Create()));
624 665
625 CHECK(!page_); 666 // SVGImage will fire events (and the default C++ handlers run) but doesn't
667 // actually allow script to run so it's fine to call into it. We allow this
668 // since it means an SVG data url can synchronously load like other image
669 // types.
670 EventDispatchForbiddenScope::AllowUserAgentEvents allow_user_agent_events;
626 671
627 Page::PageClients page_clients; 672 CHECK_EQ(load_state_, kDataChangedNotStarted);
628 FillWithEmptyClients(page_clients); 673 load_state_ = kInDataChanged;
629 chrome_client_ = SVGImageChromeClient::Create(this);
630 page_clients.chrome_client = chrome_client_.Get();
631 674
632 // FIXME: If this SVG ends up loading itself, we might leak the world. 675 Page::PageClients page_clients;
633 // The Cache code does not know about ImageResources holding Frames and 676 FillWithEmptyClients(page_clients);
634 // won't know to break the cycle. 677 chrome_client_ = SVGImageChromeClient::Create(this);
635 // This will become an issue when SVGImage will be able to load other 678 page_clients.chrome_client = chrome_client_.Get();
636 // SVGImage objects, but we're safe now, because SVGImage can only be
637 // loaded by a top-level document.
638 Page* page;
639 {
640 TRACE_EVENT0("blink", "SVGImage::dataChanged::createPage");
641 page = Page::Create(page_clients);
642 page->GetSettings().SetScriptEnabled(false);
643 page->GetSettings().SetPluginsEnabled(false);
644 page->GetSettings().SetAcceleratedCompositingEnabled(false);
645 679
646 // Because this page is detached, it can't get default font settings 680 // FIXME: If this SVG ends up loading itself, we might leak the world.
647 // from the embedder. Copy over font settings so we have sensible 681 // The Cache code does not know about ImageResources holding Frames and
648 // defaults. These settings are fixed and will not update if changed. 682 // won't know to break the cycle.
649 if (!Page::OrdinaryPages().IsEmpty()) { 683 // This will become an issue when SVGImage will be able to load other
650 Settings& default_settings = 684 // SVGImage objects, but we're safe now, because SVGImage can only be
651 (*Page::OrdinaryPages().begin())->GetSettings(); 685 // loaded by a top-level document.
652 page->GetSettings().GetGenericFontFamilySettings() = 686 Page* page;
653 default_settings.GetGenericFontFamilySettings(); 687 {
654 page->GetSettings().SetMinimumFontSize( 688 TRACE_EVENT0("blink", "SVGImage::dataChanged::createPage");
655 default_settings.GetMinimumFontSize()); 689 page = Page::Create(page_clients);
656 page->GetSettings().SetMinimumLogicalFontSize( 690 page->GetSettings().SetScriptEnabled(false);
657 default_settings.GetMinimumLogicalFontSize()); 691 page->GetSettings().SetPluginsEnabled(false);
658 page->GetSettings().SetDefaultFontSize( 692 page->GetSettings().SetAcceleratedCompositingEnabled(false);
659 default_settings.GetDefaultFontSize()); 693
660 page->GetSettings().SetDefaultFixedFontSize( 694 // Because this page is detached, it can't get default font settings
661 default_settings.GetDefaultFixedFontSize()); 695 // from the embedder. Copy over font settings so we have sensible
662 } 696 // defaults. These settings are fixed and will not update if changed.
697 if (!Page::OrdinaryPages().IsEmpty()) {
698 Settings& default_settings =
699 (*Page::OrdinaryPages().begin())->GetSettings();
700 page->GetSettings().GetGenericFontFamilySettings() =
701 default_settings.GetGenericFontFamilySettings();
702 page->GetSettings().SetMinimumFontSize(
703 default_settings.GetMinimumFontSize());
704 page->GetSettings().SetMinimumLogicalFontSize(
705 default_settings.GetMinimumLogicalFontSize());
706 page->GetSettings().SetDefaultFontSize(
707 default_settings.GetDefaultFontSize());
708 page->GetSettings().SetDefaultFixedFontSize(
709 default_settings.GetDefaultFixedFontSize());
710 }
663 } 711 }
664 712
665 LocalFrame* frame = nullptr; 713 LocalFrame* frame = nullptr;
666 { 714 {
667 TRACE_EVENT0("blink", "SVGImage::dataChanged::createFrame"); 715 TRACE_EVENT0("blink", "SVGImage::dataChanged::createFrame");
668 frame = LocalFrame::Create(&dummy_local_frame_client, *page, 0); 716 DCHECK(!frame_client_);
717 frame_client_ = new SVGImageLocalFrameClient(this);
718 frame = LocalFrame::Create(frame_client_, *page, 0);
669 frame->SetView(FrameView::Create(*frame)); 719 frame->SetView(FrameView::Create(*frame));
670 frame->Init(); 720 frame->Init();
671 } 721 }
672 722
673 FrameLoader& loader = frame->Loader(); 723 FrameLoader& loader = frame->Loader();
674 loader.ForceSandboxFlags(kSandboxAll); 724 loader.ForceSandboxFlags(kSandboxAll);
675 725
676 frame->View()->SetScrollbarsSuppressed(true); 726 frame->View()->SetScrollbarsSuppressed(true);
677 // SVG Images will always synthesize a viewBox, if it's not available, and 727 // SVG Images will always synthesize a viewBox, if it's not available, and
678 // thus never see scrollbars. 728 // thus never see scrollbars.
679 frame->View()->SetCanHaveScrollbars(false); 729 frame->View()->SetCanHaveScrollbars(false);
680 // SVG Images are transparent. 730 // SVG Images are transparent.
681 frame->View()->SetBaseBackgroundColor(Color::kTransparent); 731 frame->View()->SetBaseBackgroundColor(Color::kTransparent);
682 732
683 page_ = page; 733 page_ = page;
684 734
685 TRACE_EVENT0("blink", "SVGImage::dataChanged::load"); 735 TRACE_EVENT0("blink", "SVGImage::dataChanged::load");
686 loader.Load(FrameLoadRequest( 736 loader.Load(FrameLoadRequest(
687 0, ResourceRequest(BlankURL()), 737 0, ResourceRequest(BlankURL()),
688 SubstituteData(Data(), AtomicString("image/svg+xml"), 738 SubstituteData(Data(), AtomicString("image/svg+xml"),
689 AtomicString("UTF-8"), KURL(), kForceSynchronousLoad))); 739 AtomicString("UTF-8"), KURL(), kForceSynchronousLoad)));
690 740
691 // Set the concrete object size before a container size is available. 741 // Set the concrete object size before a container size is available.
692 intrinsic_size_ = RoundedIntSize(ConcreteObjectSize(FloatSize( 742 intrinsic_size_ = RoundedIntSize(ConcreteObjectSize(FloatSize(
693 LayoutReplaced::kDefaultWidth, LayoutReplaced::kDefaultHeight))); 743 LayoutReplaced::kDefaultWidth, LayoutReplaced::kDefaultHeight)));
744
745 DCHECK(page_);
746 switch (load_state_) {
747 case kInDataChanged:
748 load_state_ = kWaitingForAsyncLoadCompletion;
749 return kSizeAvailableAndLoadingAsynchronously;
750
751 case kLoadCompleted:
752 return kSizeAvailable;
753
754 case kDataChangedNotStarted:
755 case kWaitingForAsyncLoadCompletion:
756 CHECK(false);
757 break;
694 } 758 }
695 759
696 return page_ ? kSizeAvailable : kSizeUnavailable; 760 NOTREACHED();
761 return kSizeAvailable;
697 } 762 }
698 763
699 String SVGImage::FilenameExtension() const { 764 String SVGImage::FilenameExtension() const {
700 return "svg"; 765 return "svg";
701 } 766 }
702 767
703 } // namespace blink 768 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/svg/graphics/SVGImage.h ('k') | third_party/WebKit/Source/core/svg/graphics/SVGImageTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698