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 49a8cfbfddf11320a29348b0d5cda3ecb3e3342e..f08fb31f2b3c61147a15d2ff925a489b7a7d688d 100644 |
--- a/third_party/WebKit/Source/core/loader/ImageLoader.cpp |
+++ b/third_party/WebKit/Source/core/loader/ImageLoader.cpp |
@@ -30,7 +30,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 |
- << "; m_hasPendingLoadEvent=" << has_pending_load_event_ |
- << ", m_hasPendingErrorEvent=" << has_pending_error_event_; |
+ << "; pending load event=" << pending_load_event_.IsActive() |
+ << ", pending error event=" << pending_error_event_.IsActive(); |
if (image_) { |
image_->RemoveObserver(this); |
@@ -203,14 +188,10 @@ void ImageLoader::SetImageWithoutConsideringPendingLoadEvent( |
if (new_image != old_image) { |
image_ = new_image; |
delay_until_image_notify_finished_ = nullptr; |
- 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(); |
image_complete_ = true; |
if (new_image) { |
new_image->AddObserver(this); |
@@ -245,8 +226,15 @@ static void ConfigureRequest( |
} |
inline void ImageLoader::DispatchErrorEvent() { |
- has_pending_error_event_ = true; |
- ErrorEventSender().DispatchEventSoon(this); |
+ 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( |
@@ -342,10 +330,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 |
@@ -353,10 +339,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(); |
image_ = new_image; |
image_complete_ = !new_image; |
@@ -490,7 +474,7 @@ void ImageLoader::ImageChanged(ImageResourceContent* content, const IntRect*) { |
void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) { |
RESOURCE_LOADING_DVLOG(1) |
<< "ImageLoader::imageNotifyFinished " << this |
- << "; m_hasPendingLoadEvent=" << has_pending_load_event_; |
+ << "; m_hasPendingLoadEvent=" << pending_load_event_.IsActive(); |
DCHECK(failed_load_url_.IsEmpty()); |
DCHECK_EQ(resource, image_.Get()); |
@@ -514,12 +498,13 @@ void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) { |
ToSVGImage(image_->GetImage()) |
->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( |
@@ -538,8 +523,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() { |
@@ -586,7 +580,8 @@ void ImageLoader::UpdatedHasPendingEvent() { |
// needs to stop the ImageLoader explicitly. |
bool was_protected = element_is_protected_; |
element_is_protected_ = (image_ && !image_complete_) || |
- has_pending_load_event_ || has_pending_error_event_; |
+ pending_load_event_.IsActive() || |
+ pending_error_event_.IsActive(); |
if (was_protected == element_is_protected_) |
return; |
@@ -605,24 +600,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; |
- CHECK(image_complete_); |
if (GetElement()->GetDocument().GetFrame()) |
DispatchLoadEvent(); |
@@ -630,13 +612,14 @@ void ImageLoader::DispatchPendingLoadEvent() { |
// before returning from this function as doing so might result in the |
// destruction of this ImageLoader. |
UpdatedHasPendingEvent(); |
-} |
-void ImageLoader::DispatchPendingErrorEvent() { |
- if (!has_pending_error_event_) |
- return; |
- 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)); |
@@ -644,6 +627,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) { |
@@ -654,14 +641,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( |