1/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * Copyright (C) 2004, 2009 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB.  If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#ifndef ImageLoader_h
24#define ImageLoader_h
25
26#include "CachedImageClient.h"
27#include "CachedResourceHandle.h"
28#include "Timer.h"
29#include <wtf/text/AtomicString.h>
30
31namespace WebCore {
32
33class Element;
34class ImageLoader;
35class RenderImageResource;
36
37template<typename T> class EventSender;
38typedef EventSender<ImageLoader> ImageEventSender;
39
40class ImageLoader : public CachedImageClient {
41    WTF_MAKE_FAST_ALLOCATED;
42public:
43    virtual ~ImageLoader();
44
45    // This function should be called when the element is attached to a document; starts
46    // loading if a load hasn't already been started.
47    void updateFromElement();
48
49    // This function should be called whenever the 'src' attribute is set, even if its value
50    // doesn't change; starts new load unconditionally (matches Firefox and Opera behavior).
51    void updateFromElementIgnoringPreviousError();
52
53    void elementDidMoveToNewDocument();
54
55    Element& element() { return m_element; }
56    const Element& element() const { return m_element; }
57
58    bool imageComplete() const { return m_imageComplete; }
59
60    CachedImage* image() const { return m_image.get(); }
61    void setImage(CachedImage*); // Cancels pending beforeload and load events, and doesn't dispatch new ones.
62
63    void setLoadManually(bool loadManually) { m_loadManually = loadManually; }
64
65    bool hasPendingBeforeLoadEvent() const { return m_hasPendingBeforeLoadEvent; }
66    bool hasPendingActivity() const { return m_hasPendingLoadEvent || m_hasPendingErrorEvent; }
67
68    void dispatchPendingEvent(ImageEventSender*);
69
70    static void dispatchPendingBeforeLoadEvents();
71    static void dispatchPendingLoadEvents();
72    static void dispatchPendingErrorEvents();
73
74protected:
75    explicit ImageLoader(Element&);
76    virtual void notifyFinished(CachedResource*) override;
77
78private:
79    virtual void dispatchLoadEvent() = 0;
80    virtual String sourceURI(const AtomicString&) const = 0;
81
82    void updatedHasPendingEvent();
83
84    void dispatchPendingBeforeLoadEvent();
85    void dispatchPendingLoadEvent();
86    void dispatchPendingErrorEvent();
87
88    RenderImageResource* renderImageResource();
89    void updateRenderer();
90
91    void setImageWithoutConsideringPendingLoadEvent(CachedImage*);
92    void clearFailedLoadURL();
93
94    void timerFired(Timer<ImageLoader>&);
95
96    Element& m_element;
97    CachedResourceHandle<CachedImage> m_image;
98    Timer<ImageLoader> m_derefElementTimer;
99    AtomicString m_failedLoadURL;
100    bool m_hasPendingBeforeLoadEvent : 1;
101    bool m_hasPendingLoadEvent : 1;
102    bool m_hasPendingErrorEvent : 1;
103    bool m_imageComplete : 1;
104    bool m_loadManually : 1;
105    bool m_elementIsProtected : 1;
106};
107
108}
109
110#endif
111