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