 Chromium Code Reviews
 Chromium Code Reviews Issue 1154413002:
  Make multipart image documents work again.  (Closed) 
  Base URL: svn://svn.chromium.org/blink/trunk
    
  
    Issue 1154413002:
  Make multipart image documents work again.  (Closed) 
  Base URL: svn://svn.chromium.org/blink/trunk| OLD | NEW | 
|---|---|
| 1 /* | 1 /* | 
| 2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. | 
| 3 * | 3 * | 
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without | 
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions | 
| 6 * are met: | 6 * are met: | 
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright | 
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. | 
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright | 
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the | 
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 129 | 129 | 
| 130 LocalFrame* frame = document()->frame(); | 130 LocalFrame* frame = document()->frame(); | 
| 131 Settings* settings = frame->settings(); | 131 Settings* settings = frame->settings(); | 
| 132 if (!frame->loader().client()->allowImage(!settings || settings->imagesEnabl ed(), document()->url())) | 132 if (!frame->loader().client()->allowImage(!settings || settings->imagesEnabl ed(), document()->url())) | 
| 133 return; | 133 return; | 
| 134 | 134 | 
| 135 if (document()->cachedImage()) { | 135 if (document()->cachedImage()) { | 
| 136 RELEASE_ASSERT(length <= std::numeric_limits<unsigned>::max()); | 136 RELEASE_ASSERT(length <= std::numeric_limits<unsigned>::max()); | 
| 137 document()->cachedImage()->appendData(data, length); | 137 document()->cachedImage()->appendData(data, length); | 
| 138 } | 138 } | 
| 139 | |
| 140 if (!document()) | |
| 
Nate Chapin
2015/05/27 20:45:24
Here and in finish(), if createDocumentStructure()
 | |
| 141 return; | |
| 142 | |
| 139 // Make sure the image layoutObject gets created because we need the layoutO bject | 143 // Make sure the image layoutObject gets created because we need the layoutO bject | 
| 140 // to read the aspect ratio. See crbug.com/320244 | 144 // to read the aspect ratio. See crbug.com/320244 | 
| 141 document()->updateLayoutTreeIfNeeded(); | 145 document()->updateLayoutTreeIfNeeded(); | 
| 142 document()->imageUpdated(); | 146 document()->imageUpdated(); | 
| 143 } | 147 } | 
| 144 | 148 | 
| 145 void ImageDocumentParser::finish() | 149 void ImageDocumentParser::finish() | 
| 146 { | 150 { | 
| 147 if (!isStopped() && document()->imageElement() && document()->cachedImage()) { | 151 if (!isStopped() && document()->imageElement() && document()->cachedImage()) { | 
| 148 ImageResource* cachedImage = document()->cachedImage(); | 152 ImageResource* cachedImage = document()->cachedImage(); | 
| 149 cachedImage->finish(); | 153 cachedImage->finish(); | 
| 150 cachedImage->setResponse(document()->frame()->loader().documentLoader()- >response()); | 154 cachedImage->setResponse(document()->frame()->loader().documentLoader()- >response()); | 
| 151 | 155 | 
| 152 // Report the natural image size in the page title, regardless of zoom l evel. | 156 // Report the natural image size in the page title, regardless of zoom l evel. | 
| 153 // At a zoom level of 1 the image is guaranteed to have an integer size. | 157 // At a zoom level of 1 the image is guaranteed to have an integer size. | 
| 154 IntSize size = flooredIntSize(cachedImage->imageSizeForLayoutObject(docu ment()->imageElement()->layoutObject(), 1.0f)); | 158 IntSize size = flooredIntSize(cachedImage->imageSizeForLayoutObject(docu ment()->imageElement()->layoutObject(), 1.0f)); | 
| 155 if (size.width()) { | 159 if (size.width()) { | 
| 156 // Compute the title, we use the decoded filename of the resource, f alling | 160 // Compute the title, we use the decoded filename of the resource, f alling | 
| 157 // back on the (decoded) hostname if there is no path. | 161 // back on the (decoded) hostname if there is no path. | 
| 158 String fileName = decodeURLEscapeSequences(document()->url().lastPat hComponent()); | 162 String fileName = decodeURLEscapeSequences(document()->url().lastPat hComponent()); | 
| 159 if (fileName.isEmpty()) | 163 if (fileName.isEmpty()) | 
| 160 fileName = document()->url().host(); | 164 fileName = document()->url().host(); | 
| 161 document()->setTitle(imageTitle(fileName, size)); | 165 document()->setTitle(imageTitle(fileName, size)); | 
| 162 } | 166 } | 
| 163 | 167 | 
| 164 document()->imageUpdated(); | 168 document()->imageUpdated(); | 
| 165 } | 169 } | 
| 166 | 170 | 
| 167 document()->finishedParsing(); | 171 if (document()) | 
| 172 document()->finishedParsing(); | |
| 168 } | 173 } | 
| 169 | 174 | 
| 170 // -------- | 175 // -------- | 
| 171 | 176 | 
| 172 ImageDocument::ImageDocument(const DocumentInit& initializer) | 177 ImageDocument::ImageDocument(const DocumentInit& initializer) | 
| 173 : HTMLDocument(initializer, ImageDocumentClass) | 178 : HTMLDocument(initializer, ImageDocumentClass) | 
| 174 , m_imageElement(nullptr) | 179 , m_imageElement(nullptr) | 
| 175 , m_imageSizeIsKnown(false) | 180 , m_imageSizeIsKnown(false) | 
| 176 , m_didShrinkImage(false) | 181 , m_didShrinkImage(false) | 
| 177 , m_shouldShrinkImage(shouldShrinkToFit()) | 182 , m_shouldShrinkImage(shouldShrinkToFit()) | 
| 178 , m_shrinkToFitMode(frame()->settings()->viewportEnabled() ? Viewport : Desk top) | 183 , m_shrinkToFitMode(frame()->settings()->viewportEnabled() ? Viewport : Desk top) | 
| 179 { | 184 { | 
| 180 setCompatibilityMode(QuirksMode); | 185 setCompatibilityMode(QuirksMode); | 
| 181 lockCompatibilityMode(); | 186 lockCompatibilityMode(); | 
| 182 } | 187 } | 
| 183 | 188 | 
| 184 PassRefPtrWillBeRawPtr<DocumentParser> ImageDocument::createParser() | 189 PassRefPtrWillBeRawPtr<DocumentParser> ImageDocument::createParser() | 
| 185 { | 190 { | 
| 186 return ImageDocumentParser::create(this); | 191 return ImageDocumentParser::create(this); | 
| 187 } | 192 } | 
| 188 | 193 | 
| 189 void ImageDocument::createDocumentStructure() | 194 void ImageDocument::createDocumentStructure(bool loadingMultipartContent) | 
| 190 { | 195 { | 
| 191 RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*t his); | 196 RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*t his); | 
| 192 appendChild(rootElement); | 197 appendChild(rootElement); | 
| 193 rootElement->insertedByParser(); | 198 rootElement->insertedByParser(); | 
| 194 | 199 | 
| 195 if (frame()) | 200 if (frame()) | 
| 196 frame()->loader().dispatchDocumentElementAvailable(); | 201 frame()->loader().dispatchDocumentElementAvailable(); | 
| 202 // Normally, ImageDocument creates an HTMLImageElement that doesn't actually load | |
| 203 // anything, and the ImageDocument routes the main resource data into the HT MLImageElement's | |
| 204 // ImageResource. However, the main resource pipeline doesn't know how to ha ndle multipart content. | |
| 205 // For multipart content, we instead stop streaming data through the main re source and re-request | |
| 206 // the data directly. | |
| 207 if (loadingMultipartContent) | |
| 208 loader()->stopLoading(); | |
| 197 | 209 | 
| 198 RefPtrWillBeRawPtr<HTMLHeadElement> head = HTMLHeadElement::create(*this); | 210 RefPtrWillBeRawPtr<HTMLHeadElement> head = HTMLHeadElement::create(*this); | 
| 199 RefPtrWillBeRawPtr<HTMLMetaElement> meta = HTMLMetaElement::create(*this); | 211 RefPtrWillBeRawPtr<HTMLMetaElement> meta = HTMLMetaElement::create(*this); | 
| 200 meta->setAttribute(nameAttr, "viewport"); | 212 meta->setAttribute(nameAttr, "viewport"); | 
| 201 meta->setAttribute(contentAttr, "width=device-width, minimum-scale=0.1"); | 213 meta->setAttribute(contentAttr, "width=device-width, minimum-scale=0.1"); | 
| 202 head->appendChild(meta); | 214 head->appendChild(meta); | 
| 203 | 215 | 
| 204 RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*this); | 216 RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*this); | 
| 205 body->setAttribute(styleAttr, "margin: 0px;"); | 217 body->setAttribute(styleAttr, "margin: 0px;"); | 
| 206 | 218 | 
| 207 m_imageElement = HTMLImageElement::create(*this); | 219 m_imageElement = HTMLImageElement::create(*this); | 
| 208 m_imageElement->setAttribute(styleAttr, "-webkit-user-select: none"); | 220 m_imageElement->setAttribute(styleAttr, "-webkit-user-select: none"); | 
| 209 m_imageElement->setLoadingImageDocument(); | 221 // If the image is multipart, we neglect to mention to the HTMLImageElement that it's in an | 
| 222 // ImageDocument, so that it requests the image normally. | |
| 223 if (!loadingMultipartContent) | |
| 224 m_imageElement->setLoadingImageDocument(); | |
| 210 m_imageElement->setSrc(url().string()); | 225 m_imageElement->setSrc(url().string()); | 
| 211 body->appendChild(m_imageElement.get()); | 226 body->appendChild(m_imageElement.get()); | 
| 212 | 227 | 
| 213 if (shouldShrinkToFit()) { | 228 if (shouldShrinkToFit()) { | 
| 214 // Add event listeners | 229 // Add event listeners | 
| 215 RefPtr<EventListener> listener = ImageEventListener::create(this); | 230 RefPtr<EventListener> listener = ImageEventListener::create(this); | 
| 216 if (LocalDOMWindow* domWindow = this->domWindow()) | 231 if (LocalDOMWindow* domWindow = this->domWindow()) | 
| 217 domWindow->addEventListener("resize", listener, false); | 232 domWindow->addEventListener("resize", listener, false); | 
| 218 if (m_shrinkToFitMode == Desktop) | 233 if (m_shrinkToFitMode == Desktop) | 
| 219 m_imageElement->addEventListener("click", listener.release(), false) ; | 234 m_imageElement->addEventListener("click", listener.release(), false) ; | 
| 220 } | 235 } | 
| 221 | 236 | 
| 222 rootElement->appendChild(head); | 237 rootElement->appendChild(head); | 
| 223 rootElement->appendChild(body); | 238 rootElement->appendChild(body); | 
| 239 if (loadingMultipartContent) | |
| 240 finishedParsing(); | |
| 
Nate Chapin
2015/05/27 20:45:24
The stopLoading() call above leaves us in a half-c
 | |
| 224 } | 241 } | 
| 225 | 242 | 
| 226 float ImageDocument::scale() const | 243 float ImageDocument::scale() const | 
| 227 { | 244 { | 
| 228 if (!m_imageElement || m_imageElement->document() != this) | 245 if (!m_imageElement || m_imageElement->document() != this) | 
| 229 return 1.0f; | 246 return 1.0f; | 
| 230 | 247 | 
| 231 FrameView* view = frame()->view(); | 248 FrameView* view = frame()->view(); | 
| 232 if (!view) | 249 if (!view) | 
| 233 return 1; | 250 return 1; | 
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 380 // If the image isn't resized but needs to be, then resize it. | 397 // If the image isn't resized but needs to be, then resize it. | 
| 381 if (!fitsInWindow) { | 398 if (!fitsInWindow) { | 
| 382 resizeImageToFit(type); | 399 resizeImageToFit(type); | 
| 383 m_didShrinkImage = true; | 400 m_didShrinkImage = true; | 
| 384 } | 401 } | 
| 385 } | 402 } | 
| 386 } | 403 } | 
| 387 | 404 | 
| 388 ImageResource* ImageDocument::cachedImage() | 405 ImageResource* ImageDocument::cachedImage() | 
| 389 { | 406 { | 
| 407 bool loadingMultipartContent = loader() && loader()->loadingMultipartContent (); | |
| 390 if (!m_imageElement) | 408 if (!m_imageElement) | 
| 391 createDocumentStructure(); | 409 createDocumentStructure(loadingMultipartContent); | 
| 392 | 410 | 
| 393 return m_imageElement->cachedImage(); | 411 return loadingMultipartContent ? nullptr : m_imageElement->cachedImage(); | 
| 
Nate Chapin
2015/05/27 20:45:25
Since multipart images will load their own content
 | |
| 394 } | 412 } | 
| 395 | 413 | 
| 396 bool ImageDocument::shouldShrinkToFit() const | 414 bool ImageDocument::shouldShrinkToFit() const | 
| 397 { | 415 { | 
| 398 return frame()->isMainFrame(); | 416 return frame()->isMainFrame(); | 
| 399 } | 417 } | 
| 400 | 418 | 
| 401 #if !ENABLE(OILPAN) | 419 #if !ENABLE(OILPAN) | 
| 402 void ImageDocument::dispose() | 420 void ImageDocument::dispose() | 
| 403 { | 421 { | 
| (...skipping 21 matching lines...) Expand all Loading... | |
| 425 } | 443 } | 
| 426 | 444 | 
| 427 bool ImageEventListener::operator==(const EventListener& listener) | 445 bool ImageEventListener::operator==(const EventListener& listener) | 
| 428 { | 446 { | 
| 429 if (const ImageEventListener* imageEventListener = ImageEventListener::cast( &listener)) | 447 if (const ImageEventListener* imageEventListener = ImageEventListener::cast( &listener)) | 
| 430 return m_doc == imageEventListener->m_doc; | 448 return m_doc == imageEventListener->m_doc; | 
| 431 return false; | 449 return false; | 
| 432 } | 450 } | 
| 433 | 451 | 
| 434 } | 452 } | 
| OLD | NEW |