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

Side by Side Diff: Source/core/html/HTMLImageElement.cpp

Issue 369423002: Have srcset respond to viewport changes (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: rebase Created 6 years, 4 months 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 | « Source/core/html/HTMLImageElement.h ('k') | Source/core/html/parser/HTMLPreloadScanner.cpp » ('j') | 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) 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, 2008, 2010 Apple Inc. All rights reserv ed. 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserv ed.
5 * Copyright (C) 2010 Google Inc. All rights reserved. 5 * Copyright (C) 2010 Google Inc. All rights 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 #include "core/html/parser/HTMLParserIdioms.h" 42 #include "core/html/parser/HTMLParserIdioms.h"
43 #include "core/html/parser/HTMLSrcsetParser.h" 43 #include "core/html/parser/HTMLSrcsetParser.h"
44 #include "core/rendering/RenderImage.h" 44 #include "core/rendering/RenderImage.h"
45 #include "platform/MIMETypeRegistry.h" 45 #include "platform/MIMETypeRegistry.h"
46 #include "platform/RuntimeEnabledFeatures.h" 46 #include "platform/RuntimeEnabledFeatures.h"
47 47
48 namespace blink { 48 namespace blink {
49 49
50 using namespace HTMLNames; 50 using namespace HTMLNames;
51 51
52 class HTMLImageElement::ViewportChangeListener FINAL : public MediaQueryListList ener {
53 public:
54 static RefPtrWillBeRawPtr<ViewportChangeListener> create(HTMLImageElement* e lement)
55 {
56 return adoptRefWillBeNoop(new ViewportChangeListener(element));
57 }
58
59 virtual void call() OVERRIDE
60 {
61 if (m_element)
62 m_element->notifyViewportChanged();
63 }
64
65 #if !ENABLE(OILPAN)
66 void clearElement() { m_element = nullptr; }
67 #endif
68 virtual void trace(Visitor* visitor) OVERRIDE
69 {
70 visitor->trace(m_element);
71 MediaQueryListListener::trace(visitor);
72 }
73 private:
74 explicit ViewportChangeListener(HTMLImageElement* element) : m_element(eleme nt) { }
75 RawPtrWillBeMember<HTMLImageElement> m_element;
76 };
77
52 HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form, bo ol createdByParser) 78 HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form, bo ol createdByParser)
53 : HTMLElement(imgTag, document) 79 : HTMLElement(imgTag, document)
54 , m_imageLoader(HTMLImageLoader::create(this)) 80 , m_imageLoader(HTMLImageLoader::create(this))
55 , m_compositeOperator(CompositeSourceOver) 81 , m_compositeOperator(CompositeSourceOver)
56 , m_imageDevicePixelRatio(1.0f) 82 , m_imageDevicePixelRatio(1.0f)
57 , m_formWasSetByParser(false) 83 , m_formWasSetByParser(false)
58 , m_elementCreatedByParser(createdByParser) 84 , m_elementCreatedByParser(createdByParser)
85 , m_intrinsicSizingViewportDependant(false)
86 , m_effectiveSizeViewportDependant(false)
59 { 87 {
60 ScriptWrappable::init(this); 88 ScriptWrappable::init(this);
61 if (form && form->inDocument()) { 89 if (form && form->inDocument()) {
62 #if ENABLE(OILPAN) 90 #if ENABLE(OILPAN)
63 m_form = form; 91 m_form = form;
64 #else 92 #else
65 m_form = form->createWeakPtr(); 93 m_form = form->createWeakPtr();
66 #endif 94 #endif
67 m_formWasSetByParser = true; 95 m_formWasSetByParser = true;
68 m_form->associate(*this); 96 m_form->associate(*this);
69 m_form->didAssociateByParser(); 97 m_form->didAssociateByParser();
70 } 98 }
71 } 99 }
72 100
73 PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::create(Document& docu ment) 101 PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::create(Document& docu ment)
74 { 102 {
75 return adoptRefWillBeNoop(new HTMLImageElement(document)); 103 return adoptRefWillBeNoop(new HTMLImageElement(document));
76 } 104 }
77 105
78 PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::create(Document& docu ment, HTMLFormElement* form, bool createdByParser) 106 PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::create(Document& docu ment, HTMLFormElement* form, bool createdByParser)
79 { 107 {
80 return adoptRefWillBeNoop(new HTMLImageElement(document, form, createdByPars er)); 108 return adoptRefWillBeNoop(new HTMLImageElement(document, form, createdByPars er));
81 } 109 }
82 110
83 HTMLImageElement::~HTMLImageElement() 111 HTMLImageElement::~HTMLImageElement()
84 { 112 {
85 #if !ENABLE(OILPAN) 113 #if !ENABLE(OILPAN)
114 if (m_listener) {
115 document().mediaQueryMatcher().removeViewportListener(m_listener.get());
116 m_listener->clearElement();
117 }
86 if (m_form) 118 if (m_form)
87 m_form->disassociate(*this); 119 m_form->disassociate(*this);
88 #endif 120 #endif
89 } 121 }
90 122
91 void HTMLImageElement::trace(Visitor* visitor) 123 void HTMLImageElement::trace(Visitor* visitor)
92 { 124 {
93 visitor->trace(m_imageLoader); 125 visitor->trace(m_imageLoader);
126 visitor->trace(m_listener);
94 visitor->trace(m_form); 127 visitor->trace(m_form);
95 HTMLElement::trace(visitor); 128 HTMLElement::trace(visitor);
96 } 129 }
97 130
131 void HTMLImageElement::notifyViewportChanged()
132 {
133 // Re-selecting the source URL in order to pick a more fitting resource
134 // And update the image's intrinsic dimensions when the viewport changes.
135 // Picking of a better fitting resource is UA dependant, not spec required.
136 selectSourceURL(ImageLoader::UpdateSizeChanged);
137 }
138
98 PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::createForJSConstructo r(Document& document, int width, int height) 139 PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::createForJSConstructo r(Document& document, int width, int height)
99 { 140 {
100 RefPtrWillBeRawPtr<HTMLImageElement> image = adoptRefWillBeNoop(new HTMLImag eElement(document)); 141 RefPtrWillBeRawPtr<HTMLImageElement> image = adoptRefWillBeNoop(new HTMLImag eElement(document));
101 if (width) 142 if (width)
102 image->setWidth(width); 143 image->setWidth(width);
103 if (height) 144 if (height)
104 image->setHeight(height); 145 image->setHeight(height);
105 image->m_elementCreatedByParser = false; 146 image->m_elementCreatedByParser = false;
106 return image.release(); 147 return image.release();
107 } 148 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 #endif 217 #endif
177 } 218 }
178 } 219 }
179 220
180 void HTMLImageElement::setBestFitURLAndDPRFromImageCandidate(const ImageCandidat e& candidate) 221 void HTMLImageElement::setBestFitURLAndDPRFromImageCandidate(const ImageCandidat e& candidate)
181 { 222 {
182 m_bestFitImageURL = candidate.url(); 223 m_bestFitImageURL = candidate.url();
183 float candidateDensity = candidate.density(); 224 float candidateDensity = candidate.density();
184 if (candidateDensity >= 0) 225 if (candidateDensity >= 0)
185 m_imageDevicePixelRatio = 1.0 / candidateDensity; 226 m_imageDevicePixelRatio = 1.0 / candidateDensity;
227 if (candidate.resourceWidth() > 0)
228 m_intrinsicSizingViewportDependant = true;
186 if (renderer() && renderer()->isImage()) 229 if (renderer() && renderer()->isImage())
187 toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRa tio); 230 toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRa tio);
188 } 231 }
189 232
190 void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value) 233 void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value)
191 { 234 {
192 if (name == altAttr) { 235 if (name == altAttr) {
193 if (renderer() && renderer()->isImage()) 236 if (renderer() && renderer()->isImage())
194 toRenderImage(renderer())->updateAltText(); 237 toRenderImage(renderer())->updateAltText();
195 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) { 238 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 String srcset = source->fastGetAttribute(srcsetAttr); 285 String srcset = source->fastGetAttribute(srcsetAttr);
243 if (srcset.isEmpty()) 286 if (srcset.isEmpty())
244 continue; 287 continue;
245 String type = source->fastGetAttribute(typeAttr); 288 String type = source->fastGetAttribute(typeAttr);
246 if (!type.isEmpty() && !supportedImageType(type)) 289 if (!type.isEmpty() && !supportedImageType(type))
247 continue; 290 continue;
248 291
249 if (!source->mediaQueryMatches()) 292 if (!source->mediaQueryMatches())
250 continue; 293 continue;
251 294
252 unsigned effectiveSize = SizesAttributeParser::findEffectiveSize(source- >fastGetAttribute(sizesAttr), MediaValuesDynamic::create(document())); 295 SizesAttributeParser parser = SizesAttributeParser(MediaValuesDynamic::c reate(document()), source->fastGetAttribute(sizesAttr));
296 unsigned effectiveSize = parser.length();
297 m_effectiveSizeViewportDependant = parser.viewportDependant();
253 ImageCandidate candidate = bestFitSourceForSrcsetAttribute(document().de vicePixelRatio(), effectiveSize, source->fastGetAttribute(srcsetAttr)); 298 ImageCandidate candidate = bestFitSourceForSrcsetAttribute(document().de vicePixelRatio(), effectiveSize, source->fastGetAttribute(srcsetAttr));
254 if (candidate.isEmpty()) 299 if (candidate.isEmpty())
255 continue; 300 continue;
256 return candidate; 301 return candidate;
257 } 302 }
258 return ImageCandidate(); 303 return ImageCandidate();
259 } 304 }
260 305
261 RenderObject* HTMLImageElement::createRenderer(RenderStyle* style) 306 RenderObject* HTMLImageElement::createRenderer(RenderStyle* style)
262 { 307 {
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 if (RuntimeEnabledFeatures::pictureEnabled()) { 611 if (RuntimeEnabledFeatures::pictureEnabled()) {
567 ImageCandidate candidate = findBestFitImageFromPictureParent(); 612 ImageCandidate candidate = findBestFitImageFromPictureParent();
568 if (!candidate.isEmpty()) { 613 if (!candidate.isEmpty()) {
569 setBestFitURLAndDPRFromImageCandidate(candidate); 614 setBestFitURLAndDPRFromImageCandidate(candidate);
570 foundURL = true; 615 foundURL = true;
571 } 616 }
572 } 617 }
573 618
574 if (!foundURL) { 619 if (!foundURL) {
575 unsigned effectiveSize = 0; 620 unsigned effectiveSize = 0;
576 if (RuntimeEnabledFeatures::pictureSizesEnabled()) 621 if (RuntimeEnabledFeatures::pictureSizesEnabled()) {
577 effectiveSize = SizesAttributeParser::findEffectiveSize(fastGetAttri bute(sizesAttr), MediaValuesDynamic::create(document())); 622 SizesAttributeParser parser = SizesAttributeParser(MediaValuesDynami c::create(document()), fastGetAttribute(sizesAttr));
623 effectiveSize = parser.length();
624 m_effectiveSizeViewportDependant = parser.viewportDependant();
625 }
578 ImageCandidate candidate = bestFitSourceForImageAttributes(document().de vicePixelRatio(), effectiveSize, fastGetAttribute(srcAttr), fastGetAttribute(src setAttr)); 626 ImageCandidate candidate = bestFitSourceForImageAttributes(document().de vicePixelRatio(), effectiveSize, fastGetAttribute(srcAttr), fastGetAttribute(src setAttr));
579 setBestFitURLAndDPRFromImageCandidate(candidate); 627 setBestFitURLAndDPRFromImageCandidate(candidate);
580 } 628 }
629 if (m_intrinsicSizingViewportDependant && m_effectiveSizeViewportDependant & & !m_listener.get()) {
630 m_listener = ViewportChangeListener::create(this);
631 document().mediaQueryMatcher().addViewportListener(m_listener.get());
632 }
581 imageLoader().updateFromElement(behavior); 633 imageLoader().updateFromElement(behavior);
582 } 634 }
583 635
584 const KURL& HTMLImageElement::sourceURL() const 636 const KURL& HTMLImageElement::sourceURL() const
585 { 637 {
586 return cachedImage()->response().url(); 638 return cachedImage()->response().url();
587 } 639 }
588 640
589 } 641 }
OLDNEW
« no previous file with comments | « Source/core/html/HTMLImageElement.h ('k') | Source/core/html/parser/HTMLPreloadScanner.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698