Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(355)

Side by Side Diff: third_party/WebKit/Source/core/loader/ImageLoader.cpp

Issue 2469873002: [ImageResource 4] Split ImageResource into Resource and Image parts (Closed)
Patch Set: comments Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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.
481 if (m_image) 484 if (m_image)
482 m_image->updateImageAnimationPolicy(); 485 m_image->updateImageAnimationPolicy();
483 486
484 updateLayoutObject(); 487 updateLayoutObject();
485 488
486 if (m_image && m_image->getImage() && m_image->getImage()->isSVGImage()) 489 if (m_image && m_image->getImage() && m_image->getImage()->isSVGImage())
487 toSVGImage(m_image->getImage())->updateUseCounters(element()->document()); 490 toSVGImage(m_image->getImage())->updateUseCounters(element()->document());
488 491
489 if (!m_hasPendingLoadEvent) 492 if (!m_hasPendingLoadEvent)
490 return; 493 return;
491 494
492 if (resource->errorOccurred()) { 495 if (resource->errorOccurred()) {
493 loadEventSender().cancelEvent(this); 496 loadEventSender().cancelEvent(this);
494 m_hasPendingLoadEvent = false; 497 m_hasPendingLoadEvent = false;
495 498
496 if (resource->resourceError().isAccessCheck()) {
hiroshige 2016/11/30 06:46:25 TODO: I'll revert this change in next major rebase
497 crossSiteOrCSPViolationOccurred(
498 AtomicString(resource->resourceError().failingURL()));
499 }
500
501 // The error event should not fire if the image data update is a result of 499 // The error event should not fire if the image data update is a result of
502 // environment change. 500 // environment change.
503 // https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-elem ent:the-img-element-55 501 // https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-elem ent:the-img-element-55
504 if (!m_suppressErrorEvents) 502 if (!m_suppressErrorEvents)
505 dispatchErrorEvent(); 503 dispatchErrorEvent();
506 504
507 // Only consider updating the protection ref-count of the Element 505 // Only consider updating the protection ref-count of the Element
508 // immediately before returning from this function as doing so might result 506 // immediately before returning from this function as doing so might result
509 // in the destruction of this ImageLoader. 507 // in the destruction of this ImageLoader.
510 updatedHasPendingEvent(); 508 updatedHasPendingEvent();
511 return; 509 return;
512 } 510 }
513 if (resource->wasCanceled()) {
hiroshige 2016/11/30 06:46:24 TODO: This change will be done in https://coderevi
514 m_hasPendingLoadEvent = false;
515 // Only consider updating the protection ref-count of the Element
516 // immediately before returning from this function as doing so might result
517 // in the destruction of this ImageLoader.
518 updatedHasPendingEvent();
519 return;
520 }
521 loadEventSender().dispatchEventSoon(this); 511 loadEventSender().dispatchEventSoon(this);
522 } 512 }
523 513
524 LayoutImageResource* ImageLoader::layoutImageResource() { 514 LayoutImageResource* ImageLoader::layoutImageResource() {
525 LayoutObject* layoutObject = m_element->layoutObject(); 515 LayoutObject* layoutObject = m_element->layoutObject();
526 516
527 if (!layoutObject) 517 if (!layoutObject)
528 return 0; 518 return 0;
529 519
530 // We don't return style generated image because it doesn't belong to the 520 // We don't return style generated image because it doesn't belong to the
(...skipping 13 matching lines...) Expand all
544 534
545 void ImageLoader::updateLayoutObject() { 535 void ImageLoader::updateLayoutObject() {
546 LayoutImageResource* imageResource = layoutImageResource(); 536 LayoutImageResource* imageResource = layoutImageResource();
547 537
548 if (!imageResource) 538 if (!imageResource)
549 return; 539 return;
550 540
551 // Only update the layoutObject if it doesn't have an image or if what we have 541 // Only update the layoutObject if it doesn't have an image or if what we have
552 // is a complete image. This prevents flickering in the case where a dynamic 542 // is a complete image. This prevents flickering in the case where a dynamic
553 // change is happening between two images. 543 // change is happening between two images.
554 ImageResource* cachedImage = imageResource->cachedImage(); 544 ImageResourceContent* cachedImage = imageResource->cachedImage();
555 if (m_image != cachedImage && (m_imageComplete || !cachedImage)) 545 if (m_image != cachedImage && (m_imageComplete || !cachedImage))
556 imageResource->setImageResource(m_image.get()); 546 imageResource->setImageResource(m_image.get());
557 } 547 }
558 548
559 void ImageLoader::updatedHasPendingEvent() { 549 void ImageLoader::updatedHasPendingEvent() {
560 // If an Element that does image loading is removed from the DOM the 550 // If an Element that does image loading is removed from the DOM the
561 // load/error event for the image is still observable. As long as the 551 // load/error event for the image is still observable. As long as the
562 // ImageLoader is actively loading, the Element itself needs to be ref'ed to 552 // ImageLoader is actively loading, the Element itself needs to be ref'ed to
563 // keep it from being destroyed by DOM manipulation or garbage collection. If 553 // keep it from being destroyed by DOM manipulation or garbage collection. If
564 // such an Element wishes for the load to stop when removed from the DOM it 554 // 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
640 } 630 }
641 631
642 void ImageLoader::elementDidMoveToNewDocument() { 632 void ImageLoader::elementDidMoveToNewDocument() {
643 if (m_loadDelayCounter) 633 if (m_loadDelayCounter)
644 m_loadDelayCounter->documentChanged(m_element->document()); 634 m_loadDelayCounter->documentChanged(m_element->document());
645 clearFailedLoadURL(); 635 clearFailedLoadURL();
646 setImage(0); 636 setImage(0);
647 } 637 }
648 638
649 } // namespace blink 639 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698