Chromium Code Reviews| 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 |
|
yhirano
2016/10/03 08:37:34
Why don't you put more words on this line?
Charlie Harrison
2016/10/03 12:30:05
Good catch, I must have missed this comment. Done.
| |
| 509 // from this function as doing so might result in the destruction of this | |
| 510 // ImageLoader. | |
| 499 updatedHasPendingEvent(); | 511 updatedHasPendingEvent(); |
| 500 return; | 512 return; |
| 501 } | 513 } |
| 502 loadEventSender().dispatchEventSoon(this); | 514 loadEventSender().dispatchEventSoon(this); |
| 503 } | 515 } |
| 504 | 516 |
| 505 LayoutImageResource* ImageLoader::layoutImageResource() { | 517 LayoutImageResource* ImageLoader::layoutImageResource() { |
| 506 LayoutObject* layoutObject = m_element->layoutObject(); | 518 LayoutObject* layoutObject = m_element->layoutObject(); |
| 507 | 519 |
| 508 if (!layoutObject) | 520 if (!layoutObject) |
| 509 return 0; | 521 return 0; |
| 510 | 522 |
| 511 // We don't return style generated image because it doesn't belong to the Imag eLoader. | 523 // 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> | 524 // ImageLoader. See <https://bugs.webkit.org/show_bug.cgi?id=42840> |
| 513 if (layoutObject->isImage() && | 525 if (layoutObject->isImage() && |
| 514 !static_cast<LayoutImage*>(layoutObject)->isGeneratedContent()) | 526 !static_cast<LayoutImage*>(layoutObject)->isGeneratedContent()) |
| 515 return toLayoutImage(layoutObject)->imageResource(); | 527 return toLayoutImage(layoutObject)->imageResource(); |
| 516 | 528 |
| 517 if (layoutObject->isSVGImage()) | 529 if (layoutObject->isSVGImage()) |
| 518 return toLayoutSVGImage(layoutObject)->imageResource(); | 530 return toLayoutSVGImage(layoutObject)->imageResource(); |
| 519 | 531 |
| 520 if (layoutObject->isVideo()) | 532 if (layoutObject->isVideo()) |
| 521 return toLayoutVideo(layoutObject)->imageResource(); | 533 return toLayoutVideo(layoutObject)->imageResource(); |
| 522 | 534 |
| 523 return 0; | 535 return 0; |
| 524 } | 536 } |
| 525 | 537 |
| 526 void ImageLoader::updateLayoutObject() { | 538 void ImageLoader::updateLayoutObject() { |
| 527 LayoutImageResource* imageResource = layoutImageResource(); | 539 LayoutImageResource* imageResource = layoutImageResource(); |
| 528 | 540 |
| 529 if (!imageResource) | 541 if (!imageResource) |
| 530 return; | 542 return; |
| 531 | 543 |
| 532 // Only update the layoutObject if it doesn't have an image or if what we have | 544 // 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 | 545 // is a complete image. This prevents flickering in the case where a dynamic |
| 534 // change is happening between two images. | 546 // change is happening between two images. |
| 535 ImageResource* cachedImage = imageResource->cachedImage(); | 547 ImageResource* cachedImage = imageResource->cachedImage(); |
| 536 if (m_image != cachedImage && (m_imageComplete || !cachedImage)) | 548 if (m_image != cachedImage && (m_imageComplete || !cachedImage)) |
| 537 imageResource->setImageResource(m_image.get()); | 549 imageResource->setImageResource(m_image.get()); |
| 538 } | 550 } |
| 539 | 551 |
| 540 void ImageLoader::updatedHasPendingEvent() { | 552 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. | 553 // 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 | 554 // load/error event for the image is still observable. As long as the |
| 543 // destroyed by DOM manipulation or garbage collection. | 555 // 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. | 556 // keep it from being destroyed by DOM manipulation or garbage collection. If |
| 557 // such an Element wishes for the load to stop when removed from the DOM it | |
| 558 // needs to stop the ImageLoader explicitly. | |
| 545 bool wasProtected = m_elementIsProtected; | 559 bool wasProtected = m_elementIsProtected; |
| 546 m_elementIsProtected = m_hasPendingLoadEvent || m_hasPendingErrorEvent; | 560 m_elementIsProtected = m_hasPendingLoadEvent || m_hasPendingErrorEvent; |
| 547 if (wasProtected == m_elementIsProtected) | 561 if (wasProtected == m_elementIsProtected) |
| 548 return; | 562 return; |
| 549 | 563 |
| 550 if (m_elementIsProtected) { | 564 if (m_elementIsProtected) { |
| 551 if (m_derefElementTimer.isActive()) | 565 if (m_derefElementTimer.isActive()) |
| 552 m_derefElementTimer.stop(); | 566 m_derefElementTimer.stop(); |
| 553 else | 567 else |
| 554 m_keepAlive = m_element; | 568 m_keepAlive = m_element; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 575 | 589 |
| 576 void ImageLoader::dispatchPendingLoadEvent() { | 590 void ImageLoader::dispatchPendingLoadEvent() { |
| 577 if (!m_hasPendingLoadEvent) | 591 if (!m_hasPendingLoadEvent) |
| 578 return; | 592 return; |
| 579 if (!m_image) | 593 if (!m_image) |
| 580 return; | 594 return; |
| 581 m_hasPendingLoadEvent = false; | 595 m_hasPendingLoadEvent = false; |
| 582 if (element()->document().frame()) | 596 if (element()->document().frame()) |
| 583 dispatchLoadEvent(); | 597 dispatchLoadEvent(); |
| 584 | 598 |
| 585 // Only consider updating the protection ref-count of the Element immediately before returning | 599 // 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. | 600 // before returning from this function as doing so might result in the |
| 601 // destruction of this ImageLoader. | |
| 587 updatedHasPendingEvent(); | 602 updatedHasPendingEvent(); |
| 588 } | 603 } |
| 589 | 604 |
| 590 void ImageLoader::dispatchPendingErrorEvent() { | 605 void ImageLoader::dispatchPendingErrorEvent() { |
| 591 if (!m_hasPendingErrorEvent) | 606 if (!m_hasPendingErrorEvent) |
| 592 return; | 607 return; |
| 593 m_hasPendingErrorEvent = false; | 608 m_hasPendingErrorEvent = false; |
| 594 | 609 |
| 595 if (element()->document().frame()) | 610 if (element()->document().frame()) |
| 596 element()->dispatchEvent(Event::create(EventTypeNames::error)); | 611 element()->dispatchEvent(Event::create(EventTypeNames::error)); |
| 597 | 612 |
| 598 // Only consider updating the protection ref-count of the Element immediately before returning | 613 // 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. | 614 // before returning from this function as doing so might result in the |
| 615 // destruction of this ImageLoader. | |
| 600 updatedHasPendingEvent(); | 616 updatedHasPendingEvent(); |
| 601 } | 617 } |
| 602 | 618 |
| 603 bool ImageLoader::getImageAnimationPolicy(ImageAnimationPolicy& policy) { | 619 bool ImageLoader::getImageAnimationPolicy(ImageAnimationPolicy& policy) { |
| 604 if (!element()->document().settings()) | 620 if (!element()->document().settings()) |
| 605 return false; | 621 return false; |
| 606 | 622 |
| 607 policy = element()->document().settings()->imageAnimationPolicy(); | 623 policy = element()->document().settings()->imageAnimationPolicy(); |
| 608 return true; | 624 return true; |
| 609 } | 625 } |
| 610 | 626 |
| 611 void ImageLoader::dispatchPendingLoadEvents() { | 627 void ImageLoader::dispatchPendingLoadEvents() { |
| 612 loadEventSender().dispatchPendingEvents(); | 628 loadEventSender().dispatchPendingEvents(); |
| 613 } | 629 } |
| 614 | 630 |
| 615 void ImageLoader::dispatchPendingErrorEvents() { | 631 void ImageLoader::dispatchPendingErrorEvents() { |
| 616 errorEventSender().dispatchPendingEvents(); | 632 errorEventSender().dispatchPendingEvents(); |
| 617 } | 633 } |
| 618 | 634 |
| 619 void ImageLoader::elementDidMoveToNewDocument() { | 635 void ImageLoader::elementDidMoveToNewDocument() { |
| 620 if (m_loadDelayCounter) | 636 if (m_loadDelayCounter) |
| 621 m_loadDelayCounter->documentChanged(m_element->document()); | 637 m_loadDelayCounter->documentChanged(m_element->document()); |
| 622 clearFailedLoadURL(); | 638 clearFailedLoadURL(); |
| 623 setImage(0); | 639 setImage(0); |
| 624 } | 640 } |
| 625 | 641 |
| 626 } // namespace blink | 642 } // namespace blink |
| OLD | NEW |