OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |