Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |