| 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 |