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