void ImageDocumentParser::finish() { if (!isStopped() && document()->imageElement() && document()->cachedImage()) { ImageResource* cachedImage = document()->cachedImage(); cachedImage->finish(); cachedImage->setResponse(document()->frame()->loader().documentLoader()->response()); // Report the natural image size in the page title, regardless of zoom level. // At a zoom level of 1 the image is guaranteed to have an integer size. IntSize size = flooredIntSize(cachedImage->imageSizeForLayoutObject(document()->imageElement()->layoutObject(), 1.0f)); if (size.width()) { // Compute the title, we use the decoded filename of the resource, falling // back on the (decoded) hostname if there is no path. String fileName = decodeURLEscapeSequences(document()->url().lastPathComponent()); if (fileName.isEmpty()) fileName = document()->url().host(); document()->setTitle(imageTitle(fileName, size)); } document()->imageUpdated(); } if (document()) document()->finishedParsing(); }
void ImageDocumentParser::finish() { if (!isStopped() && document()->imageElement() && document()->cachedImage()) { ImageResource* cachedImage = document()->cachedImage(); DocumentLoader* loader = document()->loader(); cachedImage->setResponse(loader->response()); cachedImage->setLoadFinishTime(loader->timing().responseEnd()); cachedImage->finish(); // Report the natural image size in the page title, regardless of zoom level. // At a zoom level of 1 the image is guaranteed to have an integer size. IntSize size = flooredIntSize(cachedImage->imageSizeForLayoutObject(document()->imageElement()->layoutObject(), 1.0f)); if (size.width()) { // Compute the title, we use the decoded filename of the resource, falling // back on the (decoded) hostname if there is no path. String fileName = decodeURLEscapeSequences(document()->url().lastPathComponent()); if (fileName.isEmpty()) fileName = document()->url().host(); document()->setTitle(imageTitle(fileName, size)); } document()->imageUpdated(); } // TODO(esprehn): These null checks on Document don't make sense, document() // will ASSERT if it was null. Do these want to check isDetached() ? if (document()) document()->finishedParsing(); }
TEST(ImageResourceTest, DecodedDataRemainsWhileHasClients) { ImageResource* cachedImage = ImageResource::create(ResourceRequest()); cachedImage->setStatus(Resource::Pending); Persistent<MockImageResourceClient> client = new MockImageResourceClient(cachedImage); // Send the image response. cachedImage->responseReceived(ResourceResponse(KURL(), "multipart/x-mixed-replace", 0, nullAtom, String()), nullptr); Vector<unsigned char> jpeg = jpegImage(); cachedImage->responseReceived(ResourceResponse(KURL(), "image/jpeg", jpeg.size(), nullAtom, String()), nullptr); cachedImage->appendData(reinterpret_cast<const char*>(jpeg.data()), jpeg.size()); cachedImage->finish(); ASSERT_FALSE(cachedImage->errorOccurred()); ASSERT_TRUE(cachedImage->hasImage()); ASSERT_FALSE(cachedImage->getImage()->isNull()); ASSERT_TRUE(client->notifyFinishedCalled()); // The prune comes when the ImageResource still has clients. The image should not be deleted. cachedImage->prune(); ASSERT_TRUE(cachedImage->hasClientsOrObservers()); ASSERT_TRUE(cachedImage->hasImage()); ASSERT_FALSE(cachedImage->getImage()->isNull()); // The ImageResource no longer has clients. The image should be deleted by prune. client->removeAsClient(); cachedImage->prune(); ASSERT_FALSE(cachedImage->hasClientsOrObservers()); ASSERT_FALSE(cachedImage->hasImage()); ASSERT_TRUE(cachedImage->getImage()->isNull()); }
TEST(ImageResourceTest, ReloadIfLoFi) { KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html"); URLTestHelpers::registerMockedURLLoad(testURL, "cancelTest.html", "text/html"); ResourceRequest request = ResourceRequest(testURL); request.setLoFiState(WebURLRequest::LoFiOn); ImageResource* cachedImage = ImageResource::create(request); cachedImage->setStatus(Resource::Pending); Persistent<MockImageResourceClient> client = new MockImageResourceClient(cachedImage); ResourceFetcher* fetcher = ResourceFetcher::create(ImageResourceTestMockFetchContext::create()); // Send the image response. Vector<unsigned char> jpeg = jpegImage(); ResourceResponse resourceResponse(KURL(), "image/jpeg", jpeg.size(), nullAtom, String()); resourceResponse.addHTTPHeaderField("chrome-proxy", "q=low"); cachedImage->responseReceived(resourceResponse, nullptr); cachedImage->appendData(reinterpret_cast<const char*>(jpeg.data()), jpeg.size()); cachedImage->finish(); ASSERT_FALSE(cachedImage->errorOccurred()); ASSERT_TRUE(cachedImage->hasImage()); ASSERT_FALSE(cachedImage->getImage()->isNull()); ASSERT_EQ(client->imageChangedCount(), 2); ASSERT_TRUE(client->notifyFinishedCalled()); ASSERT_TRUE(cachedImage->getImage()->isBitmapImage()); EXPECT_EQ(1, cachedImage->getImage()->width()); EXPECT_EQ(1, cachedImage->getImage()->height()); cachedImage->reloadIfLoFi(fetcher); ASSERT_FALSE(cachedImage->errorOccurred()); ASSERT_FALSE(cachedImage->resourceBuffer()); ASSERT_FALSE(cachedImage->hasImage()); ASSERT_EQ(client->imageChangedCount(), 3); cachedImage->loader()->didReceiveResponse(nullptr, WrappedResourceResponse(resourceResponse), nullptr); cachedImage->loader()->didReceiveData(nullptr, reinterpret_cast<const char*>(jpeg.data()), jpeg.size(), jpeg.size()); cachedImage->loader()->didFinishLoading(nullptr, 0.0, jpeg.size()); ASSERT_FALSE(cachedImage->errorOccurred()); ASSERT_TRUE(cachedImage->hasImage()); ASSERT_FALSE(cachedImage->getImage()->isNull()); ASSERT_TRUE(client->notifyFinishedCalled()); ASSERT_TRUE(cachedImage->getImage()->isBitmapImage()); }
TEST(ImageResourceTest, UpdateBitmapImages) { ImageResource* cachedImage = ImageResource::create(ResourceRequest()); cachedImage->setStatus(Resource::Pending); Persistent<MockImageResourceClient> client = new MockImageResourceClient(cachedImage); // Send the image response. Vector<unsigned char> jpeg = jpegImage(); cachedImage->responseReceived(ResourceResponse(KURL(), "image/jpeg", jpeg.size(), nullAtom, String()), nullptr); cachedImage->appendData(reinterpret_cast<const char*>(jpeg.data()), jpeg.size()); cachedImage->finish(); ASSERT_FALSE(cachedImage->errorOccurred()); ASSERT_TRUE(cachedImage->hasImage()); ASSERT_FALSE(cachedImage->getImage()->isNull()); ASSERT_EQ(client->imageChangedCount(), 2); ASSERT_TRUE(client->notifyFinishedCalled()); ASSERT_TRUE(cachedImage->getImage()->isBitmapImage()); }
TEST(ImageResourceTest, AddClientAfterPrune) { KURL url(ParsedURLString, "http://127.0.0.1:8000/foo"); ImageResource* imageResource = ImageResource::create(ResourceRequest(url)); // Adds a ResourceClient but not ImageResourceObserver. Persistent<MockResourceClient> client1 = new MockResourceClient(imageResource); Vector<unsigned char> jpeg = jpegImage(); ResourceResponse response; response.setURL(url); response.setHTTPStatusCode(200); response.setMimeType("image/jpeg"); imageResource->responseReceived(response, nullptr); imageResource->appendData(reinterpret_cast<const char*>(jpeg.data()), jpeg.size()); imageResource->finish(); EXPECT_FALSE(imageResource->errorOccurred()); ASSERT_TRUE(imageResource->hasImage()); EXPECT_FALSE(imageResource->getImage()->isNull()); EXPECT_EQ(1, imageResource->getImage()->width()); EXPECT_EQ(1, imageResource->getImage()->height()); EXPECT_TRUE(client1->notifyFinishedCalled()); client1->removeAsClient(); EXPECT_FALSE(imageResource->hasClientsOrObservers()); imageResource->prune(); EXPECT_FALSE(imageResource->hasImage()); // Re-adds a ResourceClient but not ImageResourceObserver. Persistent<MockResourceClient> client2 = new MockResourceClient(imageResource); ASSERT_TRUE(imageResource->hasImage()); EXPECT_FALSE(imageResource->getImage()->isNull()); EXPECT_EQ(1, imageResource->getImage()->width()); EXPECT_EQ(1, imageResource->getImage()->height()); EXPECT_TRUE(client2->notifyFinishedCalled()); }
TEST(ImageResourceTest, ReloadIfLoFiAfterFinished) { KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html"); ScopedRegisteredURL scopedRegisteredURL(testURL); ResourceRequest request = ResourceRequest(testURL); request.setLoFiState(WebURLRequest::LoFiOn); ImageResource* cachedImage = ImageResource::create(request); cachedImage->setStatus(Resource::Pending); Persistent<MockImageResourceClient> client = new MockImageResourceClient(cachedImage); ResourceFetcher* fetcher = ResourceFetcher::create(ImageResourceTestMockFetchContext::create()); // Send the image response. Vector<unsigned char> jpeg = jpegImage(); ResourceResponse resourceResponse(KURL(), "image/jpeg", jpeg.size(), nullAtom, String()); resourceResponse.addHTTPHeaderField("chrome-proxy", "q=low"); cachedImage->responseReceived(resourceResponse, nullptr); cachedImage->appendData(reinterpret_cast<const char*>(jpeg.data()), jpeg.size()); cachedImage->finish(); EXPECT_FALSE(cachedImage->errorOccurred()); ASSERT_TRUE(cachedImage->hasImage()); EXPECT_FALSE(cachedImage->getImage()->isNull()); EXPECT_EQ(2, client->imageChangedCount()); EXPECT_EQ(jpeg.size(), client->encodedSizeOnLastImageChanged()); // The client should have been notified that the image load completed. EXPECT_TRUE(client->notifyFinishedCalled()); EXPECT_EQ(jpeg.size(), client->encodedSizeOnNotifyFinished()); EXPECT_EQ(jpeg.size(), client->encodedSizeOnImageNotifyFinished()); EXPECT_TRUE(cachedImage->getImage()->isBitmapImage()); EXPECT_EQ(1, cachedImage->getImage()->width()); EXPECT_EQ(1, cachedImage->getImage()->height()); // Call reloadIfLoFi() after the image has finished loading. cachedImage->reloadIfLoFi(fetcher); EXPECT_FALSE(cachedImage->errorOccurred()); EXPECT_FALSE(cachedImage->resourceBuffer()); EXPECT_FALSE(cachedImage->hasImage()); EXPECT_EQ(3, client->imageChangedCount()); Vector<unsigned char> jpeg2 = jpegImage2(); cachedImage->loader()->didReceiveResponse( nullptr, WrappedResourceResponse(resourceResponse), nullptr); cachedImage->loader()->didReceiveData( nullptr, reinterpret_cast<const char*>(jpeg2.data()), jpeg2.size(), jpeg2.size(), jpeg2.size()); cachedImage->loader()->didFinishLoading(nullptr, 0.0, jpeg2.size()); EXPECT_FALSE(cachedImage->errorOccurred()); ASSERT_TRUE(cachedImage->hasImage()); EXPECT_FALSE(cachedImage->getImage()->isNull()); EXPECT_EQ(jpeg2.size(), client->encodedSizeOnLastImageChanged()); EXPECT_TRUE(client->notifyFinishedCalled()); // The client should not have been notified of completion again. EXPECT_EQ(jpeg.size(), client->encodedSizeOnNotifyFinished()); EXPECT_EQ(jpeg.size(), client->encodedSizeOnImageNotifyFinished()); EXPECT_TRUE(cachedImage->getImage()->isBitmapImage()); EXPECT_EQ(50, cachedImage->getImage()->width()); EXPECT_EQ(50, cachedImage->getImage()->height()); }