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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
index a57d2f7ce6434ef5f6b226d2b4a847ed5ff1232b..35e54032a3cd22a73d00f493909c0cf159fcce23 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
@@ -68,7 +68,8 @@ namespace blink {
SVGImage::SVGImage(ImageObserver* observer)
: Image(observer),
paint_controller_(PaintController::Create()),
- has_pending_timeline_rewind_(false) {}
+ has_pending_timeline_rewind_(false),
+ weak_ptr_factory_(this) {}
SVGImage::~SVGImage() {
if (page_) {
@@ -605,6 +606,43 @@ void SVGImage::UpdateUseCounters(const Document& document) const {
}
}
+// SVGImageLocalFrameClient is used to wait until SVG document's load event
+// in the case where there are subresources asynchronously loaded.
+class SVGImage::SVGImageLocalFrameClient : public EmptyLocalFrameClient {
+ public:
+ SVGImageLocalFrameClient(WeakPtr<SVGImage> image) : image_(image) {}
+
+ private:
+ void DispatchDidHandleOnloadEvents() override {
+ // The SVGImage is destructed before SVG load completion.
fs 2017/05/05 10:52:42 Nit: s/is/was/
hiroshige 2017/05/08 17:22:06 Done.
+ if (!image_)
+ return;
+
+ image_->LoadCompleted();
+ }
+ WeakPtr<SVGImage> image_;
+};
+
+void SVGImage::LoadCompleted() {
+ switch (load_state_) {
+ case kInDataChanged:
+ load_state_ = kLoadCompletedSynchronously;
+ break;
+
+ case kWaitingForAsyncLoadCompletion:
+ load_state_ = kLoadCompletedAsynchronously;
+ if (GetImageObserver())
+ GetImageObserver()->LoadCompleted(this);
+ break;
+
+ case kDataChangedNotStarted:
+ case kLoadCompletedSynchronously:
+ case kLoadCompletedAsynchronously:
+ CHECK(false);
+ break;
+ }
+}
+
Image::SizeAvailability SVGImage::DataChanged(bool all_data_received) {
TRACE_EVENT0("blink", "SVGImage::dataChanged");
@@ -612,60 +650,63 @@ Image::SizeAvailability SVGImage::DataChanged(bool all_data_received) {
if (!Data()->size())
return kSizeAvailable;
- if (all_data_received) {
- // SVGImage will fire events (and the default C++ handlers run) but doesn't
- // actually allow script to run so it's fine to call into it. We allow this
- // since it means an SVG data url can synchronously load like other image
- // types.
- EventDispatchForbiddenScope::AllowUserAgentEvents allow_user_agent_events;
-
- DEFINE_STATIC_LOCAL(LocalFrameClient, dummy_local_frame_client,
- (EmptyLocalFrameClient::Create()));
-
- CHECK(!page_);
-
- Page::PageClients page_clients;
- FillWithEmptyClients(page_clients);
- chrome_client_ = SVGImageChromeClient::Create(this);
- page_clients.chrome_client = chrome_client_.Get();
-
- // FIXME: If this SVG ends up loading itself, we might leak the world.
- // The Cache code does not know about ImageResources holding Frames and
- // won't know to break the cycle.
- // This will become an issue when SVGImage will be able to load other
- // SVGImage objects, but we're safe now, because SVGImage can only be
- // loaded by a top-level document.
- Page* page;
- {
- TRACE_EVENT0("blink", "SVGImage::dataChanged::createPage");
- page = Page::Create(page_clients);
- page->GetSettings().SetScriptEnabled(false);
- page->GetSettings().SetPluginsEnabled(false);
- page->GetSettings().SetAcceleratedCompositingEnabled(false);
-
- // Because this page is detached, it can't get default font settings
- // from the embedder. Copy over font settings so we have sensible
- // defaults. These settings are fixed and will not update if changed.
- if (!Page::OrdinaryPages().IsEmpty()) {
- Settings& default_settings =
- (*Page::OrdinaryPages().begin())->GetSettings();
- page->GetSettings().GetGenericFontFamilySettings() =
- default_settings.GetGenericFontFamilySettings();
- page->GetSettings().SetMinimumFontSize(
- default_settings.GetMinimumFontSize());
- page->GetSettings().SetMinimumLogicalFontSize(
- default_settings.GetMinimumLogicalFontSize());
- page->GetSettings().SetDefaultFontSize(
- default_settings.GetDefaultFontSize());
- page->GetSettings().SetDefaultFixedFontSize(
- default_settings.GetDefaultFixedFontSize());
- }
+ if (!all_data_received)
+ return page_ ? kSizeAvailable : kSizeUnavailable;
+
+ CHECK(!page_);
+
+ // SVGImage will fire events (and the default C++ handlers run) but doesn't
+ // actually allow script to run so it's fine to call into it. We allow this
+ // since it means an SVG data url can synchronously load like other image
+ // types.
+ EventDispatchForbiddenScope::AllowUserAgentEvents allow_user_agent_events;
+
+ CHECK_EQ(load_state_, kDataChangedNotStarted);
+ load_state_ = kInDataChanged;
+
+ Page::PageClients page_clients;
+ FillWithEmptyClients(page_clients);
+ chrome_client_ = SVGImageChromeClient::Create(this);
+ page_clients.chrome_client = chrome_client_.Get();
+
+ // FIXME: If this SVG ends up loading itself, we might leak the world.
+ // The Cache code does not know about ImageResources holding Frames and
+ // won't know to break the cycle.
+ // This will become an issue when SVGImage will be able to load other
+ // SVGImage objects, but we're safe now, because SVGImage can only be
+ // loaded by a top-level document.
+ Page* page;
+ {
+ TRACE_EVENT0("blink", "SVGImage::dataChanged::createPage");
+ page = Page::Create(page_clients);
+ page->GetSettings().SetScriptEnabled(false);
+ page->GetSettings().SetPluginsEnabled(false);
+ page->GetSettings().SetAcceleratedCompositingEnabled(false);
+
+ // Because this page is detached, it can't get default font settings
+ // from the embedder. Copy over font settings so we have sensible
+ // defaults. These settings are fixed and will not update if changed.
+ if (!Page::OrdinaryPages().IsEmpty()) {
+ Settings& default_settings =
+ (*Page::OrdinaryPages().begin())->GetSettings();
+ page->GetSettings().GetGenericFontFamilySettings() =
+ default_settings.GetGenericFontFamilySettings();
+ page->GetSettings().SetMinimumFontSize(
+ default_settings.GetMinimumFontSize());
+ page->GetSettings().SetMinimumLogicalFontSize(
+ default_settings.GetMinimumLogicalFontSize());
+ page->GetSettings().SetDefaultFontSize(
+ default_settings.GetDefaultFontSize());
+ page->GetSettings().SetDefaultFixedFontSize(
+ default_settings.GetDefaultFixedFontSize());
+ }
}
LocalFrame* frame = nullptr;
{
TRACE_EVENT0("blink", "SVGImage::dataChanged::createFrame");
- frame = LocalFrame::Create(&dummy_local_frame_client, *page, 0);
+ frame = LocalFrame::Create(
+ new SVGImageLocalFrameClient(this->AsWeakPtr()), *page, 0);
frame->SetView(FrameView::Create(*frame));
frame->Init();
}
@@ -691,9 +732,25 @@ Image::SizeAvailability SVGImage::DataChanged(bool all_data_received) {
// Set the concrete object size before a container size is available.
intrinsic_size_ = RoundedIntSize(ConcreteObjectSize(FloatSize(
LayoutReplaced::kDefaultWidth, LayoutReplaced::kDefaultHeight)));
+
+ DCHECK(page_);
+ switch (load_state_) {
+ case kInDataChanged:
+ load_state_ = kWaitingForAsyncLoadCompletion;
+ return kSizeAvailableAndLoadingAsynchronously;
+
+ case kLoadCompletedSynchronously:
+ return kSizeAvailable;
+
+ case kDataChangedNotStarted:
+ case kWaitingForAsyncLoadCompletion:
+ case kLoadCompletedAsynchronously:
+ CHECK(false);
+ break;
}
- return page_ ? kSizeAvailable : kSizeUnavailable;
+ NOTREACHED();
+ return kSizeAvailable;
}
String SVGImage::FilenameExtension() const {

Powered by Google App Engine
This is Rietveld 408576698