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; |
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 |