diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
commit | 2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch) | |
tree | 988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebCore/loader/ImageLoader.cpp | |
parent | dd91e772430dc294e3bf478c119ef8d43c0a3358 (diff) | |
download | qtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz |
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/WebCore/loader/ImageLoader.cpp')
-rw-r--r-- | Source/WebCore/loader/ImageLoader.cpp | 90 |
1 files changed, 65 insertions, 25 deletions
diff --git a/Source/WebCore/loader/ImageLoader.cpp b/Source/WebCore/loader/ImageLoader.cpp index 842175b5e..a670ad415 100644 --- a/Source/WebCore/loader/ImageLoader.cpp +++ b/Source/WebCore/loader/ImageLoader.cpp @@ -75,11 +75,18 @@ static ImageEventSender& loadEventSender() return sender; } +static ImageEventSender& errorEventSender() +{ + DEFINE_STATIC_LOCAL(ImageEventSender, sender, (eventNames().errorEvent)); + return sender; +} + ImageLoader::ImageLoader(Element* element) : m_element(element) , m_image(0) - , m_firedBeforeLoad(true) - , m_firedLoad(true) + , m_hasPendingBeforeLoadEvent(false) + , m_hasPendingLoadEvent(false) + , m_hasPendingErrorEvent(false) , m_imageComplete(true) , m_loadManually(false) { @@ -90,13 +97,17 @@ ImageLoader::~ImageLoader() if (m_image) m_image->removeClient(this); - ASSERT(!m_firedBeforeLoad || !beforeLoadEventSender().hasPendingEvents(this)); - if (!m_firedBeforeLoad) + ASSERT(m_hasPendingBeforeLoadEvent || !beforeLoadEventSender().hasPendingEvents(this)); + if (m_hasPendingBeforeLoadEvent) beforeLoadEventSender().cancelEvent(this); - ASSERT(!m_firedLoad || !loadEventSender().hasPendingEvents(this)); - if (!m_firedLoad) + ASSERT(m_hasPendingLoadEvent || !loadEventSender().hasPendingEvents(this)); + if (m_hasPendingLoadEvent) loadEventSender().cancelEvent(this); + + ASSERT(m_hasPendingErrorEvent || !errorEventSender().hasPendingEvents(this)); + if (m_hasPendingErrorEvent) + errorEventSender().cancelEvent(this); } void ImageLoader::setImage(CachedImage* newImage) @@ -105,13 +116,17 @@ void ImageLoader::setImage(CachedImage* newImage) CachedImage* oldImage = m_image.get(); if (newImage != oldImage) { m_image = newImage; - if (!m_firedBeforeLoad) { + if (m_hasPendingBeforeLoadEvent) { beforeLoadEventSender().cancelEvent(this); - m_firedBeforeLoad = true; + m_hasPendingBeforeLoadEvent = false; } - if (!m_firedLoad) { + if (m_hasPendingLoadEvent) { loadEventSender().cancelEvent(this); - m_firedLoad = true; + m_hasPendingLoadEvent = false; + } + if (m_hasPendingErrorEvent) { + errorEventSender().cancelEvent(this); + m_hasPendingErrorEvent = false; } m_imageComplete = true; if (newImage) @@ -163,19 +178,24 @@ void ImageLoader::updateFromElement() // If we do not have an image here, it means that a cross-site // violation occurred. m_failedLoadURL = !newImage ? attr : AtomicString(); - } else if (!attr.isNull()) // Fire an error event if the url is empty. + } else if (!attr.isNull()) { + // Fire an error event if the url is empty. + // FIXME: Should we fire this event asynchronoulsy via errorEventSender()? m_element->dispatchEvent(Event::create(eventNames().errorEvent, false, false)); + } CachedImage* oldImage = m_image.get(); if (newImage != oldImage) { - if (!m_firedBeforeLoad) + if (m_hasPendingBeforeLoadEvent) beforeLoadEventSender().cancelEvent(this); - if (!m_firedLoad) + if (m_hasPendingLoadEvent) loadEventSender().cancelEvent(this); + if (m_hasPendingErrorEvent) + errorEventSender().cancelEvent(this); m_image = newImage; - m_firedBeforeLoad = !newImage; - m_firedLoad = !newImage; + m_hasPendingBeforeLoadEvent = newImage; + m_hasPendingLoadEvent = newImage; m_imageComplete = !newImage; if (newImage) { @@ -210,10 +230,10 @@ void ImageLoader::notifyFinished(CachedResource* resource) ASSERT(resource == m_image.get()); m_imageComplete = true; - if (haveFiredBeforeLoadEvent()) + if (!hasPendingBeforeLoadEvent()) updateRenderer(); - if (m_firedLoad) + if (!m_hasPendingLoadEvent) return; if (m_element->fastHasAttribute(HTMLNames::crossoriginAttr) @@ -222,15 +242,18 @@ void ImageLoader::notifyFinished(CachedResource* resource) setImage(0); + m_hasPendingErrorEvent = true; + errorEventSender().dispatchEventSoon(this); + DEFINE_STATIC_LOCAL(String, consoleMessage, ("Cross-origin image load denied by Cross-Origin Resource Sharing policy.")); m_element->document()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage); - ASSERT(m_firedLoad); + ASSERT(!m_hasPendingLoadEvent); return; } if (resource->wasCanceled()) { - m_firedLoad = true; + m_hasPendingLoadEvent = false; return; } @@ -279,23 +302,25 @@ void ImageLoader::updateRenderer() void ImageLoader::dispatchPendingEvent(ImageEventSender* eventSender) { - ASSERT(eventSender == &beforeLoadEventSender() || eventSender == &loadEventSender()); + ASSERT(eventSender == &beforeLoadEventSender() || eventSender == &loadEventSender() || eventSender == &errorEventSender()); const AtomicString& eventType = eventSender->eventType(); if (eventType == eventNames().beforeloadEvent) dispatchPendingBeforeLoadEvent(); if (eventType == eventNames().loadEvent) dispatchPendingLoadEvent(); + if (eventType == eventNames().errorEvent) + dispatchPendingErrorEvent(); } void ImageLoader::dispatchPendingBeforeLoadEvent() { - if (m_firedBeforeLoad) + if (!m_hasPendingBeforeLoadEvent) return; if (!m_image) return; if (!m_element->document()->attached()) return; - m_firedBeforeLoad = true; + m_hasPendingBeforeLoadEvent = false; if (m_element->dispatchBeforeLoadEvent(m_image->url())) { updateRenderer(); return; @@ -306,7 +331,7 @@ void ImageLoader::dispatchPendingBeforeLoadEvent() } loadEventSender().cancelEvent(this); - m_firedLoad = true; + m_hasPendingLoadEvent = false; if (m_element->hasTagName(HTMLNames::objectTag)) static_cast<HTMLObjectElement*>(m_element)->renderFallbackContent(); @@ -314,16 +339,26 @@ void ImageLoader::dispatchPendingBeforeLoadEvent() void ImageLoader::dispatchPendingLoadEvent() { - if (m_firedLoad) + if (!m_hasPendingLoadEvent) return; if (!m_image) return; if (!m_element->document()->attached()) return; - m_firedLoad = true; + m_hasPendingLoadEvent = false; dispatchLoadEvent(); } +void ImageLoader::dispatchPendingErrorEvent() +{ + if (!m_hasPendingErrorEvent) + return; + if (!m_element->document()->attached()) + return; + m_hasPendingErrorEvent = false; + m_element->dispatchEvent(Event::create(eventNames().errorEvent, false, false)); +} + void ImageLoader::dispatchPendingBeforeLoadEvents() { beforeLoadEventSender().dispatchPendingEvents(); @@ -334,6 +369,11 @@ void ImageLoader::dispatchPendingLoadEvents() loadEventSender().dispatchPendingEvents(); } +void ImageLoader::dispatchPendingErrorEvents() +{ + errorEventSender().dispatchPendingEvents(); +} + void ImageLoader::elementDidMoveToNewDocument() { setImage(0); |