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

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: Self review nits Created 6 years, 5 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 29 matching lines...) Expand all
40 #include "core/html/parser/HTMLParserIdioms.h" 40 #include "core/html/parser/HTMLParserIdioms.h"
41 #include "core/html/parser/HTMLSrcsetParser.h" 41 #include "core/html/parser/HTMLSrcsetParser.h"
42 #include "core/rendering/RenderImage.h" 42 #include "core/rendering/RenderImage.h"
43 #include "platform/MIMETypeRegistry.h" 43 #include "platform/MIMETypeRegistry.h"
44 #include "platform/RuntimeEnabledFeatures.h" 44 #include "platform/RuntimeEnabledFeatures.h"
45 45
46 namespace blink { 46 namespace blink {
47 47
48 using namespace HTMLNames; 48 using namespace HTMLNames;
49 49
50 class HTMLImageElement::Listener FINAL : public MediaQueryListListener {
51 public:
52 static RefPtrWillBeRawPtr<Listener> create(HTMLImageElement* element)
53 {
54 return adoptRefWillBeNoop(new Listener(element));
55 }
56
57 virtual void call() OVERRIDE
58 {
59 if (m_element)
60 m_element->notifyViewportChanged();
61 }
62
63 void clearElement() { m_element = nullptr; }
haraken 2014/07/25 01:00:59 You can add #if !ENABLE(OILPAN) to this method.
64 virtual void trace(Visitor* visitor) OVERRIDE
65 {
66 visitor->trace(m_element);
67 MediaQueryListListener::trace(visitor);
68 }
69 private:
70 Listener(HTMLImageElement* element) : m_element(element) { }
haraken 2014/07/25 01:00:59 Add explicit.
71 RawPtrWillBeMember<HTMLImageElement> m_element;
72 };
73
50 HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form, bo ol createdByParser) 74 HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form, bo ol createdByParser)
51 : HTMLElement(imgTag, document) 75 : HTMLElement(imgTag, document)
52 , m_imageLoader(HTMLImageLoader::create(this)) 76 , m_imageLoader(HTMLImageLoader::create(this))
53 , m_compositeOperator(CompositeSourceOver) 77 , m_compositeOperator(CompositeSourceOver)
54 , m_imageDevicePixelRatio(1.0f) 78 , m_imageDevicePixelRatio(1.0f)
55 , m_formWasSetByParser(false) 79 , m_formWasSetByParser(false)
56 , m_elementCreatedByParser(createdByParser) 80 , m_elementCreatedByParser(createdByParser)
81 , m_intrinsicSizingViewportDependant(false)
82 , m_effectiveSizeViewportDependant(false)
57 { 83 {
58 ScriptWrappable::init(this); 84 ScriptWrappable::init(this);
59 if (form && form->inDocument()) { 85 if (form && form->inDocument()) {
60 #if ENABLE(OILPAN) 86 #if ENABLE(OILPAN)
61 m_form = form; 87 m_form = form;
62 #else 88 #else
63 m_form = form->createWeakPtr(); 89 m_form = form->createWeakPtr();
64 #endif 90 #endif
65 m_formWasSetByParser = true; 91 m_formWasSetByParser = true;
66 m_form->associate(*this); 92 m_form->associate(*this);
67 m_form->didAssociateByParser(); 93 m_form->didAssociateByParser();
68 } 94 }
69 } 95 }
70 96
71 PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::create(Document& docu ment) 97 PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::create(Document& docu ment)
72 { 98 {
73 return adoptRefWillBeNoop(new HTMLImageElement(document)); 99 return adoptRefWillBeNoop(new HTMLImageElement(document));
74 } 100 }
75 101
76 PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::create(Document& docu ment, HTMLFormElement* form, bool createdByParser) 102 PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::create(Document& docu ment, HTMLFormElement* form, bool createdByParser)
77 { 103 {
78 return adoptRefWillBeNoop(new HTMLImageElement(document, form, createdByPars er)); 104 return adoptRefWillBeNoop(new HTMLImageElement(document, form, createdByPars er));
79 } 105 }
80 106
81 HTMLImageElement::~HTMLImageElement() 107 HTMLImageElement::~HTMLImageElement()
82 { 108 {
83 #if !ENABLE(OILPAN) 109 #if !ENABLE(OILPAN)
110 if (m_listener) {
111 document().mediaQueryMatcher().removeViewportListener(m_listener.get());
112 m_listener->clearElement();
113 }
84 if (m_form) 114 if (m_form)
85 m_form->disassociate(*this); 115 m_form->disassociate(*this);
86 #endif 116 #endif
87 } 117 }
88 118
89 void HTMLImageElement::trace(Visitor* visitor) 119 void HTMLImageElement::trace(Visitor* visitor)
90 { 120 {
91 visitor->trace(m_imageLoader); 121 visitor->trace(m_imageLoader);
92 visitor->trace(m_form); 122 visitor->trace(m_form);
123 visitor->trace(m_listener);
93 HTMLElement::trace(visitor); 124 HTMLElement::trace(visitor);
94 } 125 }
95 126
127 void HTMLImageElement::notifyViewportChanged()
128 {
129 // Re-selecting the source URL in order to pick a more fitting resource
130 // And update the image's intrinsic dimensions when the viewport changes.
131 // Picking of a better fitting resource is UA dependant, not spec required.
132 selectSourceURL(ImageLoader::UpdateForce);
133 }
134
96 PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::createForJSConstructo r(Document& document, int width, int height) 135 PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::createForJSConstructo r(Document& document, int width, int height)
97 { 136 {
98 RefPtrWillBeRawPtr<HTMLImageElement> image = adoptRefWillBeNoop(new HTMLImag eElement(document)); 137 RefPtrWillBeRawPtr<HTMLImageElement> image = adoptRefWillBeNoop(new HTMLImag eElement(document));
99 if (width) 138 if (width)
100 image->setWidth(width); 139 image->setWidth(width);
101 if (height) 140 if (height)
102 image->setHeight(height); 141 image->setHeight(height);
103 image->m_elementCreatedByParser = false; 142 image->m_elementCreatedByParser = false;
104 return image.release(); 143 return image.release();
105 } 144 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 #endif 213 #endif
175 } 214 }
176 } 215 }
177 216
178 void HTMLImageElement::setBestFitURLAndDPRFromImageCandidate(const ImageCandidat e& candidate) 217 void HTMLImageElement::setBestFitURLAndDPRFromImageCandidate(const ImageCandidat e& candidate)
179 { 218 {
180 m_bestFitImageURL = candidate.url(); 219 m_bestFitImageURL = candidate.url();
181 float candidateDensity = candidate.density(); 220 float candidateDensity = candidate.density();
182 if (candidateDensity >= 0) 221 if (candidateDensity >= 0)
183 m_imageDevicePixelRatio = 1.0 / candidateDensity; 222 m_imageDevicePixelRatio = 1.0 / candidateDensity;
223 if (candidate.resourceWidth() > 0)
224 m_intrinsicSizingViewportDependant = true;
184 if (renderer() && renderer()->isImage()) 225 if (renderer() && renderer()->isImage())
185 toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRa tio); 226 toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRa tio);
186 } 227 }
187 228
188 void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value) 229 void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value)
189 { 230 {
190 if (name == altAttr) { 231 if (name == altAttr) {
191 if (renderer() && renderer()->isImage()) 232 if (renderer() && renderer()->isImage())
192 toRenderImage(renderer())->updateAltText(); 233 toRenderImage(renderer())->updateAltText();
193 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) { 234 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 String srcset = source->fastGetAttribute(srcsetAttr); 280 String srcset = source->fastGetAttribute(srcsetAttr);
240 if (srcset.isEmpty()) 281 if (srcset.isEmpty())
241 continue; 282 continue;
242 String type = source->fastGetAttribute(typeAttr); 283 String type = source->fastGetAttribute(typeAttr);
243 if (!type.isEmpty() && !supportedImageType(type)) 284 if (!type.isEmpty() && !supportedImageType(type))
244 continue; 285 continue;
245 286
246 if (!source->mediaQueryMatches()) 287 if (!source->mediaQueryMatches())
247 continue; 288 continue;
248 289
249 unsigned effectiveSize = SizesAttributeParser::findEffectiveSize(source- >fastGetAttribute(sizesAttr), MediaValuesDynamic::create(document())); 290 SizesAttributeParser parser = SizesAttributeParser(MediaValuesDynamic::c reate(document()), source->fastGetAttribute(sizesAttr));
291 unsigned effectiveSize = parser.length();
292 m_effectiveSizeViewportDependant = parser.viewportDependant();
250 ImageCandidate candidate = bestFitSourceForSrcsetAttribute(document().de vicePixelRatio(), effectiveSize, source->fastGetAttribute(srcsetAttr)); 293 ImageCandidate candidate = bestFitSourceForSrcsetAttribute(document().de vicePixelRatio(), effectiveSize, source->fastGetAttribute(srcsetAttr));
251 if (candidate.isEmpty()) 294 if (candidate.isEmpty())
252 continue; 295 continue;
253 return candidate; 296 return candidate;
254 } 297 }
255 return ImageCandidate(); 298 return ImageCandidate();
256 } 299 }
257 300
258 RenderObject* HTMLImageElement::createRenderer(RenderStyle* style) 301 RenderObject* HTMLImageElement::createRenderer(RenderStyle* style)
259 { 302 {
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 if (RuntimeEnabledFeatures::pictureEnabled()) { 606 if (RuntimeEnabledFeatures::pictureEnabled()) {
564 ImageCandidate candidate = findBestFitImageFromPictureParent(); 607 ImageCandidate candidate = findBestFitImageFromPictureParent();
565 if (!candidate.isEmpty()) { 608 if (!candidate.isEmpty()) {
566 setBestFitURLAndDPRFromImageCandidate(candidate); 609 setBestFitURLAndDPRFromImageCandidate(candidate);
567 foundURL = true; 610 foundURL = true;
568 } 611 }
569 } 612 }
570 613
571 if (!foundURL) { 614 if (!foundURL) {
572 unsigned effectiveSize = 0; 615 unsigned effectiveSize = 0;
573 if (RuntimeEnabledFeatures::pictureSizesEnabled()) 616 if (RuntimeEnabledFeatures::pictureSizesEnabled()) {
574 effectiveSize = SizesAttributeParser::findEffectiveSize(fastGetAttri bute(sizesAttr), MediaValuesDynamic::create(document())); 617 SizesAttributeParser parser = SizesAttributeParser(MediaValuesDynami c::create(document()), fastGetAttribute(sizesAttr));
618 effectiveSize = parser.length();
619 m_effectiveSizeViewportDependant = parser.viewportDependant();
620 }
575 ImageCandidate candidate = bestFitSourceForImageAttributes(document().de vicePixelRatio(), effectiveSize, fastGetAttribute(srcAttr), fastGetAttribute(src setAttr)); 621 ImageCandidate candidate = bestFitSourceForImageAttributes(document().de vicePixelRatio(), effectiveSize, fastGetAttribute(srcAttr), fastGetAttribute(src setAttr));
576 setBestFitURLAndDPRFromImageCandidate(candidate); 622 setBestFitURLAndDPRFromImageCandidate(candidate);
577 } 623 }
624 if (m_intrinsicSizingViewportDependant && m_effectiveSizeViewportDependant) {
625 if (!m_listener.get())
626 m_listener = Listener::create(this);
627 document().mediaQueryMatcher().addViewportListener(m_listener.get());
628 }
578 imageLoader().updateFromElement(behavior); 629 imageLoader().updateFromElement(behavior);
579 } 630 }
580 631
581 const KURL& HTMLImageElement::sourceURL() const 632 const KURL& HTMLImageElement::sourceURL() const
582 { 633 {
583 return cachedImage()->response().url(); 634 return cachedImage()->response().url();
584 } 635 }
585 636
586 } 637 }
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