OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserv
ed. | 4 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserv
ed. |
5 * | 5 * |
6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include "core/fetch/ResourceFetcher.h" | 31 #include "core/fetch/ResourceFetcher.h" |
32 #include "core/html/HTMLObjectElement.h" | 32 #include "core/html/HTMLObjectElement.h" |
33 #include "core/html/parser/HTMLParserIdioms.h" | 33 #include "core/html/parser/HTMLParserIdioms.h" |
34 #include "core/rendering/RenderImage.h" | 34 #include "core/rendering/RenderImage.h" |
35 #include "core/rendering/RenderVideo.h" | 35 #include "core/rendering/RenderVideo.h" |
36 #include "core/rendering/svg/RenderSVGImage.h" | 36 #include "core/rendering/svg/RenderSVGImage.h" |
37 #include "platform/weborigin/SecurityOrigin.h" | 37 #include "platform/weborigin/SecurityOrigin.h" |
38 | 38 |
39 namespace WebCore { | 39 namespace WebCore { |
40 | 40 |
41 static ImageEventSender& beforeLoadEventSender() | |
42 { | |
43 DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::beforeload)); | |
44 return sender; | |
45 } | |
46 | |
47 static ImageEventSender& loadEventSender() | 41 static ImageEventSender& loadEventSender() |
48 { | 42 { |
49 DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::load)); | 43 DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::load)); |
50 return sender; | 44 return sender; |
51 } | 45 } |
52 | 46 |
53 static ImageEventSender& errorEventSender() | 47 static ImageEventSender& errorEventSender() |
54 { | 48 { |
55 DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::error)); | 49 DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::error)); |
56 return sender; | 50 return sender; |
57 } | 51 } |
58 | 52 |
59 static inline bool pageIsBeingDismissed(Document* document) | 53 static inline bool pageIsBeingDismissed(Document* document) |
60 { | 54 { |
61 return document->pageDismissalEventBeingDispatched() != Document::NoDismissa
l; | 55 return document->pageDismissalEventBeingDispatched() != Document::NoDismissa
l; |
62 } | 56 } |
63 | 57 |
64 ImageLoader::ImageLoader(Element* element) | 58 ImageLoader::ImageLoader(Element* element) |
65 : m_element(element) | 59 : m_element(element) |
66 , m_image(0) | 60 , m_image(0) |
67 , m_derefElementTimer(this, &ImageLoader::timerFired) | 61 , m_derefElementTimer(this, &ImageLoader::timerFired) |
68 , m_hasPendingBeforeLoadEvent(false) | |
69 , m_hasPendingLoadEvent(false) | 62 , m_hasPendingLoadEvent(false) |
70 , m_hasPendingErrorEvent(false) | 63 , m_hasPendingErrorEvent(false) |
71 , m_imageComplete(true) | 64 , m_imageComplete(true) |
72 , m_loadManually(false) | 65 , m_loadManually(false) |
73 , m_elementIsProtected(false) | 66 , m_elementIsProtected(false) |
74 , m_highPriorityClientCount(0) | 67 , m_highPriorityClientCount(0) |
75 { | 68 { |
76 } | 69 } |
77 | 70 |
78 ImageLoader::~ImageLoader() | 71 ImageLoader::~ImageLoader() |
79 { | 72 { |
80 if (m_image) | 73 if (m_image) |
81 m_image->removeClient(this); | 74 m_image->removeClient(this); |
82 | 75 |
83 ASSERT(m_hasPendingBeforeLoadEvent || !beforeLoadEventSender().hasPendingEve
nts(this)); | |
84 if (m_hasPendingBeforeLoadEvent) | |
85 beforeLoadEventSender().cancelEvent(this); | |
86 | |
87 ASSERT(m_hasPendingLoadEvent || !loadEventSender().hasPendingEvents(this)); | 76 ASSERT(m_hasPendingLoadEvent || !loadEventSender().hasPendingEvents(this)); |
88 if (m_hasPendingLoadEvent) | 77 if (m_hasPendingLoadEvent) |
89 loadEventSender().cancelEvent(this); | 78 loadEventSender().cancelEvent(this); |
90 | 79 |
91 ASSERT(m_hasPendingErrorEvent || !errorEventSender().hasPendingEvents(this))
; | 80 ASSERT(m_hasPendingErrorEvent || !errorEventSender().hasPendingEvents(this))
; |
92 if (m_hasPendingErrorEvent) | 81 if (m_hasPendingErrorEvent) |
93 errorEventSender().cancelEvent(this); | 82 errorEventSender().cancelEvent(this); |
94 | 83 |
95 // If the ImageLoader is being destroyed but it is still protecting its imag
e-loading Element, | 84 // If the ImageLoader is being destroyed but it is still protecting its imag
e-loading Element, |
96 // remove that protection here. | 85 // remove that protection here. |
(...skipping 10 matching lines...) Expand all Loading... |
107 updatedHasPendingEvent(); | 96 updatedHasPendingEvent(); |
108 } | 97 } |
109 | 98 |
110 void ImageLoader::setImageWithoutConsideringPendingLoadEvent(ImageResource* newI
mage) | 99 void ImageLoader::setImageWithoutConsideringPendingLoadEvent(ImageResource* newI
mage) |
111 { | 100 { |
112 ASSERT(m_failedLoadURL.isEmpty()); | 101 ASSERT(m_failedLoadURL.isEmpty()); |
113 ImageResource* oldImage = m_image.get(); | 102 ImageResource* oldImage = m_image.get(); |
114 if (newImage != oldImage) { | 103 if (newImage != oldImage) { |
115 sourceImageChanged(); | 104 sourceImageChanged(); |
116 m_image = newImage; | 105 m_image = newImage; |
117 if (m_hasPendingBeforeLoadEvent) { | |
118 beforeLoadEventSender().cancelEvent(this); | |
119 m_hasPendingBeforeLoadEvent = false; | |
120 } | |
121 if (m_hasPendingLoadEvent) { | 106 if (m_hasPendingLoadEvent) { |
122 loadEventSender().cancelEvent(this); | 107 loadEventSender().cancelEvent(this); |
123 m_hasPendingLoadEvent = false; | 108 m_hasPendingLoadEvent = false; |
124 } | 109 } |
125 if (m_hasPendingErrorEvent) { | 110 if (m_hasPendingErrorEvent) { |
126 errorEventSender().cancelEvent(this); | 111 errorEventSender().cancelEvent(this); |
127 m_hasPendingErrorEvent = false; | 112 m_hasPendingErrorEvent = false; |
128 } | 113 } |
129 m_imageComplete = true; | 114 m_imageComplete = true; |
130 if (newImage) | 115 if (newImage) |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 } else if (!attr.isNull()) { | 169 } else if (!attr.isNull()) { |
185 // Fire an error event if the url is empty. | 170 // Fire an error event if the url is empty. |
186 m_hasPendingErrorEvent = true; | 171 m_hasPendingErrorEvent = true; |
187 errorEventSender().dispatchEventSoon(this); | 172 errorEventSender().dispatchEventSoon(this); |
188 } | 173 } |
189 | 174 |
190 ImageResource* oldImage = m_image.get(); | 175 ImageResource* oldImage = m_image.get(); |
191 if (newImage != oldImage) { | 176 if (newImage != oldImage) { |
192 sourceImageChanged(); | 177 sourceImageChanged(); |
193 | 178 |
194 if (m_hasPendingBeforeLoadEvent) { | |
195 beforeLoadEventSender().cancelEvent(this); | |
196 m_hasPendingBeforeLoadEvent = false; | |
197 } | |
198 if (m_hasPendingLoadEvent) { | 179 if (m_hasPendingLoadEvent) { |
199 loadEventSender().cancelEvent(this); | 180 loadEventSender().cancelEvent(this); |
200 m_hasPendingLoadEvent = false; | 181 m_hasPendingLoadEvent = false; |
201 } | 182 } |
202 | 183 |
203 // Cancel error events that belong to the previous load, which is now ca
ncelled by changing the src attribute. | 184 // Cancel error events that belong to the previous load, which is now ca
ncelled by changing the src attribute. |
204 // If newImage is null and m_hasPendingErrorEvent is true, we know the e
rror event has been just posted by | 185 // If newImage is null and m_hasPendingErrorEvent is true, we know the e
rror event has been just posted by |
205 // this load and we should not cancel the event. | 186 // this load and we should not cancel the event. |
206 // FIXME: If both previous load and this one got blocked with an error,
we can receive one error event instead of two. | 187 // FIXME: If both previous load and this one got blocked with an error,
we can receive one error event instead of two. |
207 if (m_hasPendingErrorEvent && newImage) { | 188 if (m_hasPendingErrorEvent && newImage) { |
208 errorEventSender().cancelEvent(this); | 189 errorEventSender().cancelEvent(this); |
209 m_hasPendingErrorEvent = false; | 190 m_hasPendingErrorEvent = false; |
210 } | 191 } |
211 | 192 |
212 m_image = newImage; | 193 m_image = newImage; |
213 m_hasPendingBeforeLoadEvent = !m_element->document().isImageDocument() &
& newImage; | |
214 m_hasPendingLoadEvent = newImage; | 194 m_hasPendingLoadEvent = newImage; |
215 m_imageComplete = !newImage; | 195 m_imageComplete = !newImage; |
216 | 196 |
217 if (newImage) { | 197 if (newImage) { |
218 if (!m_element->document().isImageDocument()) { | 198 updateRenderer(); |
219 if (!m_element->document().hasListenerType(Document::BEFORELOAD_
LISTENER)) | |
220 dispatchPendingBeforeLoadEvent(); | |
221 else | |
222 beforeLoadEventSender().dispatchEventSoon(this); | |
223 } else | |
224 updateRenderer(); | |
225 | 199 |
226 // If newImage is cached, addClient() will result in the load event | 200 // If newImage is cached, addClient() will result in the load event |
227 // being queued to fire. Ensure this happens after beforeload is | 201 // being queued to fire. Ensure this happens after beforeload is |
228 // dispatched. | 202 // dispatched. |
229 newImage->addClient(this); | 203 newImage->addClient(this); |
230 } else { | 204 } else { |
231 updateRenderer(); | 205 updateRenderer(); |
232 } | 206 } |
233 | 207 |
234 if (oldImage) | 208 if (oldImage) |
(...skipping 13 matching lines...) Expand all Loading... |
248 clearFailedLoadURL(); | 222 clearFailedLoadURL(); |
249 updateFromElement(); | 223 updateFromElement(); |
250 } | 224 } |
251 | 225 |
252 void ImageLoader::notifyFinished(Resource* resource) | 226 void ImageLoader::notifyFinished(Resource* resource) |
253 { | 227 { |
254 ASSERT(m_failedLoadURL.isEmpty()); | 228 ASSERT(m_failedLoadURL.isEmpty()); |
255 ASSERT(resource == m_image.get()); | 229 ASSERT(resource == m_image.get()); |
256 | 230 |
257 m_imageComplete = true; | 231 m_imageComplete = true; |
258 if (!hasPendingBeforeLoadEvent()) | 232 updateRenderer(); |
259 updateRenderer(); | |
260 | 233 |
261 if (!m_hasPendingLoadEvent) | 234 if (!m_hasPendingLoadEvent) |
262 return; | 235 return; |
263 | 236 |
264 if (resource->errorOccurred()) { | 237 if (resource->errorOccurred()) { |
265 loadEventSender().cancelEvent(this); | 238 loadEventSender().cancelEvent(this); |
266 m_hasPendingLoadEvent = false; | 239 m_hasPendingLoadEvent = false; |
267 | 240 |
268 m_hasPendingErrorEvent = true; | 241 m_hasPendingErrorEvent = true; |
269 errorEventSender().dispatchEventSoon(this); | 242 errorEventSender().dispatchEventSoon(this); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 } | 314 } |
342 } | 315 } |
343 | 316 |
344 void ImageLoader::timerFired(Timer<ImageLoader>*) | 317 void ImageLoader::timerFired(Timer<ImageLoader>*) |
345 { | 318 { |
346 m_element->deref(); | 319 m_element->deref(); |
347 } | 320 } |
348 | 321 |
349 void ImageLoader::dispatchPendingEvent(ImageEventSender* eventSender) | 322 void ImageLoader::dispatchPendingEvent(ImageEventSender* eventSender) |
350 { | 323 { |
351 ASSERT(eventSender == &beforeLoadEventSender() || eventSender == &loadEventS
ender() || eventSender == &errorEventSender()); | 324 ASSERT(eventSender == &loadEventSender() || eventSender == &errorEventSender
()); |
352 const AtomicString& eventType = eventSender->eventType(); | 325 const AtomicString& eventType = eventSender->eventType(); |
353 if (eventType == EventTypeNames::beforeload) | |
354 dispatchPendingBeforeLoadEvent(); | |
355 if (eventType == EventTypeNames::load) | 326 if (eventType == EventTypeNames::load) |
356 dispatchPendingLoadEvent(); | 327 dispatchPendingLoadEvent(); |
357 if (eventType == EventTypeNames::error) | 328 if (eventType == EventTypeNames::error) |
358 dispatchPendingErrorEvent(); | 329 dispatchPendingErrorEvent(); |
359 } | 330 } |
360 | 331 |
361 void ImageLoader::dispatchPendingBeforeLoadEvent() | |
362 { | |
363 if (!m_hasPendingBeforeLoadEvent) | |
364 return; | |
365 if (!m_image) | |
366 return; | |
367 if (!m_element->document().frame()) | |
368 return; | |
369 m_hasPendingBeforeLoadEvent = false; | |
370 if (m_element->dispatchBeforeLoadEvent(m_image->url().string())) { | |
371 updateRenderer(); | |
372 return; | |
373 } | |
374 if (m_image) { | |
375 m_image->removeClient(this); | |
376 m_image = 0; | |
377 } | |
378 | |
379 loadEventSender().cancelEvent(this); | |
380 m_hasPendingLoadEvent = false; | |
381 | |
382 if (isHTMLObjectElement(*m_element)) | |
383 toHTMLObjectElement(*m_element).renderFallbackContent(); | |
384 | |
385 // Only consider updating the protection ref-count of the Element immediatel
y before returning | |
386 // from this function as doing so might result in the destruction of this Im
ageLoader. | |
387 updatedHasPendingEvent(); | |
388 } | |
389 | |
390 void ImageLoader::dispatchPendingLoadEvent() | 332 void ImageLoader::dispatchPendingLoadEvent() |
391 { | 333 { |
392 if (!m_hasPendingLoadEvent) | 334 if (!m_hasPendingLoadEvent) |
393 return; | 335 return; |
394 if (!m_image) | 336 if (!m_image) |
395 return; | 337 return; |
396 m_hasPendingLoadEvent = false; | 338 m_hasPendingLoadEvent = false; |
397 if (element()->document().frame()) | 339 if (element()->document().frame()) |
398 dispatchLoadEvent(); | 340 dispatchLoadEvent(); |
399 | 341 |
(...skipping 27 matching lines...) Expand all Loading... |
427 { | 369 { |
428 if (client->requestsHighLiveResourceCachePriority()) { | 370 if (client->requestsHighLiveResourceCachePriority()) { |
429 ASSERT(m_highPriorityClientCount); | 371 ASSERT(m_highPriorityClientCount); |
430 m_highPriorityClientCount--; | 372 m_highPriorityClientCount--; |
431 if (m_image && !m_highPriorityClientCount) | 373 if (m_image && !m_highPriorityClientCount) |
432 m_image->setCacheLiveResourcePriority(Resource::CacheLiveResourcePri
orityLow); | 374 m_image->setCacheLiveResourcePriority(Resource::CacheLiveResourcePri
orityLow); |
433 } | 375 } |
434 m_clients.remove(client); | 376 m_clients.remove(client); |
435 } | 377 } |
436 | 378 |
437 void ImageLoader::dispatchPendingBeforeLoadEvents() | |
438 { | |
439 beforeLoadEventSender().dispatchPendingEvents(); | |
440 } | |
441 | |
442 void ImageLoader::dispatchPendingLoadEvents() | 379 void ImageLoader::dispatchPendingLoadEvents() |
443 { | 380 { |
444 loadEventSender().dispatchPendingEvents(); | 381 loadEventSender().dispatchPendingEvents(); |
445 } | 382 } |
446 | 383 |
447 void ImageLoader::dispatchPendingErrorEvents() | 384 void ImageLoader::dispatchPendingErrorEvents() |
448 { | 385 { |
449 errorEventSender().dispatchPendingEvents(); | 386 errorEventSender().dispatchPendingEvents(); |
450 } | 387 } |
451 | 388 |
(...skipping 11 matching lines...) Expand all Loading... |
463 handle->notifyImageSourceChanged(); | 400 handle->notifyImageSourceChanged(); |
464 } | 401 } |
465 } | 402 } |
466 | 403 |
467 inline void ImageLoader::clearFailedLoadURL() | 404 inline void ImageLoader::clearFailedLoadURL() |
468 { | 405 { |
469 m_failedLoadURL = AtomicString(); | 406 m_failedLoadURL = AtomicString(); |
470 } | 407 } |
471 | 408 |
472 } | 409 } |
OLD | NEW |