| 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 | 4 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights |
| 5 * reserved. | 5 * reserved. |
| 6 * | 6 * |
| 7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * 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. |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 << ", m_hasPendingErrorEvent=" << m_hasPendingErrorEvent; | 175 << ", m_hasPendingErrorEvent=" << m_hasPendingErrorEvent; |
| 176 | 176 |
| 177 if (m_image) { | 177 if (m_image) { |
| 178 m_image->removeObserver(this); | 178 m_image->removeObserver(this); |
| 179 m_image = nullptr; | 179 m_image = nullptr; |
| 180 } | 180 } |
| 181 } | 181 } |
| 182 | 182 |
| 183 DEFINE_TRACE(ImageLoader) { | 183 DEFINE_TRACE(ImageLoader) { |
| 184 visitor->trace(m_image); | 184 visitor->trace(m_image); |
| 185 visitor->trace(m_imageResourceForImageDocument); |
| 185 visitor->trace(m_element); | 186 visitor->trace(m_element); |
| 186 } | 187 } |
| 187 | 188 |
| 188 void ImageLoader::setImage(ImageResource* newImage) { | 189 void ImageLoader::setImage(ImageResourceContent* newImage) { |
| 189 setImageWithoutConsideringPendingLoadEvent(newImage); | 190 setImageWithoutConsideringPendingLoadEvent(newImage); |
| 190 | 191 |
| 191 // Only consider updating the protection ref-count of the Element immediately | 192 // Only consider updating the protection ref-count of the Element immediately |
| 192 // before returning from this function as doing so might result in the | 193 // before returning from this function as doing so might result in the |
| 193 // destruction of this ImageLoader. | 194 // destruction of this ImageLoader. |
| 194 updatedHasPendingEvent(); | 195 updatedHasPendingEvent(); |
| 195 } | 196 } |
| 196 | 197 |
| 197 void ImageLoader::setImageWithoutConsideringPendingLoadEvent( | 198 void ImageLoader::setImageWithoutConsideringPendingLoadEvent( |
| 198 ImageResource* newImage) { | 199 ImageResourceContent* newImage) { |
| 199 DCHECK(m_failedLoadURL.isEmpty()); | 200 DCHECK(m_failedLoadURL.isEmpty()); |
| 200 ImageResource* oldImage = m_image.get(); | 201 ImageResourceContent* oldImage = m_image.get(); |
| 201 if (newImage != oldImage) { | 202 if (newImage != oldImage) { |
| 202 m_image = newImage; | 203 m_image = newImage; |
| 203 if (m_hasPendingLoadEvent) { | 204 if (m_hasPendingLoadEvent) { |
| 204 loadEventSender().cancelEvent(this); | 205 loadEventSender().cancelEvent(this); |
| 205 m_hasPendingLoadEvent = false; | 206 m_hasPendingLoadEvent = false; |
| 206 } | 207 } |
| 207 if (m_hasPendingErrorEvent) { | 208 if (m_hasPendingErrorEvent) { |
| 208 errorEventSender().cancelEvent(this); | 209 errorEventSender().cancelEvent(this); |
| 209 m_hasPendingErrorEvent = false; | 210 m_hasPendingErrorEvent = false; |
| 210 } | 211 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 m_pendingTask.reset(); | 282 m_pendingTask.reset(); |
| 282 // Make sure to only decrement the count when we exit this function | 283 // Make sure to only decrement the count when we exit this function |
| 283 std::unique_ptr<IncrementLoadEventDelayCount> loadDelayCounter; | 284 std::unique_ptr<IncrementLoadEventDelayCount> loadDelayCounter; |
| 284 loadDelayCounter.swap(m_loadDelayCounter); | 285 loadDelayCounter.swap(m_loadDelayCounter); |
| 285 | 286 |
| 286 Document& document = m_element->document(); | 287 Document& document = m_element->document(); |
| 287 if (!document.isActive()) | 288 if (!document.isActive()) |
| 288 return; | 289 return; |
| 289 | 290 |
| 290 AtomicString imageSourceURL = m_element->imageSourceURL(); | 291 AtomicString imageSourceURL = m_element->imageSourceURL(); |
| 291 ImageResource* newImage = nullptr; | 292 ImageResourceContent* newImage = nullptr; |
| 292 if (!url.isNull()) { | 293 if (!url.isNull()) { |
| 293 // Unlike raw <img>, we block mixed content inside of <picture> or | 294 // Unlike raw <img>, we block mixed content inside of <picture> or |
| 294 // <img srcset>. | 295 // <img srcset>. |
| 295 ResourceLoaderOptions resourceLoaderOptions = | 296 ResourceLoaderOptions resourceLoaderOptions = |
| 296 ResourceFetcher::defaultResourceOptions(); | 297 ResourceFetcher::defaultResourceOptions(); |
| 297 ResourceRequest resourceRequest(url); | 298 ResourceRequest resourceRequest(url); |
| 298 if (updateBehavior == UpdateForcedReload) { | 299 if (updateBehavior == UpdateForcedReload) { |
| 299 resourceRequest.setCachePolicy(WebCachePolicy::BypassingCache); | 300 resourceRequest.setCachePolicy(WebCachePolicy::BypassingCache); |
| 300 resourceRequest.setLoFiState(WebURLRequest::LoFiOff); | 301 resourceRequest.setLoFiState(WebURLRequest::LoFiOff); |
| 301 } | 302 } |
| 302 | 303 |
| 303 if (referrerPolicy != ReferrerPolicyDefault) { | 304 if (referrerPolicy != ReferrerPolicyDefault) { |
| 304 resourceRequest.setHTTPReferrer(SecurityPolicy::generateReferrer( | 305 resourceRequest.setHTTPReferrer(SecurityPolicy::generateReferrer( |
| 305 referrerPolicy, url, document.outgoingReferrer())); | 306 referrerPolicy, url, document.outgoingReferrer())); |
| 306 } | 307 } |
| 307 | 308 |
| 308 if (isHTMLPictureElement(element()->parentNode()) || | 309 if (isHTMLPictureElement(element()->parentNode()) || |
| 309 !element()->fastGetAttribute(HTMLNames::srcsetAttr).isNull()) | 310 !element()->fastGetAttribute(HTMLNames::srcsetAttr).isNull()) |
| 310 resourceRequest.setRequestContext(WebURLRequest::RequestContextImageSet); | 311 resourceRequest.setRequestContext(WebURLRequest::RequestContextImageSet); |
| 311 FetchRequest request(resourceRequest, element()->localName(), | 312 FetchRequest request(resourceRequest, element()->localName(), |
| 312 resourceLoaderOptions); | 313 resourceLoaderOptions); |
| 313 configureRequest(request, bypassBehavior, *m_element, | 314 configureRequest(request, bypassBehavior, *m_element, |
| 314 document.clientHintsPreferences()); | 315 document.clientHintsPreferences()); |
| 315 | 316 |
| 316 if (updateBehavior != UpdateForcedReload && document.settings() && | 317 if (updateBehavior != UpdateForcedReload && document.settings() && |
| 317 document.settings()->fetchImagePlaceholders()) { | 318 document.settings()->fetchImagePlaceholders()) { |
| 318 request.setAllowImagePlaceholder(); | 319 request.setAllowImagePlaceholder(); |
| 319 } | 320 } |
| 320 | 321 |
| 321 newImage = ImageResource::fetch(request, document.fetcher()); | 322 newImage = ImageResourceContent::fetch(request, document.fetcher()); |
| 322 | 323 |
| 323 if (!newImage && !pageIsBeingDismissed(&document)) { | 324 if (!newImage && !pageIsBeingDismissed(&document)) { |
| 324 crossSiteOrCSPViolationOccurred(imageSourceURL); | 325 crossSiteOrCSPViolationOccurred(imageSourceURL); |
| 325 dispatchErrorEvent(); | 326 dispatchErrorEvent(); |
| 326 } else { | 327 } else { |
| 327 clearFailedLoadURL(); | 328 clearFailedLoadURL(); |
| 328 } | 329 } |
| 329 } else { | 330 } else { |
| 330 if (!imageSourceURL.isNull()) { | 331 if (!imageSourceURL.isNull()) { |
| 331 // Fire an error event if the url string is not empty, but the KURL is. | 332 // Fire an error event if the url string is not empty, but the KURL is. |
| 332 dispatchErrorEvent(); | 333 dispatchErrorEvent(); |
| 333 } | 334 } |
| 334 noImageResourceToLoad(); | 335 noImageResourceToLoad(); |
| 335 } | 336 } |
| 336 | 337 |
| 337 ImageResource* oldImage = m_image.get(); | 338 ImageResourceContent* oldImage = m_image.get(); |
| 338 if (updateBehavior == UpdateSizeChanged && m_element->layoutObject() && | 339 if (updateBehavior == UpdateSizeChanged && m_element->layoutObject() && |
| 339 m_element->layoutObject()->isImage() && newImage == oldImage) { | 340 m_element->layoutObject()->isImage() && newImage == oldImage) { |
| 340 toLayoutImage(m_element->layoutObject())->intrinsicSizeChanged(); | 341 toLayoutImage(m_element->layoutObject())->intrinsicSizeChanged(); |
| 341 } else { | 342 } else { |
| 342 if (m_hasPendingLoadEvent) { | 343 if (m_hasPendingLoadEvent) { |
| 343 loadEventSender().cancelEvent(this); | 344 loadEventSender().cancelEvent(this); |
| 344 m_hasPendingLoadEvent = false; | 345 m_hasPendingLoadEvent = false; |
| 345 } | 346 } |
| 346 | 347 |
| 347 // Cancel error events that belong to the previous load, which is now | 348 // Cancel error events that belong to the previous load, which is now |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 | 391 |
| 391 if (!m_failedLoadURL.isEmpty() && imageSourceURL == m_failedLoadURL) | 392 if (!m_failedLoadURL.isEmpty() && imageSourceURL == m_failedLoadURL) |
| 392 return; | 393 return; |
| 393 | 394 |
| 394 // Prevent the creation of a ResourceLoader (and therefore a network request) | 395 // Prevent the creation of a ResourceLoader (and therefore a network request) |
| 395 // for ImageDocument loads. In this case, the image contents have already been | 396 // for ImageDocument loads. In this case, the image contents have already been |
| 396 // requested as a main resource and ImageDocumentParser will take care of | 397 // requested as a main resource and ImageDocumentParser will take care of |
| 397 // funneling the main resource bytes into m_image, so just create an | 398 // funneling the main resource bytes into m_image, so just create an |
| 398 // ImageResource to be populated later. | 399 // ImageResource to be populated later. |
| 399 if (m_loadingImageDocument && updateBehavior != UpdateForcedReload) { | 400 if (m_loadingImageDocument && updateBehavior != UpdateForcedReload) { |
| 400 setImage( | 401 ImageResource* imageResource = |
| 401 ImageResource::create(imageSourceToKURL(m_element->imageSourceURL()))); | 402 ImageResource::create(imageSourceToKURL(m_element->imageSourceURL())); |
| 402 m_image->setStatus(Resource::Pending); | 403 imageResource->setStatus(Resource::Pending); |
| 404 m_imageResourceForImageDocument = imageResource; |
| 405 setImage(imageResource->getRealContent()); |
| 403 return; | 406 return; |
| 404 } | 407 } |
| 405 | 408 |
| 406 // If we have a pending task, we have to clear it -- either we're now loading | 409 // If we have a pending task, we have to clear it -- either we're now loading |
| 407 // immediately, or we need to reset the task's state. | 410 // immediately, or we need to reset the task's state. |
| 408 if (m_pendingTask) { | 411 if (m_pendingTask) { |
| 409 m_pendingTask->clearLoader(); | 412 m_pendingTask->clearLoader(); |
| 410 m_pendingTask.reset(); | 413 m_pendingTask.reset(); |
| 411 } | 414 } |
| 412 | 415 |
| 413 KURL url = imageSourceToKURL(imageSourceURL); | 416 KURL url = imageSourceToKURL(imageSourceURL); |
| 414 if (shouldLoadImmediately(url)) { | 417 if (shouldLoadImmediately(url)) { |
| 415 doUpdateFromElement(DoNotBypassMainWorldCSP, updateBehavior, url, | 418 doUpdateFromElement(DoNotBypassMainWorldCSP, updateBehavior, url, |
| 416 referrerPolicy); | 419 referrerPolicy); |
| 417 return; | 420 return; |
| 418 } | 421 } |
| 419 // Allow the idiom "img.src=''; img.src='.." to clear down the image before an | 422 // Allow the idiom "img.src=''; img.src='.." to clear down the image before an |
| 420 // asynchronous load completes. | 423 // asynchronous load completes. |
| 421 if (imageSourceURL.isEmpty()) { | 424 if (imageSourceURL.isEmpty()) { |
| 422 ImageResource* image = m_image.get(); | 425 ImageResourceContent* image = m_image.get(); |
| 423 if (image) { | 426 if (image) { |
| 424 image->removeObserver(this); | 427 image->removeObserver(this); |
| 425 } | 428 } |
| 426 m_image = nullptr; | 429 m_image = nullptr; |
| 427 } | 430 } |
| 428 | 431 |
| 429 // Don't load images for inactive documents. We don't want to slow down the | 432 // Don't load images for inactive documents. We don't want to slow down the |
| 430 // raw HTML parsing case by loading images we don't intend to display. | 433 // raw HTML parsing case by loading images we don't intend to display. |
| 431 Document& document = m_element->document(); | 434 Document& document = m_element->document(); |
| 432 if (document.isActive()) | 435 if (document.isActive()) |
| (...skipping 27 matching lines...) Expand all Loading... |
| 460 if (!url.isNull()) { | 463 if (!url.isNull()) { |
| 461 Resource* resource = memoryCache()->resourceForURL( | 464 Resource* resource = memoryCache()->resourceForURL( |
| 462 url, m_element->document().fetcher()->getCacheIdentifier()); | 465 url, m_element->document().fetcher()->getCacheIdentifier()); |
| 463 if (resource && !resource->errorOccurred()) | 466 if (resource && !resource->errorOccurred()) |
| 464 return true; | 467 return true; |
| 465 } | 468 } |
| 466 return (isHTMLObjectElement(m_element) || isHTMLEmbedElement(m_element) || | 469 return (isHTMLObjectElement(m_element) || isHTMLEmbedElement(m_element) || |
| 467 url.protocolIsData()); | 470 url.protocolIsData()); |
| 468 } | 471 } |
| 469 | 472 |
| 470 void ImageLoader::imageNotifyFinished(ImageResource* resource) { | 473 void ImageLoader::imageNotifyFinished(ImageResourceContent* resource) { |
| 471 RESOURCE_LOADING_DVLOG(1) | 474 RESOURCE_LOADING_DVLOG(1) |
| 472 << "ImageLoader::imageNotifyFinished " << this | 475 << "ImageLoader::imageNotifyFinished " << this |
| 473 << "; m_hasPendingLoadEvent=" << m_hasPendingLoadEvent; | 476 << "; m_hasPendingLoadEvent=" << m_hasPendingLoadEvent; |
| 474 | 477 |
| 475 DCHECK(m_failedLoadURL.isEmpty()); | 478 DCHECK(m_failedLoadURL.isEmpty()); |
| 476 DCHECK_EQ(resource, m_image.get()); | 479 DCHECK_EQ(resource, m_image.get()); |
| 477 | 480 |
| 478 m_imageComplete = true; | 481 m_imageComplete = true; |
| 479 | 482 |
| 480 // Update ImageAnimationPolicy for m_image. | 483 // Update ImageAnimationPolicy for m_image. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 503 // https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-elem
ent:the-img-element-55 | 506 // https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-elem
ent:the-img-element-55 |
| 504 if (!m_suppressErrorEvents) | 507 if (!m_suppressErrorEvents) |
| 505 dispatchErrorEvent(); | 508 dispatchErrorEvent(); |
| 506 | 509 |
| 507 // Only consider updating the protection ref-count of the Element | 510 // Only consider updating the protection ref-count of the Element |
| 508 // immediately before returning from this function as doing so might result | 511 // immediately before returning from this function as doing so might result |
| 509 // in the destruction of this ImageLoader. | 512 // in the destruction of this ImageLoader. |
| 510 updatedHasPendingEvent(); | 513 updatedHasPendingEvent(); |
| 511 return; | 514 return; |
| 512 } | 515 } |
| 513 DCHECK(!resource->wasCanceled()); | |
| 514 loadEventSender().dispatchEventSoon(this); | 516 loadEventSender().dispatchEventSoon(this); |
| 515 } | 517 } |
| 516 | 518 |
| 517 LayoutImageResource* ImageLoader::layoutImageResource() { | 519 LayoutImageResource* ImageLoader::layoutImageResource() { |
| 518 LayoutObject* layoutObject = m_element->layoutObject(); | 520 LayoutObject* layoutObject = m_element->layoutObject(); |
| 519 | 521 |
| 520 if (!layoutObject) | 522 if (!layoutObject) |
| 521 return 0; | 523 return 0; |
| 522 | 524 |
| 523 // We don't return style generated image because it doesn't belong to the | 525 // We don't return style generated image because it doesn't belong to the |
| (...skipping 13 matching lines...) Expand all Loading... |
| 537 | 539 |
| 538 void ImageLoader::updateLayoutObject() { | 540 void ImageLoader::updateLayoutObject() { |
| 539 LayoutImageResource* imageResource = layoutImageResource(); | 541 LayoutImageResource* imageResource = layoutImageResource(); |
| 540 | 542 |
| 541 if (!imageResource) | 543 if (!imageResource) |
| 542 return; | 544 return; |
| 543 | 545 |
| 544 // Only update the layoutObject if it doesn't have an image or if what we have | 546 // Only update the layoutObject if it doesn't have an image or if what we have |
| 545 // is a complete image. This prevents flickering in the case where a dynamic | 547 // is a complete image. This prevents flickering in the case where a dynamic |
| 546 // change is happening between two images. | 548 // change is happening between two images. |
| 547 ImageResource* cachedImage = imageResource->cachedImage(); | 549 ImageResourceContent* cachedImage = imageResource->cachedImage(); |
| 548 if (m_image != cachedImage && (m_imageComplete || !cachedImage)) | 550 if (m_image != cachedImage && (m_imageComplete || !cachedImage)) |
| 549 imageResource->setImageResource(m_image.get()); | 551 imageResource->setImageResource(m_image.get()); |
| 550 } | 552 } |
| 551 | 553 |
| 552 void ImageLoader::updatedHasPendingEvent() { | 554 void ImageLoader::updatedHasPendingEvent() { |
| 553 // If an Element that does image loading is removed from the DOM the | 555 // If an Element that does image loading is removed from the DOM the |
| 554 // load/error event for the image is still observable. As long as the | 556 // load/error event for the image is still observable. As long as the |
| 555 // ImageLoader is actively loading, the Element itself needs to be ref'ed to | 557 // ImageLoader is actively loading, the Element itself needs to be ref'ed to |
| 556 // keep it from being destroyed by DOM manipulation or garbage collection. If | 558 // 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 | 559 // such an Element wishes for the load to stop when removed from the DOM it |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 } | 635 } |
| 634 | 636 |
| 635 void ImageLoader::elementDidMoveToNewDocument() { | 637 void ImageLoader::elementDidMoveToNewDocument() { |
| 636 if (m_loadDelayCounter) | 638 if (m_loadDelayCounter) |
| 637 m_loadDelayCounter->documentChanged(m_element->document()); | 639 m_loadDelayCounter->documentChanged(m_element->document()); |
| 638 clearFailedLoadURL(); | 640 clearFailedLoadURL(); |
| 639 setImage(0); | 641 setImage(0); |
| 640 } | 642 } |
| 641 | 643 |
| 642 } // namespace blink | 644 } // namespace blink |
| OLD | NEW |