diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-06-20 13:01:08 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-06-20 13:01:08 +0200 |
commit | 49233e234e5c787396cadb2cea33b31ae0cd65c1 (patch) | |
tree | 5410cb9a8fd53168bb60d62c54b654d86f03c38d /Source/WebCore/loader/ImageLoader.cpp | |
parent | b211c645d8ab690f713515dfdc84d80b11c27d2c (diff) | |
download | qtwebkit-49233e234e5c787396cadb2cea33b31ae0cd65c1.tar.gz |
Imported WebKit commit 3a8c29f35d00659d2ce7a0ccdfa8304f14e82327 (http://svn.webkit.org/repository/webkit/trunk@120813)
New snapshot with Windows build fixes
Diffstat (limited to 'Source/WebCore/loader/ImageLoader.cpp')
-rw-r--r-- | Source/WebCore/loader/ImageLoader.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/Source/WebCore/loader/ImageLoader.cpp b/Source/WebCore/loader/ImageLoader.cpp index f4a9ff535..0e3781cdb 100644 --- a/Source/WebCore/loader/ImageLoader.cpp +++ b/Source/WebCore/loader/ImageLoader.cpp @@ -89,6 +89,7 @@ ImageLoader::ImageLoader(Element* element) , m_hasPendingErrorEvent(false) , m_imageComplete(true) , m_loadManually(false) + , m_elementIsProtected(false) { } @@ -108,6 +109,11 @@ ImageLoader::~ImageLoader() ASSERT(m_hasPendingErrorEvent || !errorEventSender().hasPendingEvents(this)); if (m_hasPendingErrorEvent) errorEventSender().cancelEvent(this); + + // If the ImageLoader is being destroyed but it is still protecting its image-loading Element, + // remove that protection here. + if (m_elementIsProtected) + m_element->deref(); } void ImageLoader::setImage(CachedImage* newImage) @@ -137,6 +143,10 @@ void ImageLoader::setImage(CachedImage* newImage) if (RenderImageResource* imageResource = renderImageResource()) imageResource->resetAnimation(); + + // Only consider updating the protection ref-count of the Element immediately before returning + // from this function as doing so might result in the destruction of this ImageLoader. + updatedHasPendingLoadEvent(); } void ImageLoader::updateFromElement() @@ -218,6 +228,10 @@ void ImageLoader::updateFromElement() if (RenderImageResource* imageResource = renderImageResource()) imageResource->resetAnimation(); + + // Only consider updating the protection ref-count of the Element immediately before returning + // from this function as doing so might result in the destruction of this ImageLoader. + updatedHasPendingLoadEvent(); } void ImageLoader::updateFromElementIgnoringPreviousError() @@ -257,6 +271,9 @@ void ImageLoader::notifyFinished(CachedResource* resource) if (resource->wasCanceled()) { m_hasPendingLoadEvent = false; + // Only consider updating the protection ref-count of the Element immediately before returning + // from this function as doing so might result in the destruction of this ImageLoader. + updatedHasPendingLoadEvent(); return; } @@ -303,6 +320,24 @@ void ImageLoader::updateRenderer() imageResource->setCachedImage(m_image.get()); } +void ImageLoader::updatedHasPendingLoadEvent() +{ + // If an Element that does image loading is removed from the DOM the load event for the image is still observable. + // As long as the ImageLoader is actively loading, the Element itself needs to be ref'ed to keep it from being + // destroyed by DOM manipulation or garbage collection. + // If such an Element wishes for the load to stop when removed from the DOM it needs to stop the ImageLoader explicitly. + + if (m_hasPendingLoadEvent == m_elementIsProtected) + return; + + m_elementIsProtected = m_hasPendingLoadEvent; + + if (m_elementIsProtected) + m_element->ref(); + else + m_element->deref(); +} + void ImageLoader::dispatchPendingEvent(ImageEventSender* eventSender) { ASSERT(eventSender == &beforeLoadEventSender() || eventSender == &loadEventSender() || eventSender == &errorEventSender()); @@ -338,6 +373,10 @@ void ImageLoader::dispatchPendingBeforeLoadEvent() if (m_element->hasTagName(HTMLNames::objectTag)) static_cast<HTMLObjectElement*>(m_element)->renderFallbackContent(); + + // Only consider updating the protection ref-count of the Element immediately before returning + // from this function as doing so might result in the destruction of this ImageLoader. + updatedHasPendingLoadEvent(); } void ImageLoader::dispatchPendingLoadEvent() @@ -350,6 +389,10 @@ void ImageLoader::dispatchPendingLoadEvent() return; m_hasPendingLoadEvent = false; dispatchLoadEvent(); + + // Only consider updating the protection ref-count of the Element immediately before returning + // from this function as doing so might result in the destruction of this ImageLoader. + updatedHasPendingLoadEvent(); } void ImageLoader::dispatchPendingErrorEvent() |