diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/loader/ImageLoader.cpp')
-rw-r--r-- | src/3rdparty/webkit/WebCore/loader/ImageLoader.cpp | 341 |
1 files changed, 0 insertions, 341 deletions
diff --git a/src/3rdparty/webkit/WebCore/loader/ImageLoader.cpp b/src/3rdparty/webkit/WebCore/loader/ImageLoader.cpp deleted file mode 100644 index 929b28a..0000000 --- a/src/3rdparty/webkit/WebCore/loader/ImageLoader.cpp +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "ImageLoader.h" - -#include "CSSHelper.h" -#include "CachedImage.h" -#include "DocLoader.h" -#include "Document.h" -#include "Element.h" -#include "RenderImage.h" - -#if !ASSERT_DISABLED -// ImageLoader objects are allocated as members of other objects, so generic pointer check would always fail. -namespace WTF { - -template<> struct ValueCheck<WebCore::ImageLoader*> { - typedef WebCore::ImageLoader* TraitType; - static void checkConsistency(const WebCore::ImageLoader* p) - { - if (!p) - return; - ASSERT(p->element()); - ValueCheck<WebCore::Element*>::checkConsistency(p->element()); - } -}; - -} -#endif - -namespace WebCore { - -class ImageEventSender : public Noncopyable { -public: - ImageEventSender(const AtomicString& eventType); - - void dispatchEventSoon(ImageLoader*); - void cancelEvent(ImageLoader*); - - void dispatchPendingEvents(); - -#if !ASSERT_DISABLED - bool hasPendingEvents(ImageLoader* loader) { return m_dispatchSoonList.find(loader) != notFound; } -#endif - -private: - void timerFired(Timer<ImageEventSender>*); - - AtomicString m_eventType; - Timer<ImageEventSender> m_timer; - Vector<ImageLoader*> m_dispatchSoonList; - Vector<ImageLoader*> m_dispatchingList; -}; - -static ImageEventSender& beforeLoadEventSender() -{ - DEFINE_STATIC_LOCAL(ImageEventSender, sender, (eventNames().beforeloadEvent)); - return sender; -} - -static ImageEventSender& loadEventSender() -{ - DEFINE_STATIC_LOCAL(ImageEventSender, sender, (eventNames().loadEvent)); - return sender; -} - -ImageLoader::ImageLoader(Element* element) - : m_element(element) - , m_image(0) - , m_firedBeforeLoad(true) - , m_firedLoad(true) - , m_imageComplete(true) - , m_loadManually(false) -{ -} - -ImageLoader::~ImageLoader() -{ - if (m_image) - m_image->removeClient(this); - - ASSERT(!m_firedBeforeLoad || !beforeLoadEventSender().hasPendingEvents(this)); - if (!m_firedBeforeLoad) - beforeLoadEventSender().cancelEvent(this); - - ASSERT(!m_firedLoad || !loadEventSender().hasPendingEvents(this)); - if (!m_firedLoad) - loadEventSender().cancelEvent(this); -} - -void ImageLoader::setImage(CachedImage* newImage) -{ - ASSERT(m_failedLoadURL.isEmpty()); - CachedImage* oldImage = m_image.get(); - if (newImage != oldImage) { - m_image = newImage; - if (!m_firedBeforeLoad) { - beforeLoadEventSender().cancelEvent(this); - m_firedBeforeLoad = true; - } - if (!m_firedLoad) { - loadEventSender().cancelEvent(this); - m_firedLoad = true; - } - m_imageComplete = true; - if (newImage) - newImage->addClient(this); - if (oldImage) - oldImage->removeClient(this); - } - - if (RenderObject* renderer = m_element->renderer()) { - if (!renderer->isImage()) - return; - toRenderImage(renderer)->resetAnimation(); - } -} - -void ImageLoader::updateFromElement() -{ - // If we're not making renderers for the page, then don't load images. We don't want to slow - // down the raw HTML parsing case by loading images we don't intend to display. - Document* document = m_element->document(); - if (!document->renderer()) - return; - - AtomicString attr = m_element->getAttribute(m_element->imageSourceAttributeName()); - - if (attr == m_failedLoadURL) - return; - - // Do not load any image if the 'src' attribute is missing or if it is - // an empty string referring to a local file. The latter condition is - // a quirk that preserves old behavior that Dashboard widgets - // need (<rdar://problem/5994621>). - CachedImage* newImage = 0; - if (!(attr.isNull() || (attr.isEmpty() && document->baseURI().isLocalFile()))) { - if (m_loadManually) { - document->docLoader()->setAutoLoadImages(false); - newImage = new CachedImage(sourceURI(attr)); - newImage->setLoading(true); - newImage->setDocLoader(document->docLoader()); - document->docLoader()->m_documentResources.set(newImage->url(), newImage); - } else - newImage = document->docLoader()->requestImage(sourceURI(attr)); - - // If we do not have an image here, it means that a cross-site - // violation occurred. - m_failedLoadURL = !newImage ? attr : AtomicString(); - } - - CachedImage* oldImage = m_image.get(); - if (newImage != oldImage) { - if (!m_firedBeforeLoad) - beforeLoadEventSender().cancelEvent(this); - if (!m_firedLoad) - loadEventSender().cancelEvent(this); - - m_image = newImage; - m_firedBeforeLoad = !newImage; - m_firedLoad = !newImage; - m_imageComplete = !newImage; - - if (newImage) { - newImage->addClient(this); - if (!m_element->document()->hasListenerType(Document::BEFORELOAD_LISTENER)) - dispatchPendingBeforeLoadEvent(); - else - beforeLoadEventSender().dispatchEventSoon(this); - } - if (oldImage) - oldImage->removeClient(this); - } - - if (RenderObject* renderer = m_element->renderer()) { - if (!renderer->isImage()) - return; - toRenderImage(renderer)->resetAnimation(); - } -} - -void ImageLoader::updateFromElementIgnoringPreviousError() -{ - // Clear previous error. - m_failedLoadURL = AtomicString(); - updateFromElement(); -} - -void ImageLoader::notifyFinished(CachedResource*) -{ - ASSERT(m_failedLoadURL.isEmpty()); - - m_imageComplete = true; - if (haveFiredBeforeLoadEvent()) - updateRenderer(); - - if (m_firedLoad) - return; - - loadEventSender().dispatchEventSoon(this); -} - -void ImageLoader::updateRenderer() -{ - if (RenderObject* renderer = m_element->renderer()) { - if (!renderer->isImage() && !renderer->isVideo()) - return; - RenderImage* imageRenderer = toRenderImage(renderer); - - // Only update the renderer if it doesn't have an image or if what we have - // is a complete image. This prevents flickering in the case where a dynamic - // change is happening between two images. - CachedImage* cachedImage = imageRenderer->cachedImage(); - if (m_image != cachedImage && (m_imageComplete || !cachedImage)) - imageRenderer->setCachedImage(m_image.get()); - } -} - -void ImageLoader::dispatchPendingBeforeLoadEvent() -{ - if (m_firedBeforeLoad) - return; - if (!m_image) - return; - if (!m_element->document()->attached()) - return; - m_firedBeforeLoad = true; - if (m_element->dispatchBeforeLoadEvent(m_image->url())) { - updateRenderer(); - return; - } - if (m_image) { - m_image->removeClient(this); - m_image = 0; - } - loadEventSender().cancelEvent(this); -} - -void ImageLoader::dispatchPendingLoadEvent() -{ - if (m_firedLoad) - return; - if (!m_image) - return; - if (!m_element->document()->attached()) - return; - m_firedLoad = true; - dispatchLoadEvent(); -} - -void ImageLoader::dispatchPendingBeforeLoadEvents() -{ - beforeLoadEventSender().dispatchPendingEvents(); -} - -void ImageLoader::dispatchPendingLoadEvents() -{ - loadEventSender().dispatchPendingEvents(); -} - -ImageEventSender::ImageEventSender(const AtomicString& eventType) - : m_eventType(eventType) - , m_timer(this, &ImageEventSender::timerFired) -{ -} - -void ImageEventSender::dispatchEventSoon(ImageLoader* loader) -{ - m_dispatchSoonList.append(loader); - if (!m_timer.isActive()) - m_timer.startOneShot(0); -} - -void ImageEventSender::cancelEvent(ImageLoader* loader) -{ - // Remove instances of this loader from both lists. - // Use loops because we allow multiple instances to get into the lists. - size_t size = m_dispatchSoonList.size(); - for (size_t i = 0; i < size; ++i) { - if (m_dispatchSoonList[i] == loader) - m_dispatchSoonList[i] = 0; - } - size = m_dispatchingList.size(); - for (size_t i = 0; i < size; ++i) { - if (m_dispatchingList[i] == loader) - m_dispatchingList[i] = 0; - } - if (m_dispatchSoonList.isEmpty()) - m_timer.stop(); -} - -void ImageEventSender::dispatchPendingEvents() -{ - // Need to avoid re-entering this function; if new dispatches are - // scheduled before the parent finishes processing the list, they - // will set a timer and eventually be processed. - if (!m_dispatchingList.isEmpty()) - return; - - m_timer.stop(); - - m_dispatchSoonList.checkConsistency(); - - m_dispatchingList.swap(m_dispatchSoonList); - size_t size = m_dispatchingList.size(); - for (size_t i = 0; i < size; ++i) { - if (ImageLoader* loader = m_dispatchingList[i]) { - if (m_eventType == eventNames().beforeloadEvent) - loader->dispatchPendingBeforeLoadEvent(); - else - loader->dispatchPendingLoadEvent(); - } - } - m_dispatchingList.clear(); -} - -void ImageEventSender::timerFired(Timer<ImageEventSender>*) -{ - dispatchPendingEvents(); -} - -} |