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 11 matching lines...) Expand all Loading... |
22 | 22 |
23 #include "core/loader/ImageLoader.h" | 23 #include "core/loader/ImageLoader.h" |
24 | 24 |
25 #include <memory> | 25 #include <memory> |
26 #include "bindings/core/v8/ScriptController.h" | 26 #include "bindings/core/v8/ScriptController.h" |
27 #include "bindings/core/v8/V8BindingForCore.h" | 27 #include "bindings/core/v8/V8BindingForCore.h" |
28 #include "core/dom/Document.h" | 28 #include "core/dom/Document.h" |
29 #include "core/dom/Element.h" | 29 #include "core/dom/Element.h" |
30 #include "core/dom/IncrementLoadEventDelayCount.h" | 30 #include "core/dom/IncrementLoadEventDelayCount.h" |
31 #include "core/events/Event.h" | 31 #include "core/events/Event.h" |
32 #include "core/events/EventSender.h" | |
33 #include "core/frame/LocalFrame.h" | 32 #include "core/frame/LocalFrame.h" |
34 #include "core/frame/Settings.h" | 33 #include "core/frame/Settings.h" |
35 #include "core/frame/UseCounter.h" | 34 #include "core/frame/UseCounter.h" |
36 #include "core/html/CrossOriginAttribute.h" | 35 #include "core/html/CrossOriginAttribute.h" |
37 #include "core/html/HTMLImageElement.h" | 36 #include "core/html/HTMLImageElement.h" |
38 #include "core/html/parser/HTMLParserIdioms.h" | 37 #include "core/html/parser/HTMLParserIdioms.h" |
39 #include "core/layout/LayoutImage.h" | 38 #include "core/layout/LayoutImage.h" |
40 #include "core/layout/LayoutVideo.h" | 39 #include "core/layout/LayoutVideo.h" |
41 #include "core/layout/svg/LayoutSVGImage.h" | 40 #include "core/layout/svg/LayoutSVGImage.h" |
42 #include "core/probe/CoreProbes.h" | 41 #include "core/probe/CoreProbes.h" |
43 #include "core/svg/graphics/SVGImage.h" | 42 #include "core/svg/graphics/SVGImage.h" |
44 #include "platform/bindings/Microtask.h" | 43 #include "platform/bindings/Microtask.h" |
45 #include "platform/bindings/ScriptState.h" | 44 #include "platform/bindings/ScriptState.h" |
46 #include "platform/bindings/V8PerIsolateData.h" | 45 #include "platform/bindings/V8PerIsolateData.h" |
47 #include "platform/loader/fetch/FetchParameters.h" | 46 #include "platform/loader/fetch/FetchParameters.h" |
48 #include "platform/loader/fetch/MemoryCache.h" | 47 #include "platform/loader/fetch/MemoryCache.h" |
49 #include "platform/loader/fetch/ResourceFetcher.h" | 48 #include "platform/loader/fetch/ResourceFetcher.h" |
50 #include "platform/loader/fetch/ResourceLoadingLog.h" | 49 #include "platform/loader/fetch/ResourceLoadingLog.h" |
51 #include "platform/weborigin/SecurityOrigin.h" | 50 #include "platform/weborigin/SecurityOrigin.h" |
52 #include "platform/weborigin/SecurityPolicy.h" | 51 #include "platform/weborigin/SecurityPolicy.h" |
53 #include "platform/wtf/PtrUtil.h" | 52 #include "platform/wtf/PtrUtil.h" |
54 #include "public/platform/WebCachePolicy.h" | 53 #include "public/platform/WebCachePolicy.h" |
55 #include "public/platform/WebURLRequest.h" | 54 #include "public/platform/WebURLRequest.h" |
56 | 55 |
57 namespace blink { | 56 namespace blink { |
58 | 57 |
59 static ImageEventSender& LoadEventSender() { | |
60 DEFINE_STATIC_LOCAL(ImageEventSender, sender, | |
61 (ImageEventSender::Create(EventTypeNames::load))); | |
62 return sender; | |
63 } | |
64 | |
65 static ImageEventSender& ErrorEventSender() { | |
66 DEFINE_STATIC_LOCAL(ImageEventSender, sender, | |
67 (ImageEventSender::Create(EventTypeNames::error))); | |
68 return sender; | |
69 } | |
70 | |
71 static inline bool PageIsBeingDismissed(Document* document) { | 58 static inline bool PageIsBeingDismissed(Document* document) { |
72 return document->PageDismissalEventBeingDispatched() != | 59 return document->PageDismissalEventBeingDispatched() != |
73 Document::kNoDismissal; | 60 Document::kNoDismissal; |
74 } | 61 } |
75 | 62 |
76 static ImageLoader::BypassMainWorldBehavior ShouldBypassMainWorldCSP( | 63 static ImageLoader::BypassMainWorldBehavior ShouldBypassMainWorldCSP( |
77 ImageLoader* loader) { | 64 ImageLoader* loader) { |
78 DCHECK(loader); | 65 DCHECK(loader); |
79 DCHECK(loader->GetElement()); | 66 DCHECK(loader->GetElement()); |
80 if (loader->GetElement()->GetDocument().GetFrame() && | 67 if (loader->GetElement()->GetDocument().GetFrame() && |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 BypassMainWorldBehavior should_bypass_main_world_csp_; | 136 BypassMainWorldBehavior should_bypass_main_world_csp_; |
150 UpdateFromElementBehavior update_behavior_; | 137 UpdateFromElementBehavior update_behavior_; |
151 RefPtr<ScriptState> script_state_; | 138 RefPtr<ScriptState> script_state_; |
152 WeakPtrFactory<Task> weak_factory_; | 139 WeakPtrFactory<Task> weak_factory_; |
153 ReferrerPolicy referrer_policy_; | 140 ReferrerPolicy referrer_policy_; |
154 KURL request_url_; | 141 KURL request_url_; |
155 }; | 142 }; |
156 | 143 |
157 ImageLoader::ImageLoader(Element* element) | 144 ImageLoader::ImageLoader(Element* element) |
158 : element_(element), | 145 : element_(element), |
159 has_pending_load_event_(false), | |
160 has_pending_error_event_(false), | |
161 image_complete_(true), | 146 image_complete_(true), |
162 loading_image_document_(false), | 147 loading_image_document_(false), |
163 suppress_error_events_(false) { | 148 suppress_error_events_(false) { |
164 RESOURCE_LOADING_DVLOG(1) << "new ImageLoader " << this; | 149 RESOURCE_LOADING_DVLOG(1) << "new ImageLoader " << this; |
165 } | 150 } |
166 | 151 |
167 ImageLoader::~ImageLoader() {} | 152 ImageLoader::~ImageLoader() {} |
168 | 153 |
169 void ImageLoader::Dispose() { | 154 void ImageLoader::Dispose() { |
170 RESOURCE_LOADING_DVLOG(1) | 155 RESOURCE_LOADING_DVLOG(1) |
171 << "~ImageLoader " << this | 156 << "~ImageLoader " << this |
172 << "; has_pending_load_event_=" << has_pending_load_event_ | 157 << "; has pending load event=" << pending_load_event_.IsActive() |
173 << ", has_pending_error_event_=" << has_pending_error_event_; | 158 << ", has pending error event=" << pending_error_event_.IsActive(); |
174 | 159 |
175 if (image_) { | 160 if (image_) { |
176 image_->RemoveObserver(this); | 161 image_->RemoveObserver(this); |
177 image_ = nullptr; | 162 image_ = nullptr; |
178 delay_until_image_notify_finished_ = nullptr; | 163 delay_until_image_notify_finished_ = nullptr; |
179 } | 164 } |
180 } | 165 } |
181 | 166 |
182 DEFINE_TRACE(ImageLoader) { | 167 DEFINE_TRACE(ImageLoader) { |
183 visitor->Trace(image_); | 168 visitor->Trace(image_); |
(...skipping 22 matching lines...) Expand all Loading... |
206 // loading is just started. | 191 // loading is just started. |
207 // TODO(hiroshige): clean up the behavior of flags. https://crbug.com/719759 | 192 // TODO(hiroshige): clean up the behavior of flags. https://crbug.com/719759 |
208 image_complete_ = true; | 193 image_complete_ = true; |
209 } | 194 } |
210 | 195 |
211 void ImageLoader::SetImageWithoutConsideringPendingLoadEvent( | 196 void ImageLoader::SetImageWithoutConsideringPendingLoadEvent( |
212 ImageResourceContent* new_image) { | 197 ImageResourceContent* new_image) { |
213 DCHECK(failed_load_url_.IsEmpty()); | 198 DCHECK(failed_load_url_.IsEmpty()); |
214 ImageResourceContent* old_image = image_.Get(); | 199 ImageResourceContent* old_image = image_.Get(); |
215 if (new_image != old_image) { | 200 if (new_image != old_image) { |
216 if (has_pending_load_event_) { | 201 if (pending_load_event_.IsActive()) |
217 LoadEventSender().CancelEvent(this); | 202 pending_load_event_.Cancel(); |
218 has_pending_load_event_ = false; | 203 if (pending_error_event_.IsActive()) |
219 } | 204 pending_error_event_.Cancel(); |
220 if (has_pending_error_event_) { | |
221 ErrorEventSender().CancelEvent(this); | |
222 has_pending_error_event_ = false; | |
223 } | |
224 UpdateImageState(new_image); | 205 UpdateImageState(new_image); |
225 if (new_image) { | 206 if (new_image) { |
226 new_image->AddObserver(this); | 207 new_image->AddObserver(this); |
227 } | 208 } |
228 if (old_image) { | 209 if (old_image) { |
229 old_image->RemoveObserver(this); | 210 old_image->RemoveObserver(this); |
230 } | 211 } |
231 } | 212 } |
232 | 213 |
233 if (LayoutImageResource* image_resource = GetLayoutImageResource()) | 214 if (LayoutImageResource* image_resource = GetLayoutImageResource()) |
(...skipping 16 matching lines...) Expand all Loading... |
250 } | 231 } |
251 | 232 |
252 if (client_hints_preferences.ShouldSendResourceWidth() && | 233 if (client_hints_preferences.ShouldSendResourceWidth() && |
253 isHTMLImageElement(element)) | 234 isHTMLImageElement(element)) |
254 params.SetResourceWidth(toHTMLImageElement(element).GetResourceWidth()); | 235 params.SetResourceWidth(toHTMLImageElement(element).GetResourceWidth()); |
255 } | 236 } |
256 | 237 |
257 inline void ImageLoader::DispatchErrorEvent() { | 238 inline void ImageLoader::DispatchErrorEvent() { |
258 // There can be cases where DispatchErrorEvent() is called when there is | 239 // There can be cases where DispatchErrorEvent() is called when there is |
259 // already a scheduled error event for the previous load attempt. | 240 // already a scheduled error event for the previous load attempt. |
260 // In such cases we cancel the previous event and then re-schedule a new | 241 // In such cases we cancel the previous event (by overwriting |
261 // error event here. crbug.com/722500 | 242 // |pending_error_event_|) and then re-schedule a new error event here. |
262 if (has_pending_error_event_) | 243 // crbug.com/722500 |
263 ErrorEventSender().CancelEvent(this); | 244 pending_error_event_ = |
264 | 245 TaskRunnerHelper::Get(TaskType::kDOMManipulation, |
265 has_pending_error_event_ = true; | 246 &GetElement()->GetDocument()) |
266 ErrorEventSender().DispatchEventSoon(this); | 247 ->PostCancellableTask( |
| 248 BLINK_FROM_HERE, |
| 249 WTF::Bind(&ImageLoader::DispatchPendingErrorEvent, |
| 250 WrapPersistent(this), |
| 251 WTF::Passed(IncrementLoadEventDelayCount::Create( |
| 252 GetElement()->GetDocument())))); |
267 } | 253 } |
268 | 254 |
269 inline void ImageLoader::CrossSiteOrCSPViolationOccurred( | 255 inline void ImageLoader::CrossSiteOrCSPViolationOccurred( |
270 AtomicString image_source_url) { | 256 AtomicString image_source_url) { |
271 failed_load_url_ = image_source_url; | 257 failed_load_url_ = image_source_url; |
272 } | 258 } |
273 | 259 |
274 inline void ImageLoader::ClearFailedLoadURL() { | 260 inline void ImageLoader::ClearFailedLoadURL() { |
275 failed_load_url_ = AtomicString(); | 261 failed_load_url_ = AtomicString(); |
276 } | 262 } |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 DispatchErrorEvent(); | 344 DispatchErrorEvent(); |
359 } | 345 } |
360 NoImageResourceToLoad(); | 346 NoImageResourceToLoad(); |
361 } | 347 } |
362 | 348 |
363 ImageResourceContent* old_image = image_.Get(); | 349 ImageResourceContent* old_image = image_.Get(); |
364 if (update_behavior == kUpdateSizeChanged && element_->GetLayoutObject() && | 350 if (update_behavior == kUpdateSizeChanged && element_->GetLayoutObject() && |
365 element_->GetLayoutObject()->IsImage() && new_image == old_image) { | 351 element_->GetLayoutObject()->IsImage() && new_image == old_image) { |
366 ToLayoutImage(element_->GetLayoutObject())->IntrinsicSizeChanged(); | 352 ToLayoutImage(element_->GetLayoutObject())->IntrinsicSizeChanged(); |
367 } else { | 353 } else { |
368 if (has_pending_load_event_) { | 354 if (pending_load_event_.IsActive()) |
369 LoadEventSender().CancelEvent(this); | 355 pending_load_event_.Cancel(); |
370 has_pending_load_event_ = false; | |
371 } | |
372 | 356 |
373 // Cancel error events that belong to the previous load, which is now | 357 // Cancel error events that belong to the previous load, which is now |
374 // cancelled by changing the src attribute. If newImage is null and | 358 // cancelled by changing the src attribute. If newImage is null and |
375 // has_pending_error_event_ is true, we know the error event has been just | 359 // has_pending_error_event_ is true, we know the error event has been just |
376 // posted by this load and we should not cancel the event. | 360 // posted by this load and we should not cancel the event. |
377 // FIXME: If both previous load and this one got blocked with an error, we | 361 // FIXME: If both previous load and this one got blocked with an error, we |
378 // can receive one error event instead of two. | 362 // can receive one error event instead of two. |
379 if (has_pending_error_event_ && new_image) { | 363 if (pending_error_event_.IsActive() && new_image) |
380 ErrorEventSender().CancelEvent(this); | 364 pending_error_event_.Cancel(); |
381 has_pending_error_event_ = false; | |
382 } | |
383 | 365 |
384 UpdateImageState(new_image); | 366 UpdateImageState(new_image); |
385 | 367 |
386 UpdateLayoutObject(); | 368 UpdateLayoutObject(); |
387 // If newImage exists and is cached, addObserver() will result in the load | 369 // If newImage exists and is cached, addObserver() will result in the load |
388 // event being queued to fire. Ensure this happens after beforeload is | 370 // event being queued to fire. Ensure this happens after beforeload is |
389 // dispatched. | 371 // dispatched. |
390 if (new_image) { | 372 if (new_image) { |
391 new_image->AddObserver(this); | 373 new_image->AddObserver(this); |
392 } | 374 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 if (!document.IsActive()) | 489 if (!document.IsActive()) |
508 return; | 490 return; |
509 | 491 |
510 delay_until_image_notify_finished_ = | 492 delay_until_image_notify_finished_ = |
511 IncrementLoadEventDelayCount::Create(document); | 493 IncrementLoadEventDelayCount::Create(document); |
512 } | 494 } |
513 | 495 |
514 void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) { | 496 void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) { |
515 RESOURCE_LOADING_DVLOG(1) | 497 RESOURCE_LOADING_DVLOG(1) |
516 << "ImageLoader::imageNotifyFinished " << this | 498 << "ImageLoader::imageNotifyFinished " << this |
517 << "; has_pending_load_event_=" << has_pending_load_event_; | 499 << "; has pending load event=" << pending_load_event_.IsActive(); |
518 | 500 |
519 DCHECK(failed_load_url_.IsEmpty()); | 501 DCHECK(failed_load_url_.IsEmpty()); |
520 DCHECK_EQ(resource, image_.Get()); | 502 DCHECK_EQ(resource, image_.Get()); |
521 | 503 |
522 // |image_complete_| is always true for entire ImageDocument loading for | 504 // |image_complete_| is always true for entire ImageDocument loading for |
523 // historical reason. | 505 // historical reason. |
524 // DoUpdateFromElement() is not called and SetImageForImageDocument() | 506 // DoUpdateFromElement() is not called and SetImageForImageDocument() |
525 // is called instead for ImageDocument loading. | 507 // is called instead for ImageDocument loading. |
526 // TODO(hiroshige): Turn the CHECK()s to DCHECK()s before going to beta. | 508 // TODO(hiroshige): Turn the CHECK()s to DCHECK()s before going to beta. |
527 if (loading_image_document_) | 509 if (loading_image_document_) |
(...skipping 15 matching lines...) Expand all Loading... |
543 // checks, which can occur anytime after ImageNotifyFinished() | 525 // checks, which can occur anytime after ImageNotifyFinished() |
544 // (See SVGImage::CurrentFrameHasSingleSecurityOrigin()). | 526 // (See SVGImage::CurrentFrameHasSingleSecurityOrigin()). |
545 // We check the document is loaded here to catch violation of the | 527 // We check the document is loaded here to catch violation of the |
546 // assumption reliably. | 528 // assumption reliably. |
547 ToSVGImage(image_->GetImage())->CheckLoaded(); | 529 ToSVGImage(image_->GetImage())->CheckLoaded(); |
548 | 530 |
549 ToSVGImage(image_->GetImage()) | 531 ToSVGImage(image_->GetImage()) |
550 ->UpdateUseCounters(GetElement()->GetDocument()); | 532 ->UpdateUseCounters(GetElement()->GetDocument()); |
551 } | 533 } |
552 | 534 |
553 if (loading_image_document_) | 535 if (loading_image_document_) { |
| 536 CHECK(!pending_load_event_.IsActive()); |
554 return; | 537 return; |
| 538 } |
555 | 539 |
556 if (resource->ErrorOccurred()) { | 540 if (resource->ErrorOccurred()) { |
557 LoadEventSender().CancelEvent(this); | 541 pending_load_event_.Cancel(); |
558 has_pending_load_event_ = false; | |
559 | 542 |
560 if (resource->GetResourceError().IsAccessCheck()) { | 543 if (resource->GetResourceError().IsAccessCheck()) { |
561 CrossSiteOrCSPViolationOccurred( | 544 CrossSiteOrCSPViolationOccurred( |
562 AtomicString(resource->GetResourceError().FailingURL())); | 545 AtomicString(resource->GetResourceError().FailingURL())); |
563 } | 546 } |
564 | 547 |
565 // The error event should not fire if the image data update is a result of | 548 // The error event should not fire if the image data update is a result of |
566 // environment change. | 549 // environment change. |
567 // https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-elem
ent:the-img-element-55 | 550 // https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-elem
ent:the-img-element-55 |
568 if (!suppress_error_events_) | 551 if (!suppress_error_events_) |
569 DispatchErrorEvent(); | 552 DispatchErrorEvent(); |
570 return; | 553 return; |
571 } | 554 } |
572 has_pending_load_event_ = true; | 555 |
573 LoadEventSender().DispatchEventSoon(this); | 556 CHECK(!pending_load_event_.IsActive()); |
| 557 pending_load_event_ = |
| 558 TaskRunnerHelper::Get(TaskType::kDOMManipulation, |
| 559 &GetElement()->GetDocument()) |
| 560 ->PostCancellableTask( |
| 561 BLINK_FROM_HERE, |
| 562 WTF::Bind(&ImageLoader::DispatchPendingLoadEvent, |
| 563 WrapPersistent(this), |
| 564 WTF::Passed(IncrementLoadEventDelayCount::Create( |
| 565 GetElement()->GetDocument())))); |
574 } | 566 } |
575 | 567 |
576 LayoutImageResource* ImageLoader::GetLayoutImageResource() { | 568 LayoutImageResource* ImageLoader::GetLayoutImageResource() { |
577 LayoutObject* layout_object = element_->GetLayoutObject(); | 569 LayoutObject* layout_object = element_->GetLayoutObject(); |
578 | 570 |
579 if (!layout_object) | 571 if (!layout_object) |
580 return 0; | 572 return 0; |
581 | 573 |
582 // We don't return style generated image because it doesn't belong to the | 574 // We don't return style generated image because it doesn't belong to the |
583 // ImageLoader. See <https://bugs.webkit.org/show_bug.cgi?id=42840> | 575 // ImageLoader. See <https://bugs.webkit.org/show_bug.cgi?id=42840> |
(...skipping 22 matching lines...) Expand all Loading... |
606 ImageResourceContent* cached_image = image_resource->CachedImage(); | 598 ImageResourceContent* cached_image = image_resource->CachedImage(); |
607 if (image_ != cached_image && (image_complete_ || !cached_image)) | 599 if (image_ != cached_image && (image_complete_ || !cached_image)) |
608 image_resource->SetImageResource(image_.Get()); | 600 image_resource->SetImageResource(image_.Get()); |
609 } | 601 } |
610 | 602 |
611 bool ImageLoader::HasPendingEvent() const { | 603 bool ImageLoader::HasPendingEvent() const { |
612 // Regular image loading is in progress. | 604 // Regular image loading is in progress. |
613 if (image_ && !image_complete_ && !loading_image_document_) | 605 if (image_ && !image_complete_ && !loading_image_document_) |
614 return true; | 606 return true; |
615 | 607 |
616 if (has_pending_load_event_ || has_pending_error_event_) | 608 if (pending_load_event_.IsActive() || pending_error_event_.IsActive()) |
617 return true; | 609 return true; |
618 | 610 |
619 return false; | 611 return false; |
620 } | 612 } |
621 | 613 |
622 void ImageLoader::DispatchPendingEvent(ImageEventSender* event_sender) { | 614 void ImageLoader::DispatchPendingLoadEvent( |
623 RESOURCE_LOADING_DVLOG(1) << "ImageLoader::dispatchPendingEvent " << this; | 615 std::unique_ptr<IncrementLoadEventDelayCount> count) { |
624 DCHECK(event_sender == &LoadEventSender() || | |
625 event_sender == &ErrorEventSender()); | |
626 const AtomicString& event_type = event_sender->EventType(); | |
627 if (event_type == EventTypeNames::load) | |
628 DispatchPendingLoadEvent(); | |
629 if (event_type == EventTypeNames::error) | |
630 DispatchPendingErrorEvent(); | |
631 } | |
632 | |
633 void ImageLoader::DispatchPendingLoadEvent() { | |
634 CHECK(has_pending_load_event_); | |
635 if (!image_) | 616 if (!image_) |
636 return; | 617 return; |
637 CHECK(image_complete_); | 618 CHECK(image_complete_); |
638 has_pending_load_event_ = false; | |
639 if (GetElement()->GetDocument().GetFrame()) | 619 if (GetElement()->GetDocument().GetFrame()) |
640 DispatchLoadEvent(); | 620 DispatchLoadEvent(); |
| 621 |
| 622 // Checks Document's load event synchronously here for performance. |
| 623 // This is safe because DispatchPendingLoadEvent() is called asynchronously. |
| 624 count->ClearAndCheckLoadEvent(); |
641 } | 625 } |
642 | 626 |
643 void ImageLoader::DispatchPendingErrorEvent() { | 627 void ImageLoader::DispatchPendingErrorEvent( |
644 CHECK(has_pending_error_event_); | 628 std::unique_ptr<IncrementLoadEventDelayCount> count) { |
645 has_pending_error_event_ = false; | |
646 | |
647 if (GetElement()->GetDocument().GetFrame()) | 629 if (GetElement()->GetDocument().GetFrame()) |
648 GetElement()->DispatchEvent(Event::Create(EventTypeNames::error)); | 630 GetElement()->DispatchEvent(Event::Create(EventTypeNames::error)); |
| 631 |
| 632 // Checks Document's load event synchronously here for performance. |
| 633 // This is safe because DispatchPendingErrorEvent() is called asynchronously. |
| 634 count->ClearAndCheckLoadEvent(); |
649 } | 635 } |
650 | 636 |
651 bool ImageLoader::GetImageAnimationPolicy(ImageAnimationPolicy& policy) { | 637 bool ImageLoader::GetImageAnimationPolicy(ImageAnimationPolicy& policy) { |
652 if (!GetElement()->GetDocument().GetSettings()) | 638 if (!GetElement()->GetDocument().GetSettings()) |
653 return false; | 639 return false; |
654 | 640 |
655 policy = GetElement()->GetDocument().GetSettings()->GetImageAnimationPolicy(); | 641 policy = GetElement()->GetDocument().GetSettings()->GetImageAnimationPolicy(); |
656 return true; | 642 return true; |
657 } | 643 } |
658 | 644 |
659 void ImageLoader::DispatchPendingLoadEvents() { | |
660 LoadEventSender().DispatchPendingEvents(); | |
661 } | |
662 | |
663 void ImageLoader::DispatchPendingErrorEvents() { | |
664 ErrorEventSender().DispatchPendingEvents(); | |
665 } | |
666 | |
667 void ImageLoader::ElementDidMoveToNewDocument() { | 645 void ImageLoader::ElementDidMoveToNewDocument() { |
668 if (delay_until_do_update_from_element_) { | 646 if (delay_until_do_update_from_element_) { |
669 delay_until_do_update_from_element_->DocumentChanged( | 647 delay_until_do_update_from_element_->DocumentChanged( |
670 element_->GetDocument()); | 648 element_->GetDocument()); |
671 } | 649 } |
672 if (delay_until_image_notify_finished_) { | 650 if (delay_until_image_notify_finished_) { |
673 delay_until_image_notify_finished_->DocumentChanged( | 651 delay_until_image_notify_finished_->DocumentChanged( |
674 element_->GetDocument()); | 652 element_->GetDocument()); |
675 } | 653 } |
676 ClearFailedLoadURL(); | 654 ClearFailedLoadURL(); |
677 ClearImage(); | 655 ClearImage(); |
678 } | 656 } |
679 | 657 |
680 } // namespace blink | 658 } // namespace blink |
OLD | NEW |