| OLD | NEW |
| 1 /* | 1 /* |
| 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) | 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) |
| 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) | 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) |
| 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) | 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) |
| 5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) |
| 6 Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. | 6 Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. |
| 7 | 7 |
| 8 This library is free software; you can redistribute it and/or | 8 This library is free software; you can redistribute it and/or |
| 9 modify it under the terms of the GNU Library General Public | 9 modify it under the terms of the GNU Library General Public |
| 10 License as published by the Free Software Foundation; either | 10 License as published by the Free Software Foundation; either |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 } | 140 } |
| 141 | 141 |
| 142 DEFINE_TRACE(ImageResource) { | 142 DEFINE_TRACE(ImageResource) { |
| 143 visitor->trace(m_multipartParser); | 143 visitor->trace(m_multipartParser); |
| 144 Resource::trace(visitor); | 144 Resource::trace(visitor); |
| 145 ImageObserver::trace(visitor); | 145 ImageObserver::trace(visitor); |
| 146 MultipartImageResourceParser::Client::trace(visitor); | 146 MultipartImageResourceParser::Client::trace(visitor); |
| 147 } | 147 } |
| 148 | 148 |
| 149 void ImageResource::checkNotify() { | 149 void ImageResource::checkNotify() { |
| 150 // Don't notify observers and clients of completion if this ImageResource is | 150 // Don't notify clients of completion if this ImageResource is |
| 151 // about to be reloaded. | 151 // about to be reloaded. |
| 152 if (m_isSchedulingReload || shouldReloadBrokenPlaceholder()) | 152 if (m_isSchedulingReload || shouldReloadBrokenPlaceholder()) |
| 153 return; | 153 return; |
| 154 | 154 |
| 155 notifyObserversInternal(); | |
| 156 Resource::checkNotify(); | 155 Resource::checkNotify(); |
| 157 } | 156 } |
| 158 | 157 |
| 159 void ImageResource::notifyObserversInternal() { | |
| 160 if (isLoading()) | |
| 161 return; | |
| 162 | |
| 163 for (auto* observer : m_observers.asVector()) { | |
| 164 if (m_observers.contains(observer)) { | |
| 165 markObserverFinished(observer); | |
| 166 observer->imageNotifyFinished(this); | |
| 167 } | |
| 168 } | |
| 169 } | |
| 170 | |
| 171 void ImageResource::markObserverFinished(ImageResourceObserver* observer) { | 158 void ImageResource::markObserverFinished(ImageResourceObserver* observer) { |
| 172 if (m_observers.contains(observer)) { | 159 if (m_observers.contains(observer)) { |
| 173 m_finishedObservers.add(observer); | 160 m_finishedObservers.add(observer); |
| 174 m_observers.remove(observer); | 161 m_observers.remove(observer); |
| 175 } | 162 } |
| 176 } | 163 } |
| 177 | 164 |
| 178 void ImageResource::didAddClient(ResourceClient* client) { | 165 void ImageResource::didAddClient(ResourceClient* client) { |
| 179 DCHECK((m_multipartParser && isLoading()) || !data() || m_image); | 166 DCHECK((m_multipartParser && isLoading()) || !data() || m_image); |
| 180 | 167 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 201 // On the other hand, when the response is multipart, |updateImage()| is not | 188 // On the other hand, when the response is multipart, |updateImage()| is not |
| 202 // called in |appendData()|, which means |m_image| might not be created even | 189 // called in |appendData()|, which means |m_image| might not be created even |
| 203 // when |data()| exists. This is intentional since creating a |m_image| on | 190 // when |data()| exists. This is intentional since creating a |m_image| on |
| 204 // receiving data might destroy an existing image in a previous part. | 191 // receiving data might destroy an existing image in a previous part. |
| 205 DCHECK((m_multipartParser && isLoading()) || !data() || m_image); | 192 DCHECK((m_multipartParser && isLoading()) || !data() || m_image); |
| 206 | 193 |
| 207 if (m_image && !m_image->isNull()) { | 194 if (m_image && !m_image->isNull()) { |
| 208 observer->imageChanged(this); | 195 observer->imageChanged(this); |
| 209 } | 196 } |
| 210 | 197 |
| 211 if (isLoaded() && !m_isSchedulingReload && !shouldReloadBrokenPlaceholder()) { | 198 if (isLoaded() && m_observers.contains(observer) && !m_isSchedulingReload && |
| 199 !shouldReloadBrokenPlaceholder()) { |
| 212 markObserverFinished(observer); | 200 markObserverFinished(observer); |
| 213 observer->imageNotifyFinished(this); | 201 observer->imageNotifyFinished(this); |
| 214 } | 202 } |
| 215 } | 203 } |
| 216 | 204 |
| 217 void ImageResource::removeObserver(ImageResourceObserver* observer) { | 205 void ImageResource::removeObserver(ImageResourceObserver* observer) { |
| 218 DCHECK(observer); | 206 DCHECK(observer); |
| 219 | 207 |
| 220 if (m_observers.contains(observer)) | 208 if (m_observers.contains(observer)) |
| 221 m_observers.remove(observer); | 209 m_observers.remove(observer); |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 | 404 |
| 417 // Don't let images that have a width/height >= 1 shrink below 1 when zoomed. | 405 // Don't let images that have a width/height >= 1 shrink below 1 when zoomed. |
| 418 LayoutSize minimumSize( | 406 LayoutSize minimumSize( |
| 419 size.width() > LayoutUnit() ? LayoutUnit(1) : LayoutUnit(), | 407 size.width() > LayoutUnit() ? LayoutUnit(1) : LayoutUnit(), |
| 420 LayoutUnit(size.height() > LayoutUnit() ? LayoutUnit(1) : LayoutUnit())); | 408 LayoutUnit(size.height() > LayoutUnit() ? LayoutUnit(1) : LayoutUnit())); |
| 421 size.scale(multiplier); | 409 size.scale(multiplier); |
| 422 size.clampToMinimumSize(minimumSize); | 410 size.clampToMinimumSize(minimumSize); |
| 423 return size; | 411 return size; |
| 424 } | 412 } |
| 425 | 413 |
| 426 void ImageResource::notifyObservers(const IntRect* changeRect) { | 414 void ImageResource::notifyObservers(NotifyFinishOption notifyingFinishOption, |
| 415 const IntRect* changeRect) { |
| 427 for (auto* observer : m_finishedObservers.asVector()) { | 416 for (auto* observer : m_finishedObservers.asVector()) { |
| 428 if (m_finishedObservers.contains(observer)) | 417 if (m_finishedObservers.contains(observer)) |
| 429 observer->imageChanged(this, changeRect); | 418 observer->imageChanged(this, changeRect); |
| 430 } | 419 } |
| 431 for (auto* observer : m_observers.asVector()) { | 420 for (auto* observer : m_observers.asVector()) { |
| 432 if (m_observers.contains(observer)) | 421 if (m_observers.contains(observer)) { |
| 433 observer->imageChanged(this, changeRect); | 422 observer->imageChanged(this, changeRect); |
| 423 if (notifyingFinishOption == ShouldNotifyFinish && |
| 424 m_observers.contains(observer) && !m_isSchedulingReload && |
| 425 !shouldReloadBrokenPlaceholder()) { |
| 426 markObserverFinished(observer); |
| 427 observer->imageNotifyFinished(this); |
| 428 } |
| 429 } |
| 434 } | 430 } |
| 435 } | 431 } |
| 436 | 432 |
| 437 void ImageResource::clear() { | 433 void ImageResource::clear() { |
| 438 clearImage(); | 434 clearImage(); |
| 439 clearData(); | 435 clearData(); |
| 440 setEncodedSize(0); | 436 setEncodedSize(0); |
| 441 } | 437 } |
| 442 | 438 |
| 443 inline void ImageResource::createImage() { | 439 inline void ImageResource::createImage() { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 if (!errorOccurred()) | 502 if (!errorOccurred()) |
| 507 setStatus(DecodeError); | 503 setStatus(DecodeError); |
| 508 if (!allDataReceived && loader()) { | 504 if (!allDataReceived && loader()) { |
| 509 loader()->didFinishLoading(monotonicallyIncreasingTime(), size, size); | 505 loader()->didFinishLoading(monotonicallyIncreasingTime(), size, size); |
| 510 } | 506 } |
| 511 memoryCache()->remove(this); | 507 memoryCache()->remove(this); |
| 512 } | 508 } |
| 513 | 509 |
| 514 // It would be nice to only redraw the decoded band of the image, but with the | 510 // It would be nice to only redraw the decoded band of the image, but with the |
| 515 // current design (decoding delayed until painting) that seems hard. | 511 // current design (decoding delayed until painting) that seems hard. |
| 516 notifyObservers(); | 512 notifyObservers(allDataReceived ? ShouldNotifyFinish : DoNotNotifyFinish); |
| 517 } | 513 } |
| 518 | 514 |
| 519 void ImageResource::updateImageAndClearBuffer() { | 515 void ImageResource::updateImageAndClearBuffer() { |
| 520 clearImage(); | 516 clearImage(); |
| 521 updateImage(true); | 517 updateImage(true); |
| 522 clearData(); | 518 clearData(); |
| 523 } | 519 } |
| 524 | 520 |
| 525 void ImageResource::finish(double loadFinishTime) { | 521 void ImageResource::finish(double loadFinishTime) { |
| 526 if (m_multipartParser) { | 522 if (m_multipartParser) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 537 clearData(); | 533 clearData(); |
| 538 } | 534 } |
| 539 Resource::finish(loadFinishTime); | 535 Resource::finish(loadFinishTime); |
| 540 } | 536 } |
| 541 | 537 |
| 542 void ImageResource::error(const ResourceError& error) { | 538 void ImageResource::error(const ResourceError& error) { |
| 543 if (m_multipartParser) | 539 if (m_multipartParser) |
| 544 m_multipartParser->cancel(); | 540 m_multipartParser->cancel(); |
| 545 clear(); | 541 clear(); |
| 546 Resource::error(error); | 542 Resource::error(error); |
| 547 notifyObservers(); | 543 notifyObservers(ShouldNotifyFinish); |
| 548 } | 544 } |
| 549 | 545 |
| 550 void ImageResource::responseReceived( | 546 void ImageResource::responseReceived( |
| 551 const ResourceResponse& response, | 547 const ResourceResponse& response, |
| 552 std::unique_ptr<WebDataConsumerHandle> handle) { | 548 std::unique_ptr<WebDataConsumerHandle> handle) { |
| 553 DCHECK(!handle); | 549 DCHECK(!handle); |
| 554 DCHECK(!m_multipartParser); | 550 DCHECK(!m_multipartParser); |
| 555 // If there's no boundary, just handle the request normally. | 551 // If there's no boundary, just handle the request normally. |
| 556 if (response.isMultipart() && !response.multipartBoundary().isEmpty()) { | 552 if (response.isMultipart() && !response.multipartBoundary().isEmpty()) { |
| 557 m_multipartParser = new MultipartImageResourceParser( | 553 m_multipartParser = new MultipartImageResourceParser( |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 if (m_observers.contains(observer) && observer->willRenderImage()) | 588 if (m_observers.contains(observer) && observer->willRenderImage()) |
| 593 return false; | 589 return false; |
| 594 } | 590 } |
| 595 | 591 |
| 596 return true; | 592 return true; |
| 597 } | 593 } |
| 598 | 594 |
| 599 void ImageResource::animationAdvanced(const blink::Image* image) { | 595 void ImageResource::animationAdvanced(const blink::Image* image) { |
| 600 if (!image || image != m_image) | 596 if (!image || image != m_image) |
| 601 return; | 597 return; |
| 602 notifyObservers(); | 598 notifyObservers(DoNotNotifyFinish); |
| 603 } | 599 } |
| 604 | 600 |
| 605 void ImageResource::updateImageAnimationPolicy() { | 601 void ImageResource::updateImageAnimationPolicy() { |
| 606 if (!m_image) | 602 if (!m_image) |
| 607 return; | 603 return; |
| 608 | 604 |
| 609 ImageAnimationPolicy newPolicy = ImageAnimationPolicyAllowed; | 605 ImageAnimationPolicy newPolicy = ImageAnimationPolicyAllowed; |
| 610 for (auto* observer : m_finishedObservers.asVector()) { | 606 for (auto* observer : m_finishedObservers.asVector()) { |
| 611 if (m_finishedObservers.contains(observer) && | 607 if (m_finishedObservers.contains(observer) && |
| 612 observer->getImageAnimationPolicy(newPolicy)) | 608 observer->getImageAnimationPolicy(newPolicy)) |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 clearRangeRequestHeader(); | 651 clearRangeRequestHeader(); |
| 656 } | 652 } |
| 657 | 653 |
| 658 if (isLoading()) { | 654 if (isLoading()) { |
| 659 loader()->cancel(); | 655 loader()->cancel(); |
| 660 // Canceling the loader causes error() to be called, which in turn calls | 656 // Canceling the loader causes error() to be called, which in turn calls |
| 661 // clear() and notifyObservers(), so there's no need to call these again | 657 // clear() and notifyObservers(), so there's no need to call these again |
| 662 // here. | 658 // here. |
| 663 } else { | 659 } else { |
| 664 clear(); | 660 clear(); |
| 665 notifyObservers(); | 661 notifyObservers(DoNotNotifyFinish); |
| 666 } | 662 } |
| 667 | 663 |
| 668 setStatus(NotStarted); | 664 setStatus(NotStarted); |
| 669 | 665 |
| 670 DCHECK(m_isSchedulingReload); | 666 DCHECK(m_isSchedulingReload); |
| 671 m_isSchedulingReload = false; | 667 m_isSchedulingReload = false; |
| 672 | 668 |
| 673 fetcher->startLoad(this); | 669 fetcher->startLoad(this); |
| 674 } | 670 } |
| 675 | 671 |
| 676 void ImageResource::changedInRect(const blink::Image* image, | 672 void ImageResource::changedInRect(const blink::Image* image, |
| 677 const IntRect& rect) { | 673 const IntRect& rect) { |
| 678 if (!image || image != m_image) | 674 if (!image || image != m_image) |
| 679 return; | 675 return; |
| 680 notifyObservers(&rect); | 676 notifyObservers(DoNotNotifyFinish, &rect); |
| 681 } | 677 } |
| 682 | 678 |
| 683 void ImageResource::onePartInMultipartReceived( | 679 void ImageResource::onePartInMultipartReceived( |
| 684 const ResourceResponse& response) { | 680 const ResourceResponse& response) { |
| 685 DCHECK(m_multipartParser); | 681 DCHECK(m_multipartParser); |
| 686 | 682 |
| 687 setResponse(response); | 683 setResponse(response); |
| 688 if (m_multipartParsingState == MultipartParsingState::WaitingForFirstPart) { | 684 if (m_multipartParsingState == MultipartParsingState::WaitingForFirstPart) { |
| 689 // We have nothing to do because we don't have any data. | 685 // We have nothing to do because we don't have any data. |
| 690 m_multipartParsingState = MultipartParsingState::ParsingFirstPart; | 686 m_multipartParsingState = MultipartParsingState::ParsingFirstPart; |
| 691 return; | 687 return; |
| 692 } | 688 } |
| 693 updateImageAndClearBuffer(); | 689 updateImageAndClearBuffer(); |
| 694 | 690 |
| 695 if (m_multipartParsingState == MultipartParsingState::ParsingFirstPart) { | 691 if (m_multipartParsingState == MultipartParsingState::ParsingFirstPart) { |
| 696 m_multipartParsingState = MultipartParsingState::FinishedParsingFirstPart; | 692 m_multipartParsingState = MultipartParsingState::FinishedParsingFirstPart; |
| 697 // Notify finished when the first part ends. | 693 // Notify finished when the first part ends. |
| 698 if (!errorOccurred()) | 694 if (!errorOccurred()) |
| 699 setStatus(Cached); | 695 setStatus(Cached); |
| 700 // We notify clients/observers of finish here, and they will not be | 696 // We notify clients and observers of finish in checkNotify() and |
| 697 // updateImageAndClearBuffer(), respectively, and they will not be |
| 701 // notified again in Resource::finish()/error(). | 698 // notified again in Resource::finish()/error(). |
| 702 checkNotify(); | 699 checkNotify(); |
| 703 if (loader()) | 700 if (loader()) |
| 704 loader()->didFinishLoadingFirstPartInMultipart(); | 701 loader()->didFinishLoadingFirstPartInMultipart(); |
| 705 } | 702 } |
| 706 } | 703 } |
| 707 | 704 |
| 708 void ImageResource::multipartDataReceived(const char* bytes, size_t size) { | 705 void ImageResource::multipartDataReceived(const char* bytes, size_t size) { |
| 709 DCHECK(m_multipartParser); | 706 DCHECK(m_multipartParser); |
| 710 Resource::appendData(bytes, size); | 707 Resource::appendData(bytes, size); |
| 711 } | 708 } |
| 712 | 709 |
| 713 bool ImageResource::isAccessAllowed(SecurityOrigin* securityOrigin) { | 710 bool ImageResource::isAccessAllowed(SecurityOrigin* securityOrigin) { |
| 714 if (response().wasFetchedViaServiceWorker()) { | 711 if (response().wasFetchedViaServiceWorker()) { |
| 715 return response().serviceWorkerResponseType() != | 712 return response().serviceWorkerResponseType() != |
| 716 WebServiceWorkerResponseTypeOpaque; | 713 WebServiceWorkerResponseTypeOpaque; |
| 717 } | 714 } |
| 718 if (!getImage()->currentFrameHasSingleSecurityOrigin()) | 715 if (!getImage()->currentFrameHasSingleSecurityOrigin()) |
| 719 return false; | 716 return false; |
| 720 if (passesAccessControlCheck(securityOrigin)) | 717 if (passesAccessControlCheck(securityOrigin)) |
| 721 return true; | 718 return true; |
| 722 return !securityOrigin->taintsCanvas(response().url()); | 719 return !securityOrigin->taintsCanvas(response().url()); |
| 723 } | 720 } |
| 724 | 721 |
| 725 } // namespace blink | 722 } // namespace blink |
| OLD | NEW |