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

Side by Side Diff: third_party/WebKit/Source/core/loader/ImageLoader.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) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights 4 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights
5 * reserved. 5 * reserved.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 170
171 void ImageLoader::Dispose() { 171 void ImageLoader::Dispose() {
172 RESOURCE_LOADING_DVLOG(1) 172 RESOURCE_LOADING_DVLOG(1)
173 << "~ImageLoader " << this 173 << "~ImageLoader " << this
174 << "; m_hasPendingLoadEvent=" << has_pending_load_event_ 174 << "; m_hasPendingLoadEvent=" << has_pending_load_event_
175 << ", m_hasPendingErrorEvent=" << has_pending_error_event_; 175 << ", m_hasPendingErrorEvent=" << has_pending_error_event_;
176 176
177 if (image_) { 177 if (image_) {
178 image_->RemoveObserver(this); 178 image_->RemoveObserver(this);
179 image_ = nullptr; 179 image_ = nullptr;
180 delay_until_image_notify_finished_ = nullptr;
180 } 181 }
181 } 182 }
182 183
183 DEFINE_TRACE(ImageLoader) { 184 DEFINE_TRACE(ImageLoader) {
184 visitor->Trace(image_); 185 visitor->Trace(image_);
185 visitor->Trace(image_resource_for_image_document_); 186 visitor->Trace(image_resource_for_image_document_);
186 visitor->Trace(element_); 187 visitor->Trace(element_);
187 } 188 }
188 189
189 void ImageLoader::SetImage(ImageResourceContent* new_image) { 190 void ImageLoader::SetImage(ImageResourceContent* new_image) {
190 SetImageWithoutConsideringPendingLoadEvent(new_image); 191 SetImageWithoutConsideringPendingLoadEvent(new_image);
191 192
192 // Only consider updating the protection ref-count of the Element immediately 193 // Only consider updating the protection ref-count of the Element immediately
193 // before returning from this function as doing so might result in the 194 // before returning from this function as doing so might result in the
194 // destruction of this ImageLoader. 195 // destruction of this ImageLoader.
195 UpdatedHasPendingEvent(); 196 UpdatedHasPendingEvent();
196 } 197 }
197 198
198 void ImageLoader::SetImageWithoutConsideringPendingLoadEvent( 199 void ImageLoader::SetImageWithoutConsideringPendingLoadEvent(
199 ImageResourceContent* new_image) { 200 ImageResourceContent* new_image) {
200 DCHECK(failed_load_url_.IsEmpty()); 201 DCHECK(failed_load_url_.IsEmpty());
201 ImageResourceContent* old_image = image_.Get(); 202 ImageResourceContent* old_image = image_.Get();
202 if (new_image != old_image) { 203 if (new_image != old_image) {
203 image_ = new_image; 204 image_ = new_image;
205 delay_until_image_notify_finished_ = nullptr;
fs 2017/05/05 10:52:42 Clearing this is tied either to a change to |compl
hiroshige 2017/05/08 17:22:06 Also when |image_| is changed (to non-null), like
fs 2017/05/08 18:52:33 Acknowledged.
hiroshige 2017/05/09 00:46:31 I found another issue that motivates me to introdu
204 if (has_pending_load_event_) { 206 if (has_pending_load_event_) {
205 LoadEventSender().CancelEvent(this); 207 LoadEventSender().CancelEvent(this);
206 has_pending_load_event_ = false; 208 has_pending_load_event_ = false;
207 } 209 }
208 if (has_pending_error_event_) { 210 if (has_pending_error_event_) {
209 ErrorEventSender().CancelEvent(this); 211 ErrorEventSender().CancelEvent(this);
210 has_pending_error_event_ = false; 212 has_pending_error_event_ = false;
211 } 213 }
212 image_complete_ = true; 214 image_complete_ = true;
213 if (new_image) { 215 if (new_image) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 } 259 }
258 260
259 inline void ImageLoader::EnqueueImageLoadingMicroTask( 261 inline void ImageLoader::EnqueueImageLoadingMicroTask(
260 UpdateFromElementBehavior update_behavior, 262 UpdateFromElementBehavior update_behavior,
261 ReferrerPolicy referrer_policy) { 263 ReferrerPolicy referrer_policy) {
262 std::unique_ptr<Task> task = 264 std::unique_ptr<Task> task =
263 Task::Create(this, update_behavior, referrer_policy); 265 Task::Create(this, update_behavior, referrer_policy);
264 pending_task_ = task->CreateWeakPtr(); 266 pending_task_ = task->CreateWeakPtr();
265 Microtask::EnqueueMicrotask( 267 Microtask::EnqueueMicrotask(
266 WTF::Bind(&Task::Run, WTF::Passed(std::move(task)))); 268 WTF::Bind(&Task::Run, WTF::Passed(std::move(task))));
267 load_delay_counter_ = 269 delay_until_do_update_from_element_ =
268 IncrementLoadEventDelayCount::Create(element_->GetDocument()); 270 IncrementLoadEventDelayCount::Create(element_->GetDocument());
269 } 271 }
270 272
271 void ImageLoader::DoUpdateFromElement(BypassMainWorldBehavior bypass_behavior, 273 void ImageLoader::DoUpdateFromElement(BypassMainWorldBehavior bypass_behavior,
272 UpdateFromElementBehavior update_behavior, 274 UpdateFromElementBehavior update_behavior,
273 const KURL& url, 275 const KURL& url,
274 ReferrerPolicy referrer_policy) { 276 ReferrerPolicy referrer_policy) {
275 // FIXME: According to 277 // FIXME: According to
276 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-conten t.html#the-img-element:the-img-element-55 278 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-conten t.html#the-img-element:the-img-element-55
277 // When "update image" is called due to environment changes and the load 279 // When "update image" is called due to environment changes and the load
278 // fails, onerror should not be called. That is currently not the case. 280 // fails, onerror should not be called. That is currently not the case.
279 // 281 //
280 // We don't need to call clearLoader here: Either we were called from the 282 // We don't need to call clearLoader here: Either we were called from the
281 // task, or our caller updateFromElement cleared the task's loader (and set 283 // task, or our caller updateFromElement cleared the task's loader (and set
282 // m_pendingTask to null). 284 // m_pendingTask to null).
283 pending_task_.reset(); 285 pending_task_.reset();
284 // Make sure to only decrement the count when we exit this function 286 // Make sure to only decrement the count when we exit this function
285 std::unique_ptr<IncrementLoadEventDelayCount> load_delay_counter; 287 std::unique_ptr<IncrementLoadEventDelayCount> load_delay_counter;
286 load_delay_counter.swap(load_delay_counter_); 288 load_delay_counter.swap(delay_until_do_update_from_element_);
287 289
288 Document& document = element_->GetDocument(); 290 Document& document = element_->GetDocument();
289 if (!document.IsActive()) 291 if (!document.IsActive())
290 return; 292 return;
291 293
292 AtomicString image_source_url = element_->ImageSourceURL(); 294 AtomicString image_source_url = element_->ImageSourceURL();
293 ImageResourceContent* new_image = nullptr; 295 ImageResourceContent* new_image = nullptr;
294 if (!url.IsNull()) { 296 if (!url.IsNull()) {
295 // Unlike raw <img>, we block mixed content inside of <picture> or 297 // Unlike raw <img>, we block mixed content inside of <picture> or
296 // <img srcset>. 298 // <img srcset>.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 // FIXME: If both previous load and this one got blocked with an error, we 354 // FIXME: If both previous load and this one got blocked with an error, we
353 // can receive one error event instead of two. 355 // can receive one error event instead of two.
354 if (has_pending_error_event_ && new_image) { 356 if (has_pending_error_event_ && new_image) {
355 ErrorEventSender().CancelEvent(this); 357 ErrorEventSender().CancelEvent(this);
356 has_pending_error_event_ = false; 358 has_pending_error_event_ = false;
357 } 359 }
358 360
359 image_ = new_image; 361 image_ = new_image;
360 has_pending_load_event_ = new_image; 362 has_pending_load_event_ = new_image;
361 image_complete_ = !new_image; 363 image_complete_ = !new_image;
364 delay_until_image_notify_finished_ = nullptr;
362 365
363 UpdateLayoutObject(); 366 UpdateLayoutObject();
364 // If newImage exists and is cached, addObserver() will result in the load 367 // If newImage exists and is cached, addObserver() will result in the load
365 // event being queued to fire. Ensure this happens after beforeload is 368 // event being queued to fire. Ensure this happens after beforeload is
366 // dispatched. 369 // dispatched.
367 if (new_image) { 370 if (new_image) {
368 new_image->AddObserver(this); 371 new_image->AddObserver(this);
369 } 372 }
370 if (old_image) { 373 if (old_image) {
371 old_image->RemoveObserver(this); 374 old_image->RemoveObserver(this);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 return; 424 return;
422 } 425 }
423 // Allow the idiom "img.src=''; img.src='.." to clear down the image before an 426 // Allow the idiom "img.src=''; img.src='.." to clear down the image before an
424 // asynchronous load completes. 427 // asynchronous load completes.
425 if (image_source_url.IsEmpty()) { 428 if (image_source_url.IsEmpty()) {
426 ImageResourceContent* image = image_.Get(); 429 ImageResourceContent* image = image_.Get();
427 if (image) { 430 if (image) {
428 image->RemoveObserver(this); 431 image->RemoveObserver(this);
429 } 432 }
430 image_ = nullptr; 433 image_ = nullptr;
434 delay_until_image_notify_finished_ = nullptr;
431 } 435 }
432 436
433 // Don't load images for inactive documents. We don't want to slow down the 437 // Don't load images for inactive documents. We don't want to slow down the
434 // raw HTML parsing case by loading images we don't intend to display. 438 // raw HTML parsing case by loading images we don't intend to display.
435 Document& document = element_->GetDocument(); 439 Document& document = element_->GetDocument();
436 if (document.IsActive()) 440 if (document.IsActive())
437 EnqueueImageLoadingMicroTask(update_behavior, referrer_policy); 441 EnqueueImageLoadingMicroTask(update_behavior, referrer_policy);
438 } 442 }
439 443
440 KURL ImageLoader::ImageSourceToKURL(AtomicString image_source_url) const { 444 KURL ImageLoader::ImageSourceToKURL(AtomicString image_source_url) const {
(...skipping 22 matching lines...) Expand all
463 // content when style recalc is over and DOM mutation is allowed again. 467 // content when style recalc is over and DOM mutation is allowed again.
464 if (!url.IsNull()) { 468 if (!url.IsNull()) {
465 Resource* resource = GetMemoryCache()->ResourceForURL( 469 Resource* resource = GetMemoryCache()->ResourceForURL(
466 url, element_->GetDocument().Fetcher()->GetCacheIdentifier()); 470 url, element_->GetDocument().Fetcher()->GetCacheIdentifier());
467 if (resource && !resource->ErrorOccurred()) 471 if (resource && !resource->ErrorOccurred())
468 return true; 472 return true;
469 } 473 }
470 return (isHTMLObjectElement(element_) || isHTMLEmbedElement(element_)); 474 return (isHTMLObjectElement(element_) || isHTMLEmbedElement(element_));
471 } 475 }
472 476
477 void ImageLoader::ImageChanged(ImageResourceContent* content, const IntRect*) {
478 DCHECK_EQ(content, image_.Get());
479 if (image_complete_ || !content->IsLoading() ||
480 delay_until_image_notify_finished_)
481 return;
482
483 Document& document = element_->GetDocument();
484 if (!document.IsActive())
485 return;
486
487 delay_until_image_notify_finished_ =
488 IncrementLoadEventDelayCount::Create(document);
489 }
490
473 void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) { 491 void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) {
474 RESOURCE_LOADING_DVLOG(1) 492 RESOURCE_LOADING_DVLOG(1)
475 << "ImageLoader::imageNotifyFinished " << this 493 << "ImageLoader::imageNotifyFinished " << this
476 << "; m_hasPendingLoadEvent=" << has_pending_load_event_; 494 << "; m_hasPendingLoadEvent=" << has_pending_load_event_;
477 495
478 DCHECK(failed_load_url_.IsEmpty()); 496 DCHECK(failed_load_url_.IsEmpty());
479 DCHECK_EQ(resource, image_.Get()); 497 DCHECK_EQ(resource, image_.Get());
480 498
481 image_complete_ = true; 499 image_complete_ = true;
500 delay_until_image_notify_finished_ = nullptr;
482 501
483 // Update ImageAnimationPolicy for m_image. 502 // Update ImageAnimationPolicy for m_image.
484 if (image_) 503 if (image_)
485 image_->UpdateImageAnimationPolicy(); 504 image_->UpdateImageAnimationPolicy();
486 505
487 UpdateLayoutObject(); 506 UpdateLayoutObject();
488 507
489 if (image_ && image_->GetImage() && image_->GetImage()->IsSVGImage()) 508 if (image_ && image_->GetImage() && image_->GetImage()->IsSVGImage())
490 ToSVGImage(image_->GetImage()) 509 ToSVGImage(image_->GetImage())
491 ->UpdateUseCounters(GetElement()->GetDocument()); 510 ->UpdateUseCounters(GetElement()->GetDocument());
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 648
630 void ImageLoader::DispatchPendingLoadEvents() { 649 void ImageLoader::DispatchPendingLoadEvents() {
631 LoadEventSender().DispatchPendingEvents(); 650 LoadEventSender().DispatchPendingEvents();
632 } 651 }
633 652
634 void ImageLoader::DispatchPendingErrorEvents() { 653 void ImageLoader::DispatchPendingErrorEvents() {
635 ErrorEventSender().DispatchPendingEvents(); 654 ErrorEventSender().DispatchPendingEvents();
636 } 655 }
637 656
638 void ImageLoader::ElementDidMoveToNewDocument() { 657 void ImageLoader::ElementDidMoveToNewDocument() {
639 if (load_delay_counter_) 658 if (delay_until_do_update_from_element_) {
640 load_delay_counter_->DocumentChanged(element_->GetDocument()); 659 delay_until_do_update_from_element_->DocumentChanged(
660 element_->GetDocument());
661 }
662 if (delay_until_image_notify_finished_) {
663 delay_until_image_notify_finished_->DocumentChanged(
664 element_->GetDocument());
665 }
641 ClearFailedLoadURL(); 666 ClearFailedLoadURL();
642 SetImage(0); 667 SetImage(0);
643 } 668 }
644 669
645 } // namespace blink 670 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698