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