File: ImageLoader.h

package info (click to toggle)
chromium-browser 57.0.2987.98-1~deb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 2,637,852 kB
  • ctags: 2,544,394
  • sloc: cpp: 12,815,961; ansic: 3,676,222; python: 1,147,112; asm: 526,608; java: 523,212; xml: 286,794; perl: 92,654; sh: 86,408; objc: 73,271; makefile: 27,698; cs: 18,487; yacc: 13,031; tcl: 12,957; pascal: 4,875; ml: 4,716; lex: 3,904; sql: 3,862; ruby: 1,982; lisp: 1,508; php: 1,368; exp: 404; awk: 325; csh: 117; jsp: 39; sed: 37
file content (176 lines) | stat: -rw-r--r-- 6,182 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 * Copyright (C) 2004, 2009 Apple Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#ifndef ImageLoader_h
#define ImageLoader_h

#include "core/CoreExport.h"
#include "core/loader/resource/ImageResource.h"
#include "core/loader/resource/ImageResourceContent.h"
#include "core/loader/resource/ImageResourceObserver.h"
#include "platform/heap/Handle.h"
#include "wtf/HashSet.h"
#include "wtf/WeakPtr.h"
#include "wtf/text/AtomicString.h"
#include <memory>

namespace blink {

class IncrementLoadEventDelayCount;
class Element;
class ImageLoader;
class LayoutImageResource;

template <typename T>
class EventSender;
using ImageEventSender = EventSender<ImageLoader>;

class CORE_EXPORT ImageLoader : public GarbageCollectedFinalized<ImageLoader>,
                                public ImageResourceObserver {
  USING_PRE_FINALIZER(ImageLoader, dispose);

 public:
  explicit ImageLoader(Element*);
  ~ImageLoader() override;

  DECLARE_TRACE();

  enum UpdateFromElementBehavior {
    // This should be the update behavior when the element is attached to a
    // document, or when DOM mutations trigger a new load. Starts loading if a
    // load hasn't already been started.
    UpdateNormal,
    // This should be the update behavior when the resource was changed (via
    // 'src', 'srcset' or 'sizes'). Starts a new load even if a previous load of
    // the same resource have failed, to match Firefox's behavior.
    // FIXME - Verify that this is the right behavior according to the spec.
    UpdateIgnorePreviousError,
    // This forces the image to update its intrinsic size, even if the image
    // source has not changed.
    UpdateSizeChanged,
    // This force the image to refetch and reload the image source, even if it
    // has not changed.
    UpdateForcedReload
  };

  enum BypassMainWorldBehavior { BypassMainWorldCSP, DoNotBypassMainWorldCSP };

  void updateFromElement(UpdateFromElementBehavior = UpdateNormal,
                         ReferrerPolicy = ReferrerPolicyDefault);

  void elementDidMoveToNewDocument();

  Element* element() const { return m_element; }
  bool imageComplete() const { return m_imageComplete && !m_pendingTask; }

  ImageResourceContent* image() const { return m_image.get(); }
  ImageResource* imageResourceForImageDocument() const {
    return m_imageResourceForImageDocument;
  }
  // Cancels pending load events, and doesn't dispatch new ones.
  void setImage(ImageResourceContent*);

  bool isLoadingImageDocument() { return m_loadingImageDocument; }
  void setLoadingImageDocument() { m_loadingImageDocument = true; }

  bool hasPendingActivity() const {
    return m_hasPendingLoadEvent || m_hasPendingErrorEvent || m_pendingTask;
  }

  bool hasPendingError() const { return m_hasPendingErrorEvent; }

  bool hadError() const { return !m_failedLoadURL.isEmpty(); }

  void dispatchPendingEvent(ImageEventSender*);

  static void dispatchPendingLoadEvents();
  static void dispatchPendingErrorEvents();

  bool getImageAnimationPolicy(ImageAnimationPolicy&) final;

 protected:
  void imageNotifyFinished(ImageResourceContent*) override;

 private:
  class Task;

  // Called from the task or from updateFromElement to initiate the load.
  void doUpdateFromElement(BypassMainWorldBehavior,
                           UpdateFromElementBehavior,
                           const KURL&,
                           ReferrerPolicy = ReferrerPolicyDefault);

  virtual void dispatchLoadEvent() = 0;
  virtual void noImageResourceToLoad() {}

  void updatedHasPendingEvent();

  void dispatchPendingLoadEvent();
  void dispatchPendingErrorEvent();

  LayoutImageResource* layoutImageResource();
  void updateLayoutObject();

  void setImageWithoutConsideringPendingLoadEvent(ImageResourceContent*);
  void clearFailedLoadURL();
  void dispatchErrorEvent();
  void crossSiteOrCSPViolationOccurred(AtomicString);
  void enqueueImageLoadingMicroTask(UpdateFromElementBehavior, ReferrerPolicy);

  void timerFired(TimerBase*);

  KURL imageSourceToKURL(AtomicString) const;

  // Used to determine whether to immediately initiate the load or to schedule a
  // microtask.
  bool shouldLoadImmediately(const KURL&) const;

  // For Oilpan, we must run dispose() as a prefinalizer and call
  // m_image->removeClient(this) (and more.) Otherwise, the ImageResource can
  // invoke didAddClient() for the ImageLoader that is about to die in the
  // current lazy sweeping, and the didAddClient() can access on-heap objects
  // that have already been finalized in the current lazy sweeping.
  void dispose();

  Member<Element> m_element;
  Member<ImageResourceContent> m_image;
  Member<ImageResource> m_imageResourceForImageDocument;
  // FIXME: Oilpan: We might be able to remove this Persistent hack when
  // ImageResourceClient is traceable.
  GC_PLUGIN_IGNORE("http://crbug.com/383741")
  Persistent<Element> m_keepAlive;

  TaskRunnerTimer<ImageLoader> m_derefElementTimer;
  AtomicString m_failedLoadURL;
  WeakPtr<Task> m_pendingTask;  // owned by Microtask
  std::unique_ptr<IncrementLoadEventDelayCount> m_loadDelayCounter;
  bool m_hasPendingLoadEvent : 1;
  bool m_hasPendingErrorEvent : 1;
  bool m_imageComplete : 1;
  bool m_loadingImageDocument : 1;
  bool m_elementIsProtected : 1;
  bool m_suppressErrorEvents : 1;
};

}  // namespace blink

#endif