15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 1999 Antti Koivisto (koivisto@kde.org)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/ImageLoader.h"
2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
25d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "bindings/v8/ScriptController.h"
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Element.h"
28d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/dom/IncrementLoadEventDelayCount.h"
29d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/dom/Microtask.h"
3006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/Event.h"
3106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/EventSender.h"
328abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#include "core/fetch/CrossOriginAccessControl.h"
33e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/FetchRequest.h"
34a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#include "core/fetch/MemoryCache.h"
35e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ResourceFetcher.h"
36d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/frame/LocalFrame.h"
37d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/html/HTMLImageElement.h"
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/parser/HTMLParserIdioms.h"
3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderImage.h"
4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderVideo.h"
4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/RenderSVGImage.h"
4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/weborigin/SecurityOrigin.h"
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static ImageEventSender& loadEventSender()
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::load));
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return sender;
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static ImageEventSender& errorEventSender()
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::error));
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return sender;
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static inline bool pageIsBeingDismissed(Document* document)
59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
60e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    return document->pageDismissalEventBeingDispatched() != Document::NoDismissal;
61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
63d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)class ImageLoader::Task : public blink::WebThread::Task {
64d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)public:
65d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    Task(ImageLoader* loader)
66d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        : m_loader(loader)
67d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        , m_shouldBypassMainWorldContentSecurityPolicy(false)
68d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        , m_weakFactory(this)
69d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
70d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        LocalFrame* frame = loader->m_element->document().frame();
71d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        m_shouldBypassMainWorldContentSecurityPolicy = frame->script().shouldBypassMainWorldContentSecurityPolicy();
72d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
73d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
74d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    virtual void run() OVERRIDE
75d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
76d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        if (m_loader) {
77d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            m_loader->doUpdateFromElement(m_shouldBypassMainWorldContentSecurityPolicy);
78d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        }
79d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
80d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
81d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    void clearLoader()
82d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
83d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        m_loader = 0;
84d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
85d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
86d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    WeakPtr<Task> createWeakPtr()
87d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
88d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        return m_weakFactory.createWeakPtr();
89d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
90d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
91d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)private:
92d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    ImageLoader* m_loader;
93d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    bool m_shouldBypassMainWorldContentSecurityPolicy;
94d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    WeakPtrFactory<Task> m_weakFactory;
95d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)};
96d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)ImageLoader::ImageLoader(Element* element)
98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    : m_element(element)
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_image(0)
100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_derefElementTimer(this, &ImageLoader::timerFired)
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_hasPendingLoadEvent(false)
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_hasPendingErrorEvent(false)
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_imageComplete(true)
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_loadManually(false)
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_elementIsProtected(false)
1061fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    , m_highPriorityClientCount(0)
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ImageLoader::~ImageLoader()
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
112d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (m_pendingTask)
113d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        m_pendingTask->clearLoader();
114d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_image)
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_image->removeClient(this);
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_hasPendingLoadEvent || !loadEventSender().hasPendingEvents(this));
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_hasPendingLoadEvent)
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        loadEventSender().cancelEvent(this);
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_hasPendingErrorEvent || !errorEventSender().hasPendingEvents(this));
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_hasPendingErrorEvent)
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        errorEventSender().cancelEvent(this);
1255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)}
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)void ImageLoader::trace(Visitor* visitor)
1285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles){
1295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    visitor->trace(m_element);
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1323c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdochvoid ImageLoader::setImage(ImageResource* newImage)
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setImageWithoutConsideringPendingLoadEvent(newImage);
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Only consider updating the protection ref-count of the Element immediately before returning
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // from this function as doing so might result in the destruction of this ImageLoader.
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    updatedHasPendingEvent();
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1413c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdochvoid ImageLoader::setImageWithoutConsideringPendingLoadEvent(ImageResource* newImage)
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_failedLoadURL.isEmpty());
1443c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    ImageResource* oldImage = m_image.get();
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (newImage != oldImage) {
1461fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        sourceImageChanged();
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_image = newImage;
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_hasPendingLoadEvent) {
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            loadEventSender().cancelEvent(this);
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_hasPendingLoadEvent = false;
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_hasPendingErrorEvent) {
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            errorEventSender().cancelEvent(this);
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_hasPendingErrorEvent = false;
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_imageComplete = true;
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (newImage)
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            newImage->addClient(this);
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (oldImage)
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            oldImage->removeClient(this);
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (RenderImageResource* imageResource = renderImageResource())
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        imageResource->resetAnimation();
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
167d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void ImageLoader::doUpdateFromElement(bool bypassMainWorldCSP)
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
169d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // We don't need to call clearLoader here: Either we were called from the
170d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // task, or our caller updateFromElement cleared the task's loader (and set
171d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // m_pendingTask to null).
172d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    m_pendingTask.clear();
173d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // Make sure to only decrement the count when we exit this function
174d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    OwnPtr<IncrementLoadEventDelayCount> delayLoad;
175d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    delayLoad.swap(m_delayLoad);
176d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
1778abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    Document& document = m_element->document();
17876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (!document.isActive())
17976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        return;
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
181926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    AtomicString attr = m_element->imageSourceURL();
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
183d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    KURL url = imageURL();
1843c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    ResourcePtr<ImageResource> newImage = 0;
185d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (!url.isNull()) {
186d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        FetchRequest request(ResourceRequest(url), element()->localName());
187d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        if (bypassMainWorldCSP)
188d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            request.setContentSecurityCheck(DoNotCheckContentSecurityPolicy);
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
190a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        AtomicString crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr);
19109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (!crossOriginMode.isNull())
19209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            request.setCrossOriginAccessControl(document.securityOrigin(), crossOriginMode);
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_loadManually) {
1958abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            bool autoLoadOtherImages = document.fetcher()->autoLoadImages();
1968abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            document.fetcher()->setAutoLoadImages(false);
1973c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            newImage = new ImageResource(request.resourceRequest());
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            newImage->setLoading(true);
1998abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            document.fetcher()->m_documentResources.set(newImage->url(), newImage.get());
2008abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            document.fetcher()->setAutoLoadImages(autoLoadOtherImages);
2013464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch        } else {
2028abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            newImage = document.fetcher()->fetchImage(request);
2033464d02a173573db42f8ee6bb07bb74fabf4f5f2Ben Murdoch        }
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If we do not have an image here, it means that a cross-site
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // violation occurred, or that the image was blocked via Content
207926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // Security Policy, or the page is being dismissed. Trigger an
208926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // error event if the page is not being dismissed.
2098abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if (!newImage && !pageIsBeingDismissed(&document)) {
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_failedLoadURL = attr;
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_hasPendingErrorEvent = true;
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            errorEventSender().dispatchEventSoon(this);
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else
214926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            clearFailedLoadURL();
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else if (!attr.isNull()) {
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Fire an error event if the url is empty.
217e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        m_hasPendingErrorEvent = true;
218e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        errorEventSender().dispatchEventSoon(this);
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
22002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2213c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    ImageResource* oldImage = m_image.get();
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (newImage != oldImage) {
2231fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        sourceImageChanged();
2241fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch
225926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (m_hasPendingLoadEvent) {
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            loadEventSender().cancelEvent(this);
227926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            m_hasPendingLoadEvent = false;
228926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
229926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
230926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // Cancel error events that belong to the previous load, which is now cancelled by changing the src attribute.
231926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // If newImage is null and m_hasPendingErrorEvent is true, we know the error event has been just posted by
232926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // this load and we should not cancel the event.
233926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // FIXME: If both previous load and this one got blocked with an error, we can receive one error event instead of two.
234926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (m_hasPendingErrorEvent && newImage) {
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            errorEventSender().cancelEvent(this);
236926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            m_hasPendingErrorEvent = false;
237926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_image = newImage;
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_hasPendingLoadEvent = newImage;
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_imageComplete = !newImage;
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (newImage) {
24407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            updateRenderer();
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If newImage is cached, addClient() will result in the load event
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // being queued to fire. Ensure this happens after beforeload is
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // dispatched.
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            newImage->addClient(this);
250f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        } else {
251f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            updateRenderer();
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
253f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (oldImage)
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            oldImage->removeClient(this);
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (RenderImageResource* imageResource = renderImageResource())
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        imageResource->resetAnimation();
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Only consider updating the protection ref-count of the Element immediately before returning
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // from this function as doing so might result in the destruction of this ImageLoader.
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    updatedHasPendingEvent();
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
266d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void ImageLoader::updateFromElement(LoadType loadType)
267d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
268d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    AtomicString attr = m_element->imageSourceURL();
269d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
270d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (!m_failedLoadURL.isEmpty() && attr == m_failedLoadURL)
271d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        return;
272d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
273f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    // If we have a pending task, we have to clear it -- either we're
274f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    // now loading immediately, or we need to reset the task's state.
275f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (m_pendingTask) {
276f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        m_pendingTask->clearLoader();
277f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        m_pendingTask.clear();
278f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
279f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
280d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    KURL url = imageURL();
281d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (!attr.isNull() && !url.isNull()) {
282d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        bool loadImmediately = shouldLoadImmediately(url) || (loadType == ForceLoadImmediately);
283d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        if (loadImmediately) {
284d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            doUpdateFromElement(false);
285d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        } else {
286d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            OwnPtr<Task> task = adoptPtr(new Task(this));
287d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            m_pendingTask = task->createWeakPtr();
288d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            Microtask::enqueueMicrotask(task.release());
289d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            m_delayLoad = adoptPtr(new IncrementLoadEventDelayCount(m_element->document()));
290d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            return;
291d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        }
292d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    } else {
293d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        doUpdateFromElement(false);
294d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
295d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
296d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ImageLoader::updateFromElementIgnoringPreviousError()
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
299926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    clearFailedLoadURL();
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    updateFromElement();
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
303d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)KURL ImageLoader::imageURL() const
304d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
305d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    KURL url;
306d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
307d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // Don't load images for inactive documents. We don't want to slow down the
308d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // raw HTML parsing case by loading images we don't intend to display.
309d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    Document& document = m_element->document();
310d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (!document.isActive())
311d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        return url;
312d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
313d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    AtomicString attr = m_element->imageSourceURL();
314d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
315d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // Do not load any image if the 'src' attribute is missing or if it is
316d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // an empty string.
317d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (!attr.isNull() && !stripLeadingAndTrailingHTMLSpaces(attr).isEmpty()) {
318d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        url = document.completeURL(sourceURI(attr));
319d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
320d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return url;
321d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
322d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
323d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)bool ImageLoader::shouldLoadImmediately(const KURL& url) const
324d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
325d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (m_loadManually)
326d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        return true;
327d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (isHTMLObjectElement(m_element) || isHTMLEmbedElement(m_element))
328d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        return true;
329d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
330d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (url.protocolIsData())
331d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        return true;
332d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (memoryCache()->resourceForURL(url))
333d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        return true;
334d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return false;
335d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
336d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
337fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid ImageLoader::notifyFinished(Resource* resource)
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_failedLoadURL.isEmpty());
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(resource == m_image.get());
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_imageComplete = true;
34307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    updateRenderer();
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_hasPendingLoadEvent)
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
34809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (resource->errorOccurred()) {
34909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        loadEventSender().cancelEvent(this);
35009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_hasPendingLoadEvent = false;
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_hasPendingErrorEvent = true;
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        errorEventSender().dispatchEventSoon(this);
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Only consider updating the protection ref-count of the Element immediately before returning
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // from this function as doing so might result in the destruction of this ImageLoader.
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        updatedHasPendingEvent();
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (resource->wasCanceled()) {
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_hasPendingLoadEvent = false;
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Only consider updating the protection ref-count of the Element immediately before returning
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // from this function as doing so might result in the destruction of this ImageLoader.
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        updatedHasPendingEvent();
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    loadEventSender().dispatchEventSoon(this);
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderImageResource* ImageLoader::renderImageResource()
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
372926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RenderObject* renderer = m_element->renderer();
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!renderer)
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We don't return style generated image because it doesn't belong to the ImageLoader.
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // See <https://bugs.webkit.org/show_bug.cgi?id=42840>
3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (renderer->isImage() && !static_cast<RenderImage*>(renderer)->isGeneratedContent())
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return toRenderImage(renderer)->imageResource();
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (renderer->isSVGImage())
3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return toRenderSVGImage(renderer)->imageResource();
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (renderer->isVideo())
3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return toRenderVideo(renderer)->imageResource();
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ImageLoader::updateRenderer()
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderImageResource* imageResource = renderImageResource();
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!imageResource)
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Only update the renderer if it doesn't have an image or if what we have
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // is a complete image.  This prevents flickering in the case where a dynamic
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // change is happening between two images.
4013c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    ImageResource* cachedImage = imageResource->cachedImage();
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_image != cachedImage && (m_imageComplete || !cachedImage))
4033c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        imageResource->setImageResource(m_image.get());
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ImageLoader::updatedHasPendingEvent()
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If an Element that does image loading is removed from the DOM the load/error event for the image is still observable.
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // As long as the ImageLoader is actively loading, the Element itself needs to be ref'ed to keep it from being
4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // destroyed by DOM manipulation or garbage collection.
4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If such an Element wishes for the load to stop when removed from the DOM it needs to stop the ImageLoader explicitly.
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool wasProtected = m_elementIsProtected;
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_elementIsProtected = m_hasPendingLoadEvent || m_hasPendingErrorEvent;
4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (wasProtected == m_elementIsProtected)
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
417926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_elementIsProtected) {
418926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (m_derefElementTimer.isActive())
419926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            m_derefElementTimer.stop();
420926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        else
4215d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            m_keepAlive = m_element;
422926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    } else {
423926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ASSERT(!m_derefElementTimer.isActive());
424d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_derefElementTimer.startOneShot(0, FROM_HERE);
42502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    }
426926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
427926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
428926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void ImageLoader::timerFired(Timer<ImageLoader>*)
429926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
4305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_keepAlive.clear();
4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ImageLoader::dispatchPendingEvent(ImageEventSender* eventSender)
4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
43507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    ASSERT(eventSender == &loadEventSender() || eventSender == &errorEventSender());
4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const AtomicString& eventType = eventSender->eventType();
4371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (eventType == EventTypeNames::load)
4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        dispatchPendingLoadEvent();
4391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (eventType == EventTypeNames::error)
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        dispatchPendingErrorEvent();
4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ImageLoader::dispatchPendingLoadEvent()
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_hasPendingLoadEvent)
4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_image)
4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_hasPendingLoadEvent = false;
4501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (element()->document().frame())
451926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        dispatchLoadEvent();
4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Only consider updating the protection ref-count of the Element immediately before returning
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // from this function as doing so might result in the destruction of this ImageLoader.
4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    updatedHasPendingEvent();
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ImageLoader::dispatchPendingErrorEvent()
4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_hasPendingErrorEvent)
4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_hasPendingErrorEvent = false;
463f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
4641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (element()->document().frame())
4651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        element()->dispatchEvent(Event::create(EventTypeNames::error));
466926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
467926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Only consider updating the protection ref-count of the Element immediately before returning
468926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // from this function as doing so might result in the destruction of this ImageLoader.
469926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    updatedHasPendingEvent();
4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4721fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdochvoid ImageLoader::addClient(ImageLoaderClient* client)
4731fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch{
4741fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    if (client->requestsHighLiveResourceCachePriority()) {
4751fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        if (m_image && !m_highPriorityClientCount++)
476a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            memoryCache()->updateDecodedResource(m_image.get(), UpdateForPropertyChange, MemoryCacheLiveResourcePriorityHigh);
4771fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    }
478d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#if ENABLE(OILPAN)
479d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    m_clients.add(client, adoptPtr(new ImageLoaderClientRemover(*this, *client)));
480d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#else
4811fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    m_clients.add(client);
482d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#endif
4831fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch}
484d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
485d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void ImageLoader::willRemoveClient(ImageLoaderClient& client)
4861fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch{
487d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (client.requestsHighLiveResourceCachePriority()) {
4881fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        ASSERT(m_highPriorityClientCount);
4891fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        m_highPriorityClientCount--;
4901fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        if (m_image && !m_highPriorityClientCount)
491a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            memoryCache()->updateDecodedResource(m_image.get(), UpdateForPropertyChange, MemoryCacheLiveResourcePriorityLow);
4921fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    }
493d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
494d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
495d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void ImageLoader::removeClient(ImageLoaderClient* client)
496d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
497d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    willRemoveClient(*client);
4981fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    m_clients.remove(client);
4991fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch}
5001fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ImageLoader::dispatchPendingLoadEvents()
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    loadEventSender().dispatchPendingEvents();
5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ImageLoader::dispatchPendingErrorEvents()
5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    errorEventSender().dispatchPendingEvents();
5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ImageLoader::elementDidMoveToNewDocument()
5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
513d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (m_delayLoad) {
514d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        m_delayLoad->documentChanged(m_element->document());
515d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
516926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    clearFailedLoadURL();
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setImage(0);
5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5201fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdochvoid ImageLoader::sourceImageChanged()
5211fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch{
522d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#if ENABLE(OILPAN)
523d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    PersistentHeapHashMap<WeakMember<ImageLoaderClient>, OwnPtr<ImageLoaderClientRemover> >::iterator end = m_clients.end();
524d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    for (PersistentHeapHashMap<WeakMember<ImageLoaderClient>, OwnPtr<ImageLoaderClientRemover> >::iterator it = m_clients.begin(); it != end; ++it) {
525d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        it->key->notifyImageSourceChanged();
526d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
527d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#else
528d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    HashSet<ImageLoaderClient*>::iterator end = m_clients.end();
529d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    for (HashSet<ImageLoaderClient*>::iterator it = m_clients.begin(); it != end; ++it) {
5301fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        ImageLoaderClient* handle = *it;
5311fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        handle->notifyImageSourceChanged();
5321fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    }
533d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#endif
5341fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch}
5351fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch
536926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline void ImageLoader::clearFailedLoadURL()
537926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
538926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_failedLoadURL = AtomicString();
539926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
540926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
541d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#if ENABLE(OILPAN)
542d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)ImageLoader::ImageLoaderClientRemover::~ImageLoaderClientRemover()
543d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
544d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    m_loader.willRemoveClient(m_client);
545d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
546d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#endif
547d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
549