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

Side by Side Diff: third_party/WebKit/Source/core/html/ImageDocument.cpp

Issue 2445413003: [Blink] Display images on a dark background (Closed)
Patch Set: Rebase Created 4 years, 1 month 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
« no previous file with comments | « third_party/WebKit/Source/core/html/ImageDocument.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 #include "core/layout/LayoutObject.h" 47 #include "core/layout/LayoutObject.h"
48 #include "core/loader/DocumentLoader.h" 48 #include "core/loader/DocumentLoader.h"
49 #include "core/loader/FrameLoader.h" 49 #include "core/loader/FrameLoader.h"
50 #include "core/loader/FrameLoaderClient.h" 50 #include "core/loader/FrameLoaderClient.h"
51 #include "platform/HostWindow.h" 51 #include "platform/HostWindow.h"
52 #include "wtf/text/StringBuilder.h" 52 #include "wtf/text/StringBuilder.h"
53 #include <limits> 53 #include <limits>
54 54
55 using namespace std; 55 using namespace std;
56 56
57 namespace {
58
59 // The base square size is set to 10 because it rounds nicely for both the
60 // minimum scale (0.1) and maximum scale (5.0).
61 const int kBaseCheckerSize = 10;
62
63 } // namespace
64
57 namespace blink { 65 namespace blink {
58 66
59 using namespace HTMLNames; 67 using namespace HTMLNames;
60 68
61 class ImageEventListener : public EventListener { 69 class ImageEventListener : public EventListener {
62 public: 70 public:
63 static ImageEventListener* create(ImageDocument* document) { 71 static ImageEventListener* create(ImageDocument* document) {
64 return new ImageEventListener(document); 72 return new ImageEventListener(document);
65 } 73 }
66 static const ImageEventListener* cast(const EventListener* listener) { 74 static const ImageEventListener* cast(const EventListener* listener) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 result.append(" ("); 124 result.append(" (");
117 // FIXME: Localize numbers. Safari/OSX shows localized numbers with group 125 // FIXME: Localize numbers. Safari/OSX shows localized numbers with group
118 // separaters. For example, "1,920x1,080". 126 // separaters. For example, "1,920x1,080".
119 result.appendNumber(size.width()); 127 result.appendNumber(size.width());
120 result.append(static_cast<UChar>(0xD7)); // U+00D7 (multiplication sign) 128 result.append(static_cast<UChar>(0xD7)); // U+00D7 (multiplication sign)
121 result.appendNumber(size.height()); 129 result.appendNumber(size.height());
122 result.append(')'); 130 result.append(')');
123 return result.toString(); 131 return result.toString();
124 } 132 }
125 133
134 static LayoutSize cachedImageSize(HTMLImageElement* element) {
135 DCHECK(element->cachedImage());
136 return element->cachedImage()->imageSize(
137 LayoutObject::shouldRespectImageOrientation(element->layoutObject()),
138 1.0f);
139 }
140
126 void ImageDocumentParser::appendBytes(const char* data, size_t length) { 141 void ImageDocumentParser::appendBytes(const char* data, size_t length) {
127 if (!length) 142 if (!length)
128 return; 143 return;
129 144
130 LocalFrame* frame = document()->frame(); 145 LocalFrame* frame = document()->frame();
131 Settings* settings = frame->settings(); 146 Settings* settings = frame->settings();
132 if (!frame->loader().client()->allowImage( 147 if (!frame->loader().client()->allowImage(
133 !settings || settings->imagesEnabled(), document()->url())) 148 !settings || settings->imagesEnabled(), document()->url()))
134 return; 149 return;
135 150
(...skipping 12 matching lines...) Expand all
148 void ImageDocumentParser::finish() { 163 void ImageDocumentParser::finish() {
149 if (!isStopped() && document()->imageElement() && document()->cachedImage()) { 164 if (!isStopped() && document()->imageElement() && document()->cachedImage()) {
150 ImageResource* cachedImage = document()->cachedImage(); 165 ImageResource* cachedImage = document()->cachedImage();
151 DocumentLoader* loader = document()->loader(); 166 DocumentLoader* loader = document()->loader();
152 cachedImage->setResponse(loader->response()); 167 cachedImage->setResponse(loader->response());
153 cachedImage->finish(loader->timing().responseEnd()); 168 cachedImage->finish(loader->timing().responseEnd());
154 169
155 // Report the natural image size in the page title, regardless of zoom 170 // Report the natural image size in the page title, regardless of zoom
156 // level. At a zoom level of 1 the image is guaranteed to have an integer 171 // level. At a zoom level of 1 the image is guaranteed to have an integer
157 // size. 172 // size.
158 IntSize size = flooredIntSize( 173 IntSize size = flooredIntSize(cachedImageSize(document()->imageElement()));
159 cachedImage->imageSize(LayoutObject::shouldRespectImageOrientation(
160 document()->imageElement()->layoutObject()),
161 1.0f));
162 if (size.width()) { 174 if (size.width()) {
163 // Compute the title, we use the decoded filename of the resource, falling 175 // Compute the title, we use the decoded filename of the resource, falling
164 // back on the (decoded) hostname if there is no path. 176 // back on the (decoded) hostname if there is no path.
165 String fileName = 177 String fileName =
166 decodeURLEscapeSequences(document()->url().lastPathComponent()); 178 decodeURLEscapeSequences(document()->url().lastPathComponent());
167 if (fileName.isEmpty()) 179 if (fileName.isEmpty())
168 fileName = document()->url().host(); 180 fileName = document()->url().host();
169 document()->setTitle(imageTitle(fileName, size)); 181 document()->setTitle(imageTitle(fileName, size));
170 if (isDetached()) 182 if (isDetached())
171 return; 183 return;
172 } 184 }
173 185
174 document()->imageUpdated(); 186 document()->imageUpdated();
187 document()->imageLoaded();
175 } 188 }
176 189
177 if (!isDetached()) 190 if (!isDetached())
178 document()->finishedParsing(); 191 document()->finishedParsing();
179 } 192 }
180 193
181 // -------- 194 // --------
182 195
183 ImageDocument::ImageDocument(const DocumentInit& initializer) 196 ImageDocument::ImageDocument(const DocumentInit& initializer)
184 : HTMLDocument(initializer, ImageDocumentClass), 197 : HTMLDocument(initializer, ImageDocumentClass),
185 m_divElement(nullptr), 198 m_divElement(nullptr),
186 m_imageElement(nullptr), 199 m_imageElement(nullptr),
187 m_imageSizeIsKnown(false), 200 m_imageSizeIsKnown(false),
188 m_didShrinkImage(false), 201 m_didShrinkImage(false),
189 m_shouldShrinkImage(shouldShrinkToFit()), 202 m_shouldShrinkImage(shouldShrinkToFit()),
203 m_imageIsLoaded(false),
204 m_checkerSize(0),
190 m_shrinkToFitMode(frame()->settings()->viewportEnabled() ? Viewport 205 m_shrinkToFitMode(frame()->settings()->viewportEnabled() ? Viewport
191 : Desktop) { 206 : Desktop) {
192 setCompatibilityMode(QuirksMode); 207 setCompatibilityMode(QuirksMode);
193 lockCompatibilityMode(); 208 lockCompatibilityMode();
194 UseCounter::count(*this, UseCounter::ImageDocument); 209 UseCounter::count(*this, UseCounter::ImageDocument);
195 if (!isInMainFrame()) 210 if (!isInMainFrame())
196 UseCounter::count(*this, UseCounter::ImageDocumentInFrame); 211 UseCounter::count(*this, UseCounter::ImageDocumentInFrame);
197 } 212 }
198 213
199 DocumentParser* ImageDocument::createParser() { 214 DocumentParser* ImageDocument::createParser() {
(...skipping 11 matching lines...) Expand all
211 HTMLHeadElement* head = HTMLHeadElement::create(*this); 226 HTMLHeadElement* head = HTMLHeadElement::create(*this);
212 HTMLMetaElement* meta = HTMLMetaElement::create(*this); 227 HTMLMetaElement* meta = HTMLMetaElement::create(*this);
213 meta->setAttribute(nameAttr, "viewport"); 228 meta->setAttribute(nameAttr, "viewport");
214 meta->setAttribute(contentAttr, "width=device-width, minimum-scale=0.1"); 229 meta->setAttribute(contentAttr, "width=device-width, minimum-scale=0.1");
215 head->appendChild(meta); 230 head->appendChild(meta);
216 231
217 HTMLBodyElement* body = HTMLBodyElement::create(*this); 232 HTMLBodyElement* body = HTMLBodyElement::create(*this);
218 233
219 if (shouldShrinkToFit()) { 234 if (shouldShrinkToFit()) {
220 // Display the image prominently centered in the frame. 235 // Display the image prominently centered in the frame.
221 body->setAttribute(styleAttr, "margin: 0px;"); 236 body->setAttribute(styleAttr, "margin: 0px; background: #0e0e0e;");
222 237
223 // See w3c example on how to centering an element: 238 // See w3c example on how to center an element:
224 // https://www.w3.org/Style/Examples/007/center.en.html 239 // https://www.w3.org/Style/Examples/007/center.en.html
225 m_divElement = HTMLDivElement::create(*this); 240 m_divElement = HTMLDivElement::create(*this);
226 m_divElement->setAttribute(styleAttr, 241 m_divElement->setAttribute(styleAttr,
227 "display: flex;" 242 "display: flex;"
228 "flex-direction: column;" 243 "flex-direction: column;"
229 "justify-content: center;" 244 "justify-content: center;"
230 "align-items: center;" 245 "align-items: center;"
231 "min-height: min-content;" 246 "min-height: min-content;"
232 "min-width: min-content;" 247 "min-width: min-content;"
233 "height: 100%;" 248 "height: 100%;"
234 "width: 100%;"); 249 "width: 100%;");
235 HTMLContentElement* content = HTMLContentElement::create(*this); 250 HTMLContentElement* content = HTMLContentElement::create(*this);
236 m_divElement->appendChild(content); 251 m_divElement->appendChild(content);
237 252
238 ShadowRoot& shadowRoot = body->ensureUserAgentShadowRoot(); 253 ShadowRoot& shadowRoot = body->ensureUserAgentShadowRoot();
239 shadowRoot.appendChild(m_divElement); 254 shadowRoot.appendChild(m_divElement);
240 } else { 255 } else {
241 body->setAttribute(styleAttr, "margin: 0px;"); 256 body->setAttribute(styleAttr, "margin: 0px;");
242 } 257 }
243 258
244 willInsertBody(); 259 willInsertBody();
245 260
246 StringBuilder imageStyle;
247 imageStyle.append("-webkit-user-select: none;");
248 if (shouldShrinkToFit() && m_shrinkToFitMode == Viewport)
249 imageStyle.append("max-width: 100%");
250 m_imageElement = HTMLImageElement::create(*this); 261 m_imageElement = HTMLImageElement::create(*this);
251 m_imageElement->setAttribute(styleAttr, imageStyle.toAtomicString()); 262 updateImageStyle();
252 m_imageElement->setLoadingImageDocument(); 263 m_imageElement->setLoadingImageDocument();
253 m_imageElement->setSrc(url().getString()); 264 m_imageElement->setSrc(url().getString());
254 body->appendChild(m_imageElement.get()); 265 body->appendChild(m_imageElement.get());
255 if (loader() && m_imageElement->cachedImage()) 266 if (loader() && m_imageElement->cachedImage())
256 m_imageElement->cachedImage()->responseReceived(loader()->response(), 267 m_imageElement->cachedImage()->responseReceived(loader()->response(),
257 nullptr); 268 nullptr);
258 269
259 if (shouldShrinkToFit()) { 270 if (shouldShrinkToFit()) {
260 // Add event listeners 271 // Add event listeners
261 EventListener* listener = ImageEventListener::create(this); 272 EventListener* listener = ImageEventListener::create(this);
262 if (LocalDOMWindow* domWindow = this->domWindow()) 273 if (LocalDOMWindow* domWindow = this->domWindow())
263 domWindow->addEventListener("resize", listener, false); 274 domWindow->addEventListener(EventTypeNames::resize, listener, false);
264 if (m_shrinkToFitMode == Desktop) 275
265 m_imageElement->addEventListener("click", listener, false); 276 if (m_shrinkToFitMode == Desktop) {
277 m_imageElement->addEventListener(EventTypeNames::click, listener, false);
278 } else if (m_shrinkToFitMode == Viewport) {
279 m_imageElement->addEventListener(EventTypeNames::touchend, listener,
280 false);
281 m_imageElement->addEventListener(EventTypeNames::touchcancel, listener,
282 false);
283 }
266 } 284 }
267 285
268 rootElement->appendChild(head); 286 rootElement->appendChild(head);
269 rootElement->appendChild(body); 287 rootElement->appendChild(body);
270 } 288 }
271 289
272 float ImageDocument::scale() const { 290 float ImageDocument::scale() const {
273 DCHECK_EQ(m_shrinkToFitMode, Desktop); 291 DCHECK_EQ(m_shrinkToFitMode, Desktop);
274 if (!m_imageElement || m_imageElement->document() != this) 292 if (!m_imageElement || m_imageElement->document() != this)
275 return 1.0f; 293 return 1.0f;
(...skipping 18 matching lines...) Expand all
294 view->height() * manualZoom / imageSize.height().toFloat(); 312 view->height() * manualZoom / imageSize.height().toFloat();
295 313
296 return min(widthScale, heightScale); 314 return min(widthScale, heightScale);
297 } 315 }
298 316
299 void ImageDocument::resizeImageToFit() { 317 void ImageDocument::resizeImageToFit() {
300 DCHECK_EQ(m_shrinkToFitMode, Desktop); 318 DCHECK_EQ(m_shrinkToFitMode, Desktop);
301 if (!m_imageElement || m_imageElement->document() != this) 319 if (!m_imageElement || m_imageElement->document() != this)
302 return; 320 return;
303 321
304 DCHECK(m_imageElement->cachedImage()); 322 LayoutSize imageSize = cachedImageSize(m_imageElement);
305 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize(
306 LayoutObject::shouldRespectImageOrientation(
307 m_imageElement->layoutObject()),
308 1.f);
309 323
310 const float scale = this->scale(); 324 const float scale = this->scale();
311 m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale)); 325 m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale));
312 m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale)); 326 m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale));
313 327
314 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomIn); 328 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomIn);
315 } 329 }
316 330
317 void ImageDocument::imageClicked(int x, int y) { 331 void ImageDocument::imageClicked(int x, int y) {
318 DCHECK_EQ(m_shrinkToFitMode, Desktop); 332 DCHECK_EQ(m_shrinkToFitMode, Desktop);
(...skipping 20 matching lines...) Expand all
339 float scrollX = 353 float scrollX =
340 imageX / scale - static_cast<float>(frame()->view()->width()) / 2; 354 imageX / scale - static_cast<float>(frame()->view()->width()) / 2;
341 float scrollY = 355 float scrollY =
342 imageY / scale - static_cast<float>(frame()->view()->height()) / 2; 356 imageY / scale - static_cast<float>(frame()->view()->height()) / 2;
343 357
344 frame()->view()->layoutViewportScrollableArea()->setScrollOffset( 358 frame()->view()->layoutViewportScrollableArea()->setScrollOffset(
345 ScrollOffset(scrollX, scrollY), ProgrammaticScroll); 359 ScrollOffset(scrollX, scrollY), ProgrammaticScroll);
346 } 360 }
347 } 361 }
348 362
363 void ImageDocument::imageLoaded() {
364 m_imageIsLoaded = true;
365
366 if (shouldShrinkToFit()) {
367 // The checkerboard background needs to be inserted.
368 updateImageStyle();
369 }
370 }
371
372 void ImageDocument::updateImageStyle() {
373 StringBuilder imageStyle;
374 imageStyle.append("-webkit-user-select: none;");
375
376 if (shouldShrinkToFit()) {
377 if (m_shrinkToFitMode == Viewport)
378 imageStyle.append("max-width: 100%;");
379
380 // Once the image has fully loaded, it is displayed atop a checkerboard to
381 // show transparency more faithfully. The pattern is generated via CSS.
382 if (m_imageIsLoaded) {
383 int newCheckerSize = kBaseCheckerSize;
384
385 if (m_shrinkToFitMode == Viewport) {
386 double scale;
387
388 if (hasFinishedParsing()) {
389 // To ensure the checker pattern is visible for large images, the
390 // checker size is dynamically adjusted to account for how much the
391 // page is currently being scaled.
392 scale = frame()->host()->visualViewport().scale();
393 } else {
394 // The checker pattern is initialized based on how large the image is
395 // relative to the viewport.
396 int viewportWidth = frame()->host()->visualViewport().size().width();
397 scale = viewportWidth / static_cast<double>(calculateDivWidth());
398 }
399
400 newCheckerSize = round(std::max(1.0, newCheckerSize / scale));
401 }
402
403 // The only thing that can differ between updates is the checker size.
404 if (newCheckerSize == m_checkerSize)
405 return;
406 m_checkerSize = newCheckerSize;
407
408 imageStyle.append("background-position: 0px 0px, ");
409 imageStyle.append(AtomicString::number(m_checkerSize));
410 imageStyle.append("px ");
411 imageStyle.append(AtomicString::number(m_checkerSize));
412 imageStyle.append("px;");
413
414 int tileSize = m_checkerSize * 2;
415 imageStyle.append("background-size: ");
416 imageStyle.append(AtomicString::number(tileSize));
417 imageStyle.append("px ");
418 imageStyle.append(AtomicString::number(tileSize));
419 imageStyle.append("px;");
420
421 imageStyle.append(
422 "background-color: white;"
423 "background-image:"
424 "linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, "
425 "#eee 75%, #eee 100%),"
426 "linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, "
427 "#eee 75%, #eee 100%);");
428 }
429 }
430
431 m_imageElement->setAttribute(styleAttr, imageStyle.toAtomicString());
432 }
433
349 void ImageDocument::imageUpdated() { 434 void ImageDocument::imageUpdated() {
350 DCHECK(m_imageElement); 435 DCHECK(m_imageElement);
351 436
352 if (m_imageSizeIsKnown) 437 if (m_imageSizeIsKnown)
353 return; 438 return;
354 439
355 updateStyleAndLayoutTree(); 440 updateStyleAndLayoutTree();
356 if (!m_imageElement->cachedImage() || 441 if (!m_imageElement->cachedImage() ||
357 m_imageElement->cachedImage() 442 m_imageElement->cachedImage()
358 ->imageSize(LayoutObject::shouldRespectImageOrientation( 443 ->imageSize(LayoutObject::shouldRespectImageOrientation(
(...skipping 11 matching lines...) Expand all
370 } 455 }
371 456
372 void ImageDocument::restoreImageSize() { 457 void ImageDocument::restoreImageSize() {
373 DCHECK_EQ(m_shrinkToFitMode, Desktop); 458 DCHECK_EQ(m_shrinkToFitMode, Desktop);
374 459
375 if (!m_imageElement || !m_imageSizeIsKnown || 460 if (!m_imageElement || !m_imageSizeIsKnown ||
376 m_imageElement->document() != this) 461 m_imageElement->document() != this)
377 return; 462 return;
378 463
379 DCHECK(m_imageElement->cachedImage()); 464 DCHECK(m_imageElement->cachedImage());
380 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize( 465 LayoutSize imageSize = cachedImageSize(m_imageElement);
381 LayoutObject::shouldRespectImageOrientation(
382 m_imageElement->layoutObject()),
383 1.0f);
384 m_imageElement->setWidth(imageSize.width().toInt()); 466 m_imageElement->setWidth(imageSize.width().toInt());
385 m_imageElement->setHeight(imageSize.height().toInt()); 467 m_imageElement->setHeight(imageSize.height().toInt());
386 468
387 if (imageFitsInWindow()) 469 if (imageFitsInWindow())
388 m_imageElement->removeInlineStyleProperty(CSSPropertyCursor); 470 m_imageElement->removeInlineStyleProperty(CSSPropertyCursor);
389 else 471 else
390 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOut); 472 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOut);
391 473
392 m_didShrinkImage = false; 474 m_didShrinkImage = false;
393 } 475 }
394 476
395 bool ImageDocument::imageFitsInWindow() const { 477 bool ImageDocument::imageFitsInWindow() const {
396 DCHECK_EQ(m_shrinkToFitMode, Desktop); 478 DCHECK_EQ(m_shrinkToFitMode, Desktop);
397 return this->scale() >= 1; 479 return this->scale() >= 1;
398 } 480 }
399 481
482 int ImageDocument::calculateDivWidth() {
483 // Zooming in and out of an image being displayed within a viewport is done
484 // by changing the page scale factor of the page instead of changing the
485 // size of the image. The size of the image is set so that:
486 // * Images wider than the viewport take the full width of the screen.
487 // * Images taller than the viewport are initially aligned with the top of
488 // of the frame.
489 // * Images smaller in either dimension are centered along that axis.
490 LayoutSize imageSize = cachedImageSize(m_imageElement);
491 int viewportWidth = frame()->host()->visualViewport().size().width();
492
493 // For huge images, minimum-scale=0.1 is still too big on small screens.
494 // Set the <div> width so that the image will shrink to fit the width of the
495 // screen when the scale is minimum.
496 int maxWidth = std::min(imageSize.width().toInt(), viewportWidth * 10);
497 return std::max(viewportWidth, maxWidth);
498 }
499
400 void ImageDocument::windowSizeChanged() { 500 void ImageDocument::windowSizeChanged() {
401 if (!m_imageElement || !m_imageSizeIsKnown || 501 if (!m_imageElement || !m_imageSizeIsKnown ||
402 m_imageElement->document() != this) 502 m_imageElement->document() != this)
403 return; 503 return;
404 504
405 if (m_shrinkToFitMode == Viewport) { 505 if (m_shrinkToFitMode == Viewport) {
406 // Zooming in and out of an image being displayed within a viewport is done 506 LayoutSize imageSize = cachedImageSize(m_imageElement);
407 // by changing the page scale factor of the page instead of changing the 507 int divWidth = calculateDivWidth();
408 // size of the image. The size of the image is set so that:
409 // * Images wider than the viewport take the full width of the screen.
410 // * Images taller than the viewport are initially aligned with the top of
411 // of the frame.
412 // * Images smaller in either dimension are centered along that axis.
413 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize(
414 LayoutObject::shouldRespectImageOrientation(
415 m_imageElement->layoutObject()),
416 1.f);
417 int viewportWidth = frame()->host()->visualViewport().size().width();
418 int viewportHeight = frame()->host()->visualViewport().size().height();
419 float viewportAspectRatio = (float)viewportWidth / viewportHeight;
420
421 // For huge images, minimum-scale=0.1 is still too big on small screens.
422 // Set the <div> width so that the image will shrink to fit the width of the
423 // screen when the scale is minimum.
424 int maxWidth = std::min(imageSize.width().toInt(), viewportWidth * 10);
425 int divWidth = std::max(viewportWidth, maxWidth);
426 m_divElement->setInlineStyleProperty(CSSPropertyWidth, divWidth, 508 m_divElement->setInlineStyleProperty(CSSPropertyWidth, divWidth,
427 CSSPrimitiveValue::UnitType::Pixels); 509 CSSPrimitiveValue::UnitType::Pixels);
428 510
429 // Explicitly set the height of the <div> containing the <img> so that it 511 // Explicitly set the height of the <div> containing the <img> so that it
430 // can display the full image without shrinking it, allowing a full-width 512 // can display the full image without shrinking it, allowing a full-width
431 // reading mode for normal-width-huge-height images. 513 // reading mode for normal-width-huge-height images.
514 float viewportAspectRatio =
515 frame()->host()->visualViewport().size().aspectRatio();
432 int divHeight = std::max(imageSize.height().toInt(), 516 int divHeight = std::max(imageSize.height().toInt(),
433 (int)(divWidth / viewportAspectRatio)); 517 static_cast<int>(divWidth / viewportAspectRatio));
434 m_divElement->setInlineStyleProperty(CSSPropertyHeight, divHeight, 518 m_divElement->setInlineStyleProperty(CSSPropertyHeight, divHeight,
435 CSSPrimitiveValue::UnitType::Pixels); 519 CSSPrimitiveValue::UnitType::Pixels);
436 return; 520 return;
437 } 521 }
438 522
439 bool fitsInWindow = imageFitsInWindow(); 523 bool fitsInWindow = imageFitsInWindow();
440 524
441 // If the image has been explicitly zoomed in, restore the cursor if the image 525 // If the image has been explicitly zoomed in, restore the cursor if the image
442 // fits and set it to a zoom out cursor if the image doesn't fit 526 // fits and set it to a zoom out cursor if the image doesn't fit
443 if (!m_shouldShrinkImage) { 527 if (!m_shouldShrinkImage) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 } 572 }
489 573
490 // -------- 574 // --------
491 575
492 void ImageEventListener::handleEvent(ExecutionContext*, Event* event) { 576 void ImageEventListener::handleEvent(ExecutionContext*, Event* event) {
493 if (event->type() == EventTypeNames::resize) { 577 if (event->type() == EventTypeNames::resize) {
494 m_doc->windowSizeChanged(); 578 m_doc->windowSizeChanged();
495 } else if (event->type() == EventTypeNames::click && event->isMouseEvent()) { 579 } else if (event->type() == EventTypeNames::click && event->isMouseEvent()) {
496 MouseEvent* mouseEvent = toMouseEvent(event); 580 MouseEvent* mouseEvent = toMouseEvent(event);
497 m_doc->imageClicked(mouseEvent->x(), mouseEvent->y()); 581 m_doc->imageClicked(mouseEvent->x(), mouseEvent->y());
582 } else if ((event->type() == EventTypeNames::touchend ||
583 event->type() == EventTypeNames::touchcancel) &&
584 event->isTouchEvent()) {
585 m_doc->updateImageStyle();
498 } 586 }
499 } 587 }
500 588
501 bool ImageEventListener::operator==(const EventListener& listener) const { 589 bool ImageEventListener::operator==(const EventListener& listener) const {
502 if (const ImageEventListener* imageEventListener = 590 if (const ImageEventListener* imageEventListener =
503 ImageEventListener::cast(&listener)) 591 ImageEventListener::cast(&listener))
504 return m_doc == imageEventListener->m_doc; 592 return m_doc == imageEventListener->m_doc;
505 return false; 593 return false;
506 } 594 }
507 595
508 } // namespace blink 596 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/ImageDocument.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698