| 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 |
| 5 * reserved. |
| 5 * | 6 * |
| 6 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
| 10 * | 11 * |
| 11 * This library is distributed in the hope that it will be useful, | 12 * This library is distributed in the hope that it will be useful, |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 * Library General Public License for more details. | 15 * Library General Public License for more details. |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 } | 181 } |
| 181 | 182 |
| 182 DEFINE_TRACE(ImageLoader) { | 183 DEFINE_TRACE(ImageLoader) { |
| 183 visitor->trace(m_image); | 184 visitor->trace(m_image); |
| 184 visitor->trace(m_element); | 185 visitor->trace(m_element); |
| 185 } | 186 } |
| 186 | 187 |
| 187 void ImageLoader::setImage(ImageResource* newImage) { | 188 void ImageLoader::setImage(ImageResource* newImage) { |
| 188 setImageWithoutConsideringPendingLoadEvent(newImage); | 189 setImageWithoutConsideringPendingLoadEvent(newImage); |
| 189 | 190 |
| 190 // Only consider updating the protection ref-count of the Element immediately
before returning | 191 // Only consider updating the protection ref-count of the Element immediately |
| 191 // from this function as doing so might result in the destruction of this Imag
eLoader. | 192 // before returning from this function as doing so might result in the |
| 193 // destruction of this ImageLoader. |
| 192 updatedHasPendingEvent(); | 194 updatedHasPendingEvent(); |
| 193 } | 195 } |
| 194 | 196 |
| 195 void ImageLoader::setImageWithoutConsideringPendingLoadEvent( | 197 void ImageLoader::setImageWithoutConsideringPendingLoadEvent( |
| 196 ImageResource* newImage) { | 198 ImageResource* newImage) { |
| 197 DCHECK(m_failedLoadURL.isEmpty()); | 199 DCHECK(m_failedLoadURL.isEmpty()); |
| 198 ImageResource* oldImage = m_image.get(); | 200 ImageResource* oldImage = m_image.get(); |
| 199 if (newImage != oldImage) { | 201 if (newImage != oldImage) { |
| 200 m_image = newImage; | 202 m_image = newImage; |
| 201 if (m_hasPendingLoadEvent) { | 203 if (m_hasPendingLoadEvent) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 m_loadDelayCounter = | 264 m_loadDelayCounter = |
| 263 IncrementLoadEventDelayCount::create(m_element->document()); | 265 IncrementLoadEventDelayCount::create(m_element->document()); |
| 264 } | 266 } |
| 265 | 267 |
| 266 void ImageLoader::doUpdateFromElement(BypassMainWorldBehavior bypassBehavior, | 268 void ImageLoader::doUpdateFromElement(BypassMainWorldBehavior bypassBehavior, |
| 267 UpdateFromElementBehavior updateBehavior, | 269 UpdateFromElementBehavior updateBehavior, |
| 268 const KURL& url, | 270 const KURL& url, |
| 269 ReferrerPolicy referrerPolicy) { | 271 ReferrerPolicy referrerPolicy) { |
| 270 // FIXME: According to | 272 // FIXME: According to |
| 271 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-conten
t.html#the-img-element:the-img-element-55 | 273 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-conten
t.html#the-img-element:the-img-element-55 |
| 272 // When "update image" is called due to environment changes and the load fails
, onerror should not be called. | 274 // When "update image" is called due to environment changes and the load |
| 273 // That is currently not the case. | 275 // fails, onerror should not be called. That is currently not the case. |
| 274 // | 276 // |
| 275 // We don't need to call clearLoader here: Either we were called from the | 277 // We don't need to call clearLoader here: Either we were called from the |
| 276 // task, or our caller updateFromElement cleared the task's loader (and set | 278 // task, or our caller updateFromElement cleared the task's loader (and set |
| 277 // m_pendingTask to null). | 279 // m_pendingTask to null). |
| 278 m_pendingTask.reset(); | 280 m_pendingTask.reset(); |
| 279 // Make sure to only decrement the count when we exit this function | 281 // Make sure to only decrement the count when we exit this function |
| 280 std::unique_ptr<IncrementLoadEventDelayCount> loadDelayCounter; | 282 std::unique_ptr<IncrementLoadEventDelayCount> loadDelayCounter; |
| 281 loadDelayCounter.swap(m_loadDelayCounter); | 283 loadDelayCounter.swap(m_loadDelayCounter); |
| 282 | 284 |
| 283 Document& document = m_element->document(); | 285 Document& document = m_element->document(); |
| 284 if (!document.isActive()) | 286 if (!document.isActive()) |
| 285 return; | 287 return; |
| 286 | 288 |
| 287 AtomicString imageSourceURL = m_element->imageSourceURL(); | 289 AtomicString imageSourceURL = m_element->imageSourceURL(); |
| 288 ImageResource* newImage = nullptr; | 290 ImageResource* newImage = nullptr; |
| 289 if (!url.isNull()) { | 291 if (!url.isNull()) { |
| 290 // Unlike raw <img>, we block mixed content inside of <picture> or <img srcs
et>. | 292 // Unlike raw <img>, we block mixed content inside of <picture> or |
| 293 // <img srcset>. |
| 291 ResourceLoaderOptions resourceLoaderOptions = | 294 ResourceLoaderOptions resourceLoaderOptions = |
| 292 ResourceFetcher::defaultResourceOptions(); | 295 ResourceFetcher::defaultResourceOptions(); |
| 293 ResourceRequest resourceRequest(url); | 296 ResourceRequest resourceRequest(url); |
| 294 if (updateBehavior == UpdateForcedReload) { | 297 if (updateBehavior == UpdateForcedReload) { |
| 295 resourceRequest.setCachePolicy(WebCachePolicy::BypassingCache); | 298 resourceRequest.setCachePolicy(WebCachePolicy::BypassingCache); |
| 296 resourceRequest.setLoFiState(WebURLRequest::LoFiOff); | 299 resourceRequest.setLoFiState(WebURLRequest::LoFiOff); |
| 297 } | 300 } |
| 298 | 301 |
| 299 if (referrerPolicy != ReferrerPolicyDefault) | 302 if (referrerPolicy != ReferrerPolicyDefault) |
| 300 resourceRequest.setHTTPReferrer(SecurityPolicy::generateReferrer( | 303 resourceRequest.setHTTPReferrer(SecurityPolicy::generateReferrer( |
| (...skipping 26 matching lines...) Expand all Loading... |
| 327 ImageResource* oldImage = m_image.get(); | 330 ImageResource* oldImage = m_image.get(); |
| 328 if (updateBehavior == UpdateSizeChanged && m_element->layoutObject() && | 331 if (updateBehavior == UpdateSizeChanged && m_element->layoutObject() && |
| 329 m_element->layoutObject()->isImage() && newImage == oldImage) { | 332 m_element->layoutObject()->isImage() && newImage == oldImage) { |
| 330 toLayoutImage(m_element->layoutObject())->intrinsicSizeChanged(); | 333 toLayoutImage(m_element->layoutObject())->intrinsicSizeChanged(); |
| 331 } else { | 334 } else { |
| 332 if (m_hasPendingLoadEvent) { | 335 if (m_hasPendingLoadEvent) { |
| 333 loadEventSender().cancelEvent(this); | 336 loadEventSender().cancelEvent(this); |
| 334 m_hasPendingLoadEvent = false; | 337 m_hasPendingLoadEvent = false; |
| 335 } | 338 } |
| 336 | 339 |
| 337 // Cancel error events that belong to the previous load, which is now cancel
led by changing the src attribute. | 340 // Cancel error events that belong to the previous load, which is now |
| 338 // If newImage is null and m_hasPendingErrorEvent is true, we know the error
event has been just posted by | 341 // cancelled by changing the src attribute. If newImage is null and |
| 339 // this load and we should not cancel the event. | 342 // m_hasPendingErrorEvent is true, we know the error event has been just |
| 340 // FIXME: If both previous load and this one got blocked with an error, we c
an receive one error event instead of two. | 343 // posted by this load and we should not cancel the event. |
| 344 // FIXME: If both previous load and this one got blocked with an error, we |
| 345 // can receive one error event instead of two. |
| 341 if (m_hasPendingErrorEvent && newImage) { | 346 if (m_hasPendingErrorEvent && newImage) { |
| 342 errorEventSender().cancelEvent(this); | 347 errorEventSender().cancelEvent(this); |
| 343 m_hasPendingErrorEvent = false; | 348 m_hasPendingErrorEvent = false; |
| 344 } | 349 } |
| 345 | 350 |
| 346 m_image = newImage; | 351 m_image = newImage; |
| 347 m_hasPendingLoadEvent = newImage; | 352 m_hasPendingLoadEvent = newImage; |
| 348 m_imageComplete = !newImage; | 353 m_imageComplete = !newImage; |
| 349 | 354 |
| 350 updateLayoutObject(); | 355 updateLayoutObject(); |
| 351 // If newImage exists and is cached, addObserver() will result in the load e
vent | 356 // If newImage exists and is cached, addObserver() will result in the load |
| 352 // being queued to fire. Ensure this happens after beforeload is dispatched. | 357 // event being queued to fire. Ensure this happens after beforeload is |
| 358 // dispatched. |
| 353 if (newImage) { | 359 if (newImage) { |
| 354 newImage->addObserver(this); | 360 newImage->addObserver(this); |
| 355 } | 361 } |
| 356 if (oldImage) { | 362 if (oldImage) { |
| 357 oldImage->removeObserver(this); | 363 oldImage->removeObserver(this); |
| 358 } | 364 } |
| 359 } | 365 } |
| 360 | 366 |
| 361 if (LayoutImageResource* imageResource = layoutImageResource()) | 367 if (LayoutImageResource* imageResource = layoutImageResource()) |
| 362 imageResource->resetAnimation(); | 368 imageResource->resetAnimation(); |
| 363 | 369 |
| 364 // Only consider updating the protection ref-count of the Element immediately
before returning | 370 // Only consider updating the protection ref-count of the Element immediately |
| 365 // from this function as doing so might result in the destruction of this Imag
eLoader. | 371 // before returning from this function as doing so might result in the |
| 372 // destruction of this ImageLoader. |
| 366 updatedHasPendingEvent(); | 373 updatedHasPendingEvent(); |
| 367 } | 374 } |
| 368 | 375 |
| 369 void ImageLoader::updateFromElement(UpdateFromElementBehavior updateBehavior, | 376 void ImageLoader::updateFromElement(UpdateFromElementBehavior updateBehavior, |
| 370 ReferrerPolicy referrerPolicy) { | 377 ReferrerPolicy referrerPolicy) { |
| 371 AtomicString imageSourceURL = m_element->imageSourceURL(); | 378 AtomicString imageSourceURL = m_element->imageSourceURL(); |
| 372 m_suppressErrorEvents = (updateBehavior == UpdateSizeChanged); | 379 m_suppressErrorEvents = (updateBehavior == UpdateSizeChanged); |
| 373 | 380 |
| 374 if (updateBehavior == UpdateIgnorePreviousError) | 381 if (updateBehavior == UpdateIgnorePreviousError) |
| 375 clearFailedLoadURL(); | 382 clearFailedLoadURL(); |
| 376 | 383 |
| 377 if (!m_failedLoadURL.isEmpty() && imageSourceURL == m_failedLoadURL) | 384 if (!m_failedLoadURL.isEmpty() && imageSourceURL == m_failedLoadURL) |
| 378 return; | 385 return; |
| 379 | 386 |
| 380 // Prevent the creation of a ResourceLoader (and therefore a network | 387 // Prevent the creation of a ResourceLoader (and therefore a network request) |
| 381 // request) for ImageDocument loads. In this case, the image contents have alr
eady | 388 // for ImageDocument loads. In this case, the image contents have already been |
| 382 // been requested as a main resource and ImageDocumentParser will take care of | 389 // requested as a main resource and ImageDocumentParser will take care of |
| 383 // funneling the main resource bytes into m_image, so just create an ImageReso
urce | 390 // funneling the main resource bytes into m_image, so just create an |
| 384 // to be populated later. | 391 // ImageResource to be populated later. |
| 385 if (m_loadingImageDocument && updateBehavior != UpdateForcedReload) { | 392 if (m_loadingImageDocument && updateBehavior != UpdateForcedReload) { |
| 386 setImage( | 393 setImage( |
| 387 ImageResource::create(imageSourceToKURL(m_element->imageSourceURL()))); | 394 ImageResource::create(imageSourceToKURL(m_element->imageSourceURL()))); |
| 388 m_image->setStatus(Resource::Pending); | 395 m_image->setStatus(Resource::Pending); |
| 389 return; | 396 return; |
| 390 } | 397 } |
| 391 | 398 |
| 392 // If we have a pending task, we have to clear it -- either we're | 399 // If we have a pending task, we have to clear it -- either we're now loading |
| 393 // now loading immediately, or we need to reset the task's state. | 400 // immediately, or we need to reset the task's state. |
| 394 if (m_pendingTask) { | 401 if (m_pendingTask) { |
| 395 m_pendingTask->clearLoader(); | 402 m_pendingTask->clearLoader(); |
| 396 m_pendingTask.reset(); | 403 m_pendingTask.reset(); |
| 397 } | 404 } |
| 398 | 405 |
| 399 KURL url = imageSourceToKURL(imageSourceURL); | 406 KURL url = imageSourceToKURL(imageSourceURL); |
| 400 if (shouldLoadImmediately(url)) { | 407 if (shouldLoadImmediately(url)) { |
| 401 doUpdateFromElement(DoNotBypassMainWorldCSP, updateBehavior, url, | 408 doUpdateFromElement(DoNotBypassMainWorldCSP, updateBehavior, url, |
| 402 referrerPolicy); | 409 referrerPolicy); |
| 403 return; | 410 return; |
| 404 } | 411 } |
| 405 // Allow the idiom "img.src=''; img.src='.." to clear down the image before | 412 // Allow the idiom "img.src=''; img.src='.." to clear down the image before an |
| 406 // an asynchronous load completes. | 413 // asynchronous load completes. |
| 407 if (imageSourceURL.isEmpty()) { | 414 if (imageSourceURL.isEmpty()) { |
| 408 ImageResource* image = m_image.get(); | 415 ImageResource* image = m_image.get(); |
| 409 if (image) { | 416 if (image) { |
| 410 image->removeObserver(this); | 417 image->removeObserver(this); |
| 411 } | 418 } |
| 412 m_image = nullptr; | 419 m_image = nullptr; |
| 413 } | 420 } |
| 414 | 421 |
| 415 // Don't load images for inactive documents. We don't want to slow down the | 422 // Don't load images for inactive documents. We don't want to slow down the |
| 416 // raw HTML parsing case by loading images we don't intend to display. | 423 // raw HTML parsing case by loading images we don't intend to display. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 433 if (!imageSourceURL.isNull()) { | 440 if (!imageSourceURL.isNull()) { |
| 434 String strippedImageSourceURL = | 441 String strippedImageSourceURL = |
| 435 stripLeadingAndTrailingHTMLSpaces(imageSourceURL); | 442 stripLeadingAndTrailingHTMLSpaces(imageSourceURL); |
| 436 if (!strippedImageSourceURL.isEmpty()) | 443 if (!strippedImageSourceURL.isEmpty()) |
| 437 url = document.completeURL(strippedImageSourceURL); | 444 url = document.completeURL(strippedImageSourceURL); |
| 438 } | 445 } |
| 439 return url; | 446 return url; |
| 440 } | 447 } |
| 441 | 448 |
| 442 bool ImageLoader::shouldLoadImmediately(const KURL& url) const { | 449 bool ImageLoader::shouldLoadImmediately(const KURL& url) const { |
| 443 // We force any image loads which might require alt content through the asynch
ronous path so that we can add the shadow DOM | 450 // We force any image loads which might require alt content through the |
| 444 // for the alt-text content when style recalc is over and DOM mutation is allo
wed again. | 451 // asynchronous path so that we can add the shadow DOM for the alt-text |
| 452 // content when style recalc is over and DOM mutation is allowed again. |
| 445 if (!url.isNull()) { | 453 if (!url.isNull()) { |
| 446 Resource* resource = memoryCache()->resourceForURL( | 454 Resource* resource = memoryCache()->resourceForURL( |
| 447 url, m_element->document().fetcher()->getCacheIdentifier()); | 455 url, m_element->document().fetcher()->getCacheIdentifier()); |
| 448 if (resource && !resource->errorOccurred()) | 456 if (resource && !resource->errorOccurred()) |
| 449 return true; | 457 return true; |
| 450 } | 458 } |
| 451 return (isHTMLObjectElement(m_element) || isHTMLEmbedElement(m_element) || | 459 return (isHTMLObjectElement(m_element) || isHTMLEmbedElement(m_element) || |
| 452 url.protocolIsData()); | 460 url.protocolIsData()); |
| 453 } | 461 } |
| 454 | 462 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 475 return; | 483 return; |
| 476 | 484 |
| 477 if (resource->errorOccurred()) { | 485 if (resource->errorOccurred()) { |
| 478 loadEventSender().cancelEvent(this); | 486 loadEventSender().cancelEvent(this); |
| 479 m_hasPendingLoadEvent = false; | 487 m_hasPendingLoadEvent = false; |
| 480 | 488 |
| 481 if (resource->resourceError().isAccessCheck()) | 489 if (resource->resourceError().isAccessCheck()) |
| 482 crossSiteOrCSPViolationOccurred( | 490 crossSiteOrCSPViolationOccurred( |
| 483 AtomicString(resource->resourceError().failingURL())); | 491 AtomicString(resource->resourceError().failingURL())); |
| 484 | 492 |
| 485 // The error event should not fire if the image data update is a result of e
nvironment change. | 493 // The error event should not fire if the image data update is a result of |
| 494 // environment change. |
| 486 // https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-elem
ent:the-img-element-55 | 495 // https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-elem
ent:the-img-element-55 |
| 487 if (!m_suppressErrorEvents) | 496 if (!m_suppressErrorEvents) |
| 488 dispatchErrorEvent(); | 497 dispatchErrorEvent(); |
| 489 | 498 |
| 490 // Only consider updating the protection ref-count of the Element immediatel
y before returning | 499 // Only consider updating the protection ref-count of the Element |
| 491 // from this function as doing so might result in the destruction of this Im
ageLoader. | 500 // immediately before returning from this function as doing so might result |
| 501 // in the destruction of this ImageLoader. |
| 492 updatedHasPendingEvent(); | 502 updatedHasPendingEvent(); |
| 493 return; | 503 return; |
| 494 } | 504 } |
| 495 if (resource->wasCanceled()) { | 505 if (resource->wasCanceled()) { |
| 496 m_hasPendingLoadEvent = false; | 506 m_hasPendingLoadEvent = false; |
| 497 // Only consider updating the protection ref-count of the Element immediatel
y before returning | 507 // Only consider updating the protection ref-count of the Element |
| 498 // from this function as doing so might result in the destruction of this Im
ageLoader. | 508 // immediately before returning from this function as doing so might result |
| 509 // in the destruction of this ImageLoader. |
| 499 updatedHasPendingEvent(); | 510 updatedHasPendingEvent(); |
| 500 return; | 511 return; |
| 501 } | 512 } |
| 502 loadEventSender().dispatchEventSoon(this); | 513 loadEventSender().dispatchEventSoon(this); |
| 503 } | 514 } |
| 504 | 515 |
| 505 LayoutImageResource* ImageLoader::layoutImageResource() { | 516 LayoutImageResource* ImageLoader::layoutImageResource() { |
| 506 LayoutObject* layoutObject = m_element->layoutObject(); | 517 LayoutObject* layoutObject = m_element->layoutObject(); |
| 507 | 518 |
| 508 if (!layoutObject) | 519 if (!layoutObject) |
| 509 return 0; | 520 return 0; |
| 510 | 521 |
| 511 // We don't return style generated image because it doesn't belong to the Imag
eLoader. | 522 // We don't return style generated image because it doesn't belong to the |
| 512 // See <https://bugs.webkit.org/show_bug.cgi?id=42840> | 523 // ImageLoader. See <https://bugs.webkit.org/show_bug.cgi?id=42840> |
| 513 if (layoutObject->isImage() && | 524 if (layoutObject->isImage() && |
| 514 !static_cast<LayoutImage*>(layoutObject)->isGeneratedContent()) | 525 !static_cast<LayoutImage*>(layoutObject)->isGeneratedContent()) |
| 515 return toLayoutImage(layoutObject)->imageResource(); | 526 return toLayoutImage(layoutObject)->imageResource(); |
| 516 | 527 |
| 517 if (layoutObject->isSVGImage()) | 528 if (layoutObject->isSVGImage()) |
| 518 return toLayoutSVGImage(layoutObject)->imageResource(); | 529 return toLayoutSVGImage(layoutObject)->imageResource(); |
| 519 | 530 |
| 520 if (layoutObject->isVideo()) | 531 if (layoutObject->isVideo()) |
| 521 return toLayoutVideo(layoutObject)->imageResource(); | 532 return toLayoutVideo(layoutObject)->imageResource(); |
| 522 | 533 |
| 523 return 0; | 534 return 0; |
| 524 } | 535 } |
| 525 | 536 |
| 526 void ImageLoader::updateLayoutObject() { | 537 void ImageLoader::updateLayoutObject() { |
| 527 LayoutImageResource* imageResource = layoutImageResource(); | 538 LayoutImageResource* imageResource = layoutImageResource(); |
| 528 | 539 |
| 529 if (!imageResource) | 540 if (!imageResource) |
| 530 return; | 541 return; |
| 531 | 542 |
| 532 // Only update the layoutObject if it doesn't have an image or if what we have | 543 // Only update the layoutObject if it doesn't have an image or if what we have |
| 533 // is a complete image. This prevents flickering in the case where a dynamic | 544 // is a complete image. This prevents flickering in the case where a dynamic |
| 534 // change is happening between two images. | 545 // change is happening between two images. |
| 535 ImageResource* cachedImage = imageResource->cachedImage(); | 546 ImageResource* cachedImage = imageResource->cachedImage(); |
| 536 if (m_image != cachedImage && (m_imageComplete || !cachedImage)) | 547 if (m_image != cachedImage && (m_imageComplete || !cachedImage)) |
| 537 imageResource->setImageResource(m_image.get()); | 548 imageResource->setImageResource(m_image.get()); |
| 538 } | 549 } |
| 539 | 550 |
| 540 void ImageLoader::updatedHasPendingEvent() { | 551 void ImageLoader::updatedHasPendingEvent() { |
| 541 // If an Element that does image loading is removed from the DOM the load/erro
r event for the image is still observable. | 552 // If an Element that does image loading is removed from the DOM the |
| 542 // As long as the ImageLoader is actively loading, the Element itself needs to
be ref'ed to keep it from being | 553 // load/error event for the image is still observable. As long as the |
| 543 // destroyed by DOM manipulation or garbage collection. | 554 // ImageLoader is actively loading, the Element itself needs to be ref'ed to |
| 544 // If such an Element wishes for the load to stop when removed from the DOM it
needs to stop the ImageLoader explicitly. | 555 // keep it from being destroyed by DOM manipulation or garbage collection. If |
| 556 // such an Element wishes for the load to stop when removed from the DOM it |
| 557 // needs to stop the ImageLoader explicitly. |
| 545 bool wasProtected = m_elementIsProtected; | 558 bool wasProtected = m_elementIsProtected; |
| 546 m_elementIsProtected = m_hasPendingLoadEvent || m_hasPendingErrorEvent; | 559 m_elementIsProtected = m_hasPendingLoadEvent || m_hasPendingErrorEvent; |
| 547 if (wasProtected == m_elementIsProtected) | 560 if (wasProtected == m_elementIsProtected) |
| 548 return; | 561 return; |
| 549 | 562 |
| 550 if (m_elementIsProtected) { | 563 if (m_elementIsProtected) { |
| 551 if (m_derefElementTimer.isActive()) | 564 if (m_derefElementTimer.isActive()) |
| 552 m_derefElementTimer.stop(); | 565 m_derefElementTimer.stop(); |
| 553 else | 566 else |
| 554 m_keepAlive = m_element; | 567 m_keepAlive = m_element; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 575 | 588 |
| 576 void ImageLoader::dispatchPendingLoadEvent() { | 589 void ImageLoader::dispatchPendingLoadEvent() { |
| 577 if (!m_hasPendingLoadEvent) | 590 if (!m_hasPendingLoadEvent) |
| 578 return; | 591 return; |
| 579 if (!m_image) | 592 if (!m_image) |
| 580 return; | 593 return; |
| 581 m_hasPendingLoadEvent = false; | 594 m_hasPendingLoadEvent = false; |
| 582 if (element()->document().frame()) | 595 if (element()->document().frame()) |
| 583 dispatchLoadEvent(); | 596 dispatchLoadEvent(); |
| 584 | 597 |
| 585 // Only consider updating the protection ref-count of the Element immediately
before returning | 598 // Only consider updating the protection ref-count of the Element immediately |
| 586 // from this function as doing so might result in the destruction of this Imag
eLoader. | 599 // before returning from this function as doing so might result in the |
| 600 // destruction of this ImageLoader. |
| 587 updatedHasPendingEvent(); | 601 updatedHasPendingEvent(); |
| 588 } | 602 } |
| 589 | 603 |
| 590 void ImageLoader::dispatchPendingErrorEvent() { | 604 void ImageLoader::dispatchPendingErrorEvent() { |
| 591 if (!m_hasPendingErrorEvent) | 605 if (!m_hasPendingErrorEvent) |
| 592 return; | 606 return; |
| 593 m_hasPendingErrorEvent = false; | 607 m_hasPendingErrorEvent = false; |
| 594 | 608 |
| 595 if (element()->document().frame()) | 609 if (element()->document().frame()) |
| 596 element()->dispatchEvent(Event::create(EventTypeNames::error)); | 610 element()->dispatchEvent(Event::create(EventTypeNames::error)); |
| 597 | 611 |
| 598 // Only consider updating the protection ref-count of the Element immediately
before returning | 612 // Only consider updating the protection ref-count of the Element immediately |
| 599 // from this function as doing so might result in the destruction of this Imag
eLoader. | 613 // before returning from this function as doing so might result in the |
| 614 // destruction of this ImageLoader. |
| 600 updatedHasPendingEvent(); | 615 updatedHasPendingEvent(); |
| 601 } | 616 } |
| 602 | 617 |
| 603 bool ImageLoader::getImageAnimationPolicy(ImageAnimationPolicy& policy) { | 618 bool ImageLoader::getImageAnimationPolicy(ImageAnimationPolicy& policy) { |
| 604 if (!element()->document().settings()) | 619 if (!element()->document().settings()) |
| 605 return false; | 620 return false; |
| 606 | 621 |
| 607 policy = element()->document().settings()->imageAnimationPolicy(); | 622 policy = element()->document().settings()->imageAnimationPolicy(); |
| 608 return true; | 623 return true; |
| 609 } | 624 } |
| 610 | 625 |
| 611 void ImageLoader::dispatchPendingLoadEvents() { | 626 void ImageLoader::dispatchPendingLoadEvents() { |
| 612 loadEventSender().dispatchPendingEvents(); | 627 loadEventSender().dispatchPendingEvents(); |
| 613 } | 628 } |
| 614 | 629 |
| 615 void ImageLoader::dispatchPendingErrorEvents() { | 630 void ImageLoader::dispatchPendingErrorEvents() { |
| 616 errorEventSender().dispatchPendingEvents(); | 631 errorEventSender().dispatchPendingEvents(); |
| 617 } | 632 } |
| 618 | 633 |
| 619 void ImageLoader::elementDidMoveToNewDocument() { | 634 void ImageLoader::elementDidMoveToNewDocument() { |
| 620 if (m_loadDelayCounter) | 635 if (m_loadDelayCounter) |
| 621 m_loadDelayCounter->documentChanged(m_element->document()); | 636 m_loadDelayCounter->documentChanged(m_element->document()); |
| 622 clearFailedLoadURL(); | 637 clearFailedLoadURL(); |
| 623 setImage(0); | 638 setImage(0); |
| 624 } | 639 } |
| 625 | 640 |
| 626 } // namespace blink | 641 } // namespace blink |
| OLD | NEW |