| 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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 BypassMainWorldBehavior m_shouldBypassMainWorldCSP; | 140 BypassMainWorldBehavior m_shouldBypassMainWorldCSP; |
| 141 UpdateFromElementBehavior m_updateBehavior; | 141 UpdateFromElementBehavior m_updateBehavior; |
| 142 RefPtr<ScriptState> m_scriptState; | 142 RefPtr<ScriptState> m_scriptState; |
| 143 WeakPtrFactory<Task> m_weakFactory; | 143 WeakPtrFactory<Task> m_weakFactory; |
| 144 ReferrerPolicy m_referrerPolicy; | 144 ReferrerPolicy m_referrerPolicy; |
| 145 KURL m_requestURL; | 145 KURL m_requestURL; |
| 146 }; | 146 }; |
| 147 | 147 |
| 148 ImageLoader::ImageLoader(Element* element) | 148 ImageLoader::ImageLoader(Element* element) |
| 149 : m_element(element) | 149 : m_element(element) |
| 150 , m_derefElementTimer(this, &ImageLoader::timerFired) | |
| 151 , m_hasPendingLoadEvent(false) | 150 , m_hasPendingLoadEvent(false) |
| 152 , m_hasPendingErrorEvent(false) | 151 , m_hasPendingErrorEvent(false) |
| 153 , m_imageComplete(true) | 152 , m_imageComplete(true) |
| 154 , m_loadingImageDocument(false) | 153 , m_loadingImageDocument(false) |
| 155 , m_elementIsProtected(false) | |
| 156 , m_suppressErrorEvents(false) | 154 , m_suppressErrorEvents(false) |
| 157 { | 155 { |
| 158 RESOURCE_LOADING_DVLOG(1) << "new ImageLoader " << this; | 156 RESOURCE_LOADING_DVLOG(1) << "new ImageLoader " << this; |
| 159 ThreadState::current()->registerPreFinalizer(this); | 157 ThreadState::current()->registerPreFinalizer(this); |
| 160 } | 158 } |
| 161 | 159 |
| 162 ImageLoader::~ImageLoader() | 160 ImageLoader::~ImageLoader() |
| 163 { | 161 { |
| 164 } | 162 } |
| 165 | 163 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 177 | 175 |
| 178 DEFINE_TRACE(ImageLoader) | 176 DEFINE_TRACE(ImageLoader) |
| 179 { | 177 { |
| 180 visitor->trace(m_image); | 178 visitor->trace(m_image); |
| 181 visitor->trace(m_element); | 179 visitor->trace(m_element); |
| 182 } | 180 } |
| 183 | 181 |
| 184 void ImageLoader::setImage(ImageResource* newImage) | 182 void ImageLoader::setImage(ImageResource* newImage) |
| 185 { | 183 { |
| 186 setImageWithoutConsideringPendingLoadEvent(newImage); | 184 setImageWithoutConsideringPendingLoadEvent(newImage); |
| 187 | |
| 188 // Only consider updating the protection ref-count of the Element immediatel
y before returning | |
| 189 // from this function as doing so might result in the destruction of this Im
ageLoader. | |
| 190 updatedHasPendingEvent(); | |
| 191 } | 185 } |
| 192 | 186 |
| 193 void ImageLoader::setImageWithoutConsideringPendingLoadEvent(ImageResource* newI
mage) | 187 void ImageLoader::setImageWithoutConsideringPendingLoadEvent(ImageResource* newI
mage) |
| 194 { | 188 { |
| 195 ASSERT(m_failedLoadURL.isEmpty()); | 189 ASSERT(m_failedLoadURL.isEmpty()); |
| 196 ImageResource* oldImage = m_image.get(); | 190 ImageResource* oldImage = m_image.get(); |
| 197 if (newImage != oldImage) { | 191 if (newImage != oldImage) { |
| 198 m_image = newImage; | 192 m_image = newImage; |
| 199 if (m_hasPendingLoadEvent) { | 193 if (m_hasPendingLoadEvent) { |
| 200 loadEventSender().cancelEvent(this); | 194 loadEventSender().cancelEvent(this); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 if (newImage) { | 330 if (newImage) { |
| 337 newImage->addObserver(this); | 331 newImage->addObserver(this); |
| 338 } | 332 } |
| 339 if (oldImage) { | 333 if (oldImage) { |
| 340 oldImage->removeObserver(this); | 334 oldImage->removeObserver(this); |
| 341 } | 335 } |
| 342 } | 336 } |
| 343 | 337 |
| 344 if (LayoutImageResource* imageResource = layoutImageResource()) | 338 if (LayoutImageResource* imageResource = layoutImageResource()) |
| 345 imageResource->resetAnimation(); | 339 imageResource->resetAnimation(); |
| 346 | |
| 347 // Only consider updating the protection ref-count of the Element immediatel
y before returning | |
| 348 // from this function as doing so might result in the destruction of this Im
ageLoader. | |
| 349 updatedHasPendingEvent(); | |
| 350 } | 340 } |
| 351 | 341 |
| 352 void ImageLoader::updateFromElement(UpdateFromElementBehavior updateBehavior, Re
ferrerPolicy referrerPolicy) | 342 void ImageLoader::updateFromElement(UpdateFromElementBehavior updateBehavior, Re
ferrerPolicy referrerPolicy) |
| 353 { | 343 { |
| 354 AtomicString imageSourceURL = m_element->imageSourceURL(); | 344 AtomicString imageSourceURL = m_element->imageSourceURL(); |
| 355 m_suppressErrorEvents = (updateBehavior == UpdateSizeChanged); | 345 m_suppressErrorEvents = (updateBehavior == UpdateSizeChanged); |
| 356 | 346 |
| 357 if (updateBehavior == UpdateIgnorePreviousError) | 347 if (updateBehavior == UpdateIgnorePreviousError) |
| 358 clearFailedLoadURL(); | 348 clearFailedLoadURL(); |
| 359 | 349 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 m_hasPendingLoadEvent = false; | 449 m_hasPendingLoadEvent = false; |
| 460 | 450 |
| 461 if (resource->resourceError().isAccessCheck()) | 451 if (resource->resourceError().isAccessCheck()) |
| 462 crossSiteOrCSPViolationOccurred(AtomicString(resource->resourceError
().failingURL())); | 452 crossSiteOrCSPViolationOccurred(AtomicString(resource->resourceError
().failingURL())); |
| 463 | 453 |
| 464 // The error event should not fire if the image data update is a result
of environment change. | 454 // The error event should not fire if the image data update is a result
of environment change. |
| 465 // https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-
element:the-img-element-55 | 455 // https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-
element:the-img-element-55 |
| 466 if (!m_suppressErrorEvents) | 456 if (!m_suppressErrorEvents) |
| 467 dispatchErrorEvent(); | 457 dispatchErrorEvent(); |
| 468 | 458 |
| 469 // Only consider updating the protection ref-count of the Element immedi
ately before returning | |
| 470 // from this function as doing so might result in the destruction of thi
s ImageLoader. | |
| 471 updatedHasPendingEvent(); | |
| 472 return; | 459 return; |
| 473 } | 460 } |
| 474 if (resource->wasCanceled()) { | 461 if (resource->wasCanceled()) { |
| 475 m_hasPendingLoadEvent = false; | 462 m_hasPendingLoadEvent = false; |
| 476 // Only consider updating the protection ref-count of the Element immedi
ately before returning | |
| 477 // from this function as doing so might result in the destruction of thi
s ImageLoader. | |
| 478 updatedHasPendingEvent(); | |
| 479 return; | 463 return; |
| 480 } | 464 } |
| 481 loadEventSender().dispatchEventSoon(this); | 465 loadEventSender().dispatchEventSoon(this); |
| 482 } | 466 } |
| 483 | 467 |
| 484 LayoutImageResource* ImageLoader::layoutImageResource() | 468 LayoutImageResource* ImageLoader::layoutImageResource() |
| 485 { | 469 { |
| 486 LayoutObject* layoutObject = m_element->layoutObject(); | 470 LayoutObject* layoutObject = m_element->layoutObject(); |
| 487 | 471 |
| 488 if (!layoutObject) | 472 if (!layoutObject) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 510 return; | 494 return; |
| 511 | 495 |
| 512 // Only update the layoutObject if it doesn't have an image or if what we ha
ve | 496 // Only update the layoutObject if it doesn't have an image or if what we ha
ve |
| 513 // is a complete image. This prevents flickering in the case where a dynami
c | 497 // is a complete image. This prevents flickering in the case where a dynami
c |
| 514 // change is happening between two images. | 498 // change is happening between two images. |
| 515 ImageResource* cachedImage = imageResource->cachedImage(); | 499 ImageResource* cachedImage = imageResource->cachedImage(); |
| 516 if (m_image != cachedImage && (m_imageComplete || !cachedImage)) | 500 if (m_image != cachedImage && (m_imageComplete || !cachedImage)) |
| 517 imageResource->setImageResource(m_image.get()); | 501 imageResource->setImageResource(m_image.get()); |
| 518 } | 502 } |
| 519 | 503 |
| 520 void ImageLoader::updatedHasPendingEvent() | |
| 521 { | |
| 522 // If an Element that does image loading is removed from the DOM the load/er
ror event for the image is still observable. | |
| 523 // As long as the ImageLoader is actively loading, the Element itself needs
to be ref'ed to keep it from being | |
| 524 // destroyed by DOM manipulation or garbage collection. | |
| 525 // If such an Element wishes for the load to stop when removed from the DOM
it needs to stop the ImageLoader explicitly. | |
| 526 bool wasProtected = m_elementIsProtected; | |
| 527 m_elementIsProtected = m_hasPendingLoadEvent || m_hasPendingErrorEvent; | |
| 528 if (wasProtected == m_elementIsProtected) | |
| 529 return; | |
| 530 | |
| 531 if (m_elementIsProtected) { | |
| 532 if (m_derefElementTimer.isActive()) | |
| 533 m_derefElementTimer.stop(); | |
| 534 else | |
| 535 m_keepAlive = m_element; | |
| 536 } else { | |
| 537 ASSERT(!m_derefElementTimer.isActive()); | |
| 538 m_derefElementTimer.startOneShot(0, BLINK_FROM_HERE); | |
| 539 } | |
| 540 } | |
| 541 | |
| 542 void ImageLoader::timerFired(TimerBase*) | |
| 543 { | |
| 544 m_keepAlive.clear(); | |
| 545 } | |
| 546 | |
| 547 void ImageLoader::dispatchPendingEvent(ImageEventSender* eventSender) | 504 void ImageLoader::dispatchPendingEvent(ImageEventSender* eventSender) |
| 548 { | 505 { |
| 549 RESOURCE_LOADING_DVLOG(1) << "ImageLoader::dispatchPendingEvent " << this; | 506 RESOURCE_LOADING_DVLOG(1) << "ImageLoader::dispatchPendingEvent " << this; |
| 550 ASSERT(eventSender == &loadEventSender() || eventSender == &errorEventSender
()); | 507 ASSERT(eventSender == &loadEventSender() || eventSender == &errorEventSender
()); |
| 551 const AtomicString& eventType = eventSender->eventType(); | 508 const AtomicString& eventType = eventSender->eventType(); |
| 552 if (eventType == EventTypeNames::load) | 509 if (eventType == EventTypeNames::load) |
| 553 dispatchPendingLoadEvent(); | 510 dispatchPendingLoadEvent(); |
| 554 if (eventType == EventTypeNames::error) | 511 if (eventType == EventTypeNames::error) |
| 555 dispatchPendingErrorEvent(); | 512 dispatchPendingErrorEvent(); |
| 556 } | 513 } |
| 557 | 514 |
| 558 void ImageLoader::dispatchPendingLoadEvent() | 515 void ImageLoader::dispatchPendingLoadEvent() |
| 559 { | 516 { |
| 560 if (!m_hasPendingLoadEvent) | 517 if (!m_hasPendingLoadEvent) |
| 561 return; | 518 return; |
| 562 if (!m_image) | 519 if (!m_image) |
| 563 return; | 520 return; |
| 564 m_hasPendingLoadEvent = false; | 521 m_hasPendingLoadEvent = false; |
| 565 if (element()->document().frame()) | 522 if (element()->document().frame()) |
| 566 dispatchLoadEvent(); | 523 dispatchLoadEvent(); |
| 567 | |
| 568 // Only consider updating the protection ref-count of the Element immediatel
y before returning | |
| 569 // from this function as doing so might result in the destruction of this Im
ageLoader. | |
| 570 updatedHasPendingEvent(); | |
| 571 } | 524 } |
| 572 | 525 |
| 573 void ImageLoader::dispatchPendingErrorEvent() | 526 void ImageLoader::dispatchPendingErrorEvent() |
| 574 { | 527 { |
| 575 if (!m_hasPendingErrorEvent) | 528 if (!m_hasPendingErrorEvent) |
| 576 return; | 529 return; |
| 577 m_hasPendingErrorEvent = false; | 530 m_hasPendingErrorEvent = false; |
| 578 | 531 |
| 579 if (element()->document().frame()) | 532 if (element()->document().frame()) |
| 580 element()->dispatchEvent(Event::create(EventTypeNames::error)); | 533 element()->dispatchEvent(Event::create(EventTypeNames::error)); |
| 581 | |
| 582 // Only consider updating the protection ref-count of the Element immediatel
y before returning | |
| 583 // from this function as doing so might result in the destruction of this Im
ageLoader. | |
| 584 updatedHasPendingEvent(); | |
| 585 } | 534 } |
| 586 | 535 |
| 587 bool ImageLoader::getImageAnimationPolicy(ImageAnimationPolicy& policy) | 536 bool ImageLoader::getImageAnimationPolicy(ImageAnimationPolicy& policy) |
| 588 { | 537 { |
| 589 if (!element()->document().settings()) | 538 if (!element()->document().settings()) |
| 590 return false; | 539 return false; |
| 591 | 540 |
| 592 policy = element()->document().settings()->imageAnimationPolicy(); | 541 policy = element()->document().settings()->imageAnimationPolicy(); |
| 593 return true; | 542 return true; |
| 594 } | 543 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 605 | 554 |
| 606 void ImageLoader::elementDidMoveToNewDocument() | 555 void ImageLoader::elementDidMoveToNewDocument() |
| 607 { | 556 { |
| 608 if (m_loadDelayCounter) | 557 if (m_loadDelayCounter) |
| 609 m_loadDelayCounter->documentChanged(m_element->document()); | 558 m_loadDelayCounter->documentChanged(m_element->document()); |
| 610 clearFailedLoadURL(); | 559 clearFailedLoadURL(); |
| 611 setImage(0); | 560 setImage(0); |
| 612 } | 561 } |
| 613 | 562 |
| 614 } // namespace blink | 563 } // namespace blink |
| OLD | NEW |