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