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