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, 2009 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) 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef ImageLoader_h 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define ImageLoader_h 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 26e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ImageResource.h" 27e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ImageResourceClient.h" 28e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ResourcePtr.h" 29f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#include "platform/heap/Handle.h" 301fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch#include "wtf/HashSet.h" 31d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "wtf/WeakPtr.h" 32e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/text/AtomicString.h" 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 34c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 36d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)class IncrementLoadEventDelayCount; 37197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass FetchRequest; 38197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass Document; 39d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 40d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class ImageLoaderClient : public WillBeGarbageCollectedMixin { 411fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdochpublic: 421fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch virtual void notifyImageSourceChanged() = 0; 431fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch 443c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // Determines whether the observed ImageResource should have higher priority in the decoded resources cache. 451fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch virtual bool requestsHighLiveResourceCachePriority() { return false; } 461fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch 47323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) virtual void trace(Visitor*) { } 48d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 491fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdochprotected: 501fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch ImageLoaderClient() { } 511fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch}; 521fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Element; 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class ImageLoader; 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class RenderImageResource; 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<typename T> class EventSender; 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef EventSender<ImageLoader> ImageEventSender; 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)class ImageLoader : public NoBaseWillBeGarbageCollectedFinalized<ImageLoader>, public ImageResourceClient { 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) explicit ImageLoader(Element*); 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual ~ImageLoader(); 645d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) void trace(Visitor*); 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 66d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) enum LoadType { 67d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LoadNormally, 68d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ForceLoadImmediately 69d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) }; 70d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 71197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch enum UpdateFromElementBehavior { 72197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // This should be the update behavior when the element is attached to a document, or when DOM mutations trigger a new load. 73197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // Starts loading if a load hasn't already been started. 74197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch UpdateNormal, 75197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // This should be the update behavior when the resource was changed (via 'src', 'srcset' or 'sizes'). 76197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // Starts a new load even if a previous load of the same resource have failed, to match Firefox's behavior. 77197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // FIXME - Verify that this is the right behavior according to the spec. 78c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) UpdateIgnorePreviousError, 79c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // This forces the image to update its intrinsic size, even if the image source has not changed. 80c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) UpdateSizeChanged 81197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch }; 82197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 83197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch enum BypassMainWorldBehavior { 84197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch BypassMainWorldCSP, 85197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch DoNotBypassMainWorldCSP 86197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch }; 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 88197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch void updateFromElement(UpdateFromElementBehavior = UpdateNormal, LoadType = LoadNormally); 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void elementDidMoveToNewDocument(); 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Element* element() const { return m_element; } 93d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) bool imageComplete() const 94d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) { 95d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return m_imageComplete && !m_pendingTask; 96d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 983c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch ImageResource* image() const { return m_image.get(); } 9907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch void setImage(ImageResource*); // Cancels pending load events, and doesn't dispatch new ones. 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 101197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch void setLoadingImageDocument() { m_loadingImageDocument = true; } 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 103d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) bool hasPendingActivity() const 104d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) { 105d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return m_hasPendingLoadEvent || m_hasPendingErrorEvent || m_pendingTask; 106d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void dispatchPendingEvent(ImageEventSender*); 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static void dispatchPendingLoadEvents(); 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static void dispatchPendingErrorEvents(); 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1131fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch void addClient(ImageLoaderClient*); 1141fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch void removeClient(ImageLoaderClient*); 1151fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)protected: 11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual void notifyFinished(Resource*) OVERRIDE; 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 120d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) class Task; 121d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 122d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // Called from the task or from updateFromElement to initiate the load. 123c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) void doUpdateFromElement(BypassMainWorldBehavior, UpdateFromElementBehavior); 124d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual void dispatchLoadEvent() = 0; 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual String sourceURI(const AtomicString&) const = 0; 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void updatedHasPendingEvent(); 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void dispatchPendingLoadEvent(); 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void dispatchPendingErrorEvent(); 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderImageResource* renderImageResource(); 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void updateRenderer(); 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1363c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch void setImageWithoutConsideringPendingLoadEvent(ImageResource*); 1371fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch void sourceImageChanged(); 138926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) void clearFailedLoadURL(); 139197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch void crossSiteOrCSPViolationOccured(AtomicString); 140c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) void enqueueImageLoadingMicroTask(UpdateFromElementBehavior); 141197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch static ResourcePtr<ImageResource> createImageResourceForImageDocument(Document&, FetchRequest&); 142926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 143926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) void timerFired(Timer<ImageLoader>*); 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 145197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch KURL imageSourceToKURL(AtomicString) const; 146d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 147d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // Used to determine whether to immediately initiate the load 148d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // or to schedule a microtask. 149197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch bool shouldLoadImmediately(const KURL&, LoadType) const; 150d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 151d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) void willRemoveClient(ImageLoaderClient&); 152d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 1535d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RawPtrWillBeMember<Element> m_element; 1543c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch ResourcePtr<ImageResource> m_image; 1555d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // FIXME: Oilpan: We might be able to remove this Persistent hack when 1565d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // ImageResourceClient is traceable. 1575d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) GC_PLUGIN_IGNORE("http://crbug.com/383741") 1585d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RefPtrWillBePersistent<Element> m_keepAlive; 159d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#if ENABLE(OILPAN) 160d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) class ImageLoaderClientRemover { 161d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) public: 162d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ImageLoaderClientRemover(ImageLoader& loader, ImageLoaderClient& client) : m_loader(loader), m_client(client) { } 163d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ~ImageLoaderClientRemover(); 164d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 165d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) private: 166d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ImageLoader& m_loader; 167d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ImageLoaderClient& m_client; 168d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) }; 169d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) friend class ImageLoaderClientRemover; 1705d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Oilpan: This ImageLoader object must outlive its clients because they 1715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // need to call ImageLoader::willRemoveClient before they 1725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // die. Non-Persistent HeapHashMap doesn't work well because weak processing 1735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // for HeapHashMap is not triggered when both of ImageLoader and 1745d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // ImageLoaderClient are unreachable. 1755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) GC_PLUGIN_IGNORE("http://crbug.com/383742") 176d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) PersistentHeapHashMap<WeakMember<ImageLoaderClient>, OwnPtr<ImageLoaderClientRemover> > m_clients; 177d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#else 178d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) HashSet<ImageLoaderClient*> m_clients; 179d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#endif 180926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Timer<ImageLoader> m_derefElementTimer; 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AtomicString m_failedLoadURL; 182d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) WeakPtr<Task> m_pendingTask; // owned by Microtask 183197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch OwnPtr<IncrementLoadEventDelayCount> m_loadDelayCounter; 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool m_hasPendingLoadEvent : 1; 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool m_hasPendingErrorEvent : 1; 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool m_imageComplete : 1; 187197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch bool m_loadingImageDocument : 1; 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool m_elementIsProtected : 1; 1891fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch unsigned m_highPriorityClientCount; 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 195