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->getContent()); |
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 |