Index: third_party/WebKit/Source/core/loader/ImageLoader.cpp |
diff --git a/third_party/WebKit/Source/core/loader/ImageLoader.cpp b/third_party/WebKit/Source/core/loader/ImageLoader.cpp |
index eb5a0cfbd7bdc4056f7869338b61e3a5b2387ae6..b137ee673a1e554a5221564c8164d7621be12a4d 100644 |
--- a/third_party/WebKit/Source/core/loader/ImageLoader.cpp |
+++ b/third_party/WebKit/Source/core/loader/ImageLoader.cpp |
@@ -29,7 +29,6 @@ |
#include "core/dom/Element.h" |
#include "core/dom/IncrementLoadEventDelayCount.h" |
#include "core/events/Event.h" |
-#include "core/events/EventSender.h" |
#include "core/frame/LocalFrame.h" |
#include "core/frame/Settings.h" |
#include "core/frame/UseCounter.h" |
@@ -56,18 +55,6 @@ |
namespace blink { |
-static ImageEventSender& LoadEventSender() { |
- DEFINE_STATIC_LOCAL(ImageEventSender, sender, |
- (ImageEventSender::Create(EventTypeNames::load))); |
- return sender; |
-} |
- |
-static ImageEventSender& ErrorEventSender() { |
- DEFINE_STATIC_LOCAL(ImageEventSender, sender, |
- (ImageEventSender::Create(EventTypeNames::error))); |
- return sender; |
-} |
- |
static inline bool PageIsBeingDismissed(Document* document) { |
return document->PageDismissalEventBeingDispatched() != |
Document::kNoDismissal; |
@@ -157,8 +144,6 @@ class ImageLoader::Task { |
ImageLoader::ImageLoader(Element* element) |
: element_(element), |
deref_element_timer_(this, &ImageLoader::TimerFired), |
- has_pending_load_event_(false), |
- has_pending_error_event_(false), |
image_complete_(true), |
loading_image_document_(false), |
element_is_protected_(false), |
@@ -171,8 +156,8 @@ ImageLoader::~ImageLoader() {} |
void ImageLoader::Dispose() { |
RESOURCE_LOADING_DVLOG(1) |
<< "~ImageLoader " << this |
- << "; has_pending_load_event_=" << has_pending_load_event_ |
- << ", has_pending_error_event_=" << has_pending_error_event_; |
+ << "; has pending load event=" << pending_load_event_.IsActive() |
+ << ", has pending error event=" << pending_error_event_.IsActive(); |
if (image_) { |
image_->RemoveObserver(this); |
@@ -230,14 +215,10 @@ void ImageLoader::SetImageWithoutConsideringPendingLoadEvent( |
DCHECK(failed_load_url_.IsEmpty()); |
ImageResourceContent* old_image = image_.Get(); |
if (new_image != old_image) { |
- if (has_pending_load_event_) { |
- LoadEventSender().CancelEvent(this); |
- has_pending_load_event_ = false; |
- } |
- if (has_pending_error_event_) { |
- ErrorEventSender().CancelEvent(this); |
- has_pending_error_event_ = false; |
- } |
+ if (pending_load_event_.IsActive()) |
+ pending_load_event_.Cancel(); |
+ if (pending_error_event_.IsActive()) |
+ pending_error_event_.Cancel(); |
UpdateImageState(new_image); |
if (new_image) { |
new_image->AddObserver(this); |
@@ -274,13 +255,18 @@ static void ConfigureRequest( |
inline void ImageLoader::DispatchErrorEvent() { |
// There can be cases where DispatchErrorEvent() is called when there is |
// already a scheduled error event for the previous load attempt. |
- // In such cases we cancel the previous event and then re-schedule a new |
- // error event here. crbug.com/722500 |
- if (has_pending_error_event_) |
- ErrorEventSender().CancelEvent(this); |
- |
- has_pending_error_event_ = true; |
- ErrorEventSender().DispatchEventSoon(this); |
+ // In such cases we cancel the previous event (by overwriting |
+ // |pending_error_event_|) and then re-schedule a new error event here. |
+ // crbug.com/722500 |
+ pending_error_event_ = |
+ TaskRunnerHelper::Get(TaskType::kDOMManipulation, |
+ &GetElement()->GetDocument()) |
+ ->PostCancellableTask( |
+ BLINK_FROM_HERE, |
+ WTF::Bind(&ImageLoader::DispatchPendingErrorEvent, |
+ WrapPersistent(this), |
+ WTF::Passed(IncrementLoadEventDelayCount::Create( |
+ GetElement()->GetDocument())))); |
} |
inline void ImageLoader::CrossSiteOrCSPViolationOccurred( |
@@ -382,10 +368,8 @@ void ImageLoader::DoUpdateFromElement(BypassMainWorldBehavior bypass_behavior, |
element_->GetLayoutObject()->IsImage() && new_image == old_image) { |
ToLayoutImage(element_->GetLayoutObject())->IntrinsicSizeChanged(); |
} else { |
- if (has_pending_load_event_) { |
- LoadEventSender().CancelEvent(this); |
- has_pending_load_event_ = false; |
- } |
+ if (pending_load_event_.IsActive()) |
+ pending_load_event_.Cancel(); |
// Cancel error events that belong to the previous load, which is now |
// cancelled by changing the src attribute. If newImage is null and |
@@ -393,10 +377,8 @@ void ImageLoader::DoUpdateFromElement(BypassMainWorldBehavior bypass_behavior, |
// posted by this load and we should not cancel the event. |
// FIXME: If both previous load and this one got blocked with an error, we |
// can receive one error event instead of two. |
- if (has_pending_error_event_ && new_image) { |
- ErrorEventSender().CancelEvent(this); |
- has_pending_error_event_ = false; |
- } |
+ if (pending_error_event_.IsActive() && new_image) |
+ pending_error_event_.Cancel(); |
UpdateImageState(new_image); |
@@ -536,7 +518,7 @@ void ImageLoader::ImageChanged(ImageResourceContent* content, const IntRect*) { |
void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) { |
RESOURCE_LOADING_DVLOG(1) |
<< "ImageLoader::imageNotifyFinished " << this |
- << "; has_pending_load_event_=" << has_pending_load_event_; |
+ << "; has pending load event=" << pending_load_event_.IsActive(); |
DCHECK(failed_load_url_.IsEmpty()); |
DCHECK_EQ(resource, image_.Get()); |
@@ -572,12 +554,13 @@ void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) { |
->UpdateUseCounters(GetElement()->GetDocument()); |
} |
- if (loading_image_document_) |
+ if (loading_image_document_) { |
+ CHECK(!pending_load_event_.IsActive()); |
return; |
+ } |
if (resource->ErrorOccurred()) { |
- LoadEventSender().CancelEvent(this); |
- has_pending_load_event_ = false; |
+ pending_load_event_.Cancel(); |
if (resource->GetResourceError().IsAccessCheck()) { |
CrossSiteOrCSPViolationOccurred( |
@@ -596,8 +579,17 @@ void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) { |
UpdatedHasPendingEvent(); |
return; |
} |
- has_pending_load_event_ = true; |
- LoadEventSender().DispatchEventSoon(this); |
+ |
+ CHECK(!pending_load_event_.IsActive()); |
+ pending_load_event_ = |
+ TaskRunnerHelper::Get(TaskType::kDOMManipulation, |
+ &GetElement()->GetDocument()) |
+ ->PostCancellableTask( |
+ BLINK_FROM_HERE, |
+ WTF::Bind(&ImageLoader::DispatchPendingLoadEvent, |
+ WrapPersistent(this), |
+ WTF::Passed(IncrementLoadEventDelayCount::Create( |
+ GetElement()->GetDocument())))); |
} |
LayoutImageResource* ImageLoader::GetLayoutImageResource() { |
@@ -640,7 +632,7 @@ bool ImageLoader::HasPendingEvent() const { |
if (image_ && !image_complete_ && !loading_image_document_) |
return true; |
- if (has_pending_load_event_ || has_pending_error_event_) |
+ if (pending_load_event_.IsActive() || pending_error_event_.IsActive()) |
return true; |
return false; |
@@ -673,23 +665,11 @@ void ImageLoader::TimerFired(TimerBase*) { |
keep_alive_.Clear(); |
} |
-void ImageLoader::DispatchPendingEvent(ImageEventSender* event_sender) { |
- RESOURCE_LOADING_DVLOG(1) << "ImageLoader::dispatchPendingEvent " << this; |
- DCHECK(event_sender == &LoadEventSender() || |
- event_sender == &ErrorEventSender()); |
- const AtomicString& event_type = event_sender->EventType(); |
- if (event_type == EventTypeNames::load) |
- DispatchPendingLoadEvent(); |
- if (event_type == EventTypeNames::error) |
- DispatchPendingErrorEvent(); |
-} |
- |
-void ImageLoader::DispatchPendingLoadEvent() { |
- CHECK(has_pending_load_event_); |
+void ImageLoader::DispatchPendingLoadEvent( |
+ std::unique_ptr<IncrementLoadEventDelayCount> count) { |
if (!image_) |
return; |
CHECK(image_complete_); |
- has_pending_load_event_ = false; |
if (GetElement()->GetDocument().GetFrame()) |
DispatchLoadEvent(); |
@@ -697,12 +677,14 @@ void ImageLoader::DispatchPendingLoadEvent() { |
// before returning from this function as doing so might result in the |
// destruction of this ImageLoader. |
UpdatedHasPendingEvent(); |
-} |
-void ImageLoader::DispatchPendingErrorEvent() { |
- CHECK(has_pending_error_event_); |
- has_pending_error_event_ = false; |
+ // Checks Document's load event synchronously here for performance. |
+ // This is safe because DispatchPendingLoadEvent() is called asynchronously. |
+ count->ClearAndCheckLoadEvent(); |
+} |
+void ImageLoader::DispatchPendingErrorEvent( |
+ std::unique_ptr<IncrementLoadEventDelayCount> count) { |
if (GetElement()->GetDocument().GetFrame()) |
GetElement()->DispatchEvent(Event::Create(EventTypeNames::error)); |
@@ -710,6 +692,10 @@ void ImageLoader::DispatchPendingErrorEvent() { |
// before returning from this function as doing so might result in the |
// destruction of this ImageLoader. |
UpdatedHasPendingEvent(); |
+ |
+ // Checks Document's load event synchronously here for performance. |
+ // This is safe because DispatchPendingErrorEvent() is called asynchronously. |
+ count->ClearAndCheckLoadEvent(); |
} |
bool ImageLoader::GetImageAnimationPolicy(ImageAnimationPolicy& policy) { |
@@ -720,14 +706,6 @@ bool ImageLoader::GetImageAnimationPolicy(ImageAnimationPolicy& policy) { |
return true; |
} |
-void ImageLoader::DispatchPendingLoadEvents() { |
- LoadEventSender().DispatchPendingEvents(); |
-} |
- |
-void ImageLoader::DispatchPendingErrorEvents() { |
- ErrorEventSender().DispatchPendingEvents(); |
-} |
- |
void ImageLoader::ElementDidMoveToNewDocument() { |
if (delay_until_do_update_from_element_) { |
delay_until_do_update_from_element_->DocumentChanged( |