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

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

Issue 288033018: Add HTMLPictureElement-based source selection to HTMLImageElement (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Review nits Created 6 years, 7 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/HTMLSrcsetParser.h » ('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.
11 * 11 *
12 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details. 15 * Library General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Library General Public License 17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to 18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA. 20 * Boston, MA 02110-1301, USA.
21 */ 21 */
22 22
23 #include "config.h" 23 #include "config.h"
24 #include "core/html/HTMLImageElement.h" 24 #include "core/html/HTMLImageElement.h"
25 25
26 #include "CSSPropertyNames.h" 26 #include "CSSPropertyNames.h"
27 #include "HTMLNames.h" 27 #include "HTMLNames.h"
28 #include "MediaTypeNames.h"
28 #include "RuntimeEnabledFeatures.h" 29 #include "RuntimeEnabledFeatures.h"
29 #include "bindings/v8/ScriptEventListener.h" 30 #include "bindings/v8/ScriptEventListener.h"
31 #include "core/css/MediaQueryMatcher.h"
30 #include "core/css/MediaValuesCached.h" 32 #include "core/css/MediaValuesCached.h"
31 #include "core/css/parser/SizesAttributeParser.h" 33 #include "core/css/parser/SizesAttributeParser.h"
32 #include "core/dom/Attribute.h" 34 #include "core/dom/Attribute.h"
33 #include "core/fetch/ImageResource.h" 35 #include "core/fetch/ImageResource.h"
34 #include "core/html/HTMLAnchorElement.h" 36 #include "core/html/HTMLAnchorElement.h"
35 #include "core/html/HTMLCanvasElement.h" 37 #include "core/html/HTMLCanvasElement.h"
36 #include "core/html/HTMLFormElement.h" 38 #include "core/html/HTMLFormElement.h"
39 #include "core/html/HTMLSourceElement.h"
37 #include "core/html/canvas/CanvasRenderingContext.h" 40 #include "core/html/canvas/CanvasRenderingContext.h"
38 #include "core/html/parser/HTMLParserIdioms.h" 41 #include "core/html/parser/HTMLParserIdioms.h"
39 #include "core/html/parser/HTMLSrcsetParser.h" 42 #include "core/html/parser/HTMLSrcsetParser.h"
40 #include "core/rendering/RenderImage.h" 43 #include "core/rendering/RenderImage.h"
44 #include "platform/MIMETypeRegistry.h"
41 45
42 using namespace std; 46 using namespace std;
43 47
44 namespace WebCore { 48 namespace WebCore {
45 49
46 using namespace HTMLNames; 50 using namespace HTMLNames;
47 51
48 HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form) 52 HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form)
49 : HTMLElement(imgTag, document) 53 : HTMLElement(imgTag, document)
50 , m_imageLoader(this) 54 , m_imageLoader(this)
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 m_form->disassociate(*this); 147 m_form->disassociate(*this);
144 } 148 }
145 if (nearestForm) { 149 if (nearestForm) {
146 m_form = nearestForm->createWeakPtr(); 150 m_form = nearestForm->createWeakPtr();
147 m_form->associate(*this); 151 m_form->associate(*this);
148 } else { 152 } else {
149 m_form = WeakPtr<HTMLFormElement>(); 153 m_form = WeakPtr<HTMLFormElement>();
150 } 154 }
151 } 155 }
152 156
157 void HTMLImageElement::setBestFitURLAndDPRFromImageCandidate(const ImageCandidat e& candidate)
158 {
159 m_bestFitImageURL = candidate.url();
160 float candidateScaleFactor = candidate.scaleFactor();
161 // FIXME: Make this ">0" part match the spec, once it settles.
162 if (candidateScaleFactor > 0)
163 m_imageDevicePixelRatio = 1 / candidateScaleFactor;
164 if (renderer() && renderer()->isImage())
165 toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRa tio);
166 }
167
153 void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value) 168 void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value)
154 { 169 {
155 if (name == altAttr) { 170 if (name == altAttr) {
156 if (renderer() && renderer()->isImage()) 171 if (renderer() && renderer()->isImage())
157 toRenderImage(renderer())->updateAltText(); 172 toRenderImage(renderer())->updateAltText();
158 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) { 173 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) {
159 int effectiveSize = 0; 174 unsigned effectiveSize = 0;
160 if (RuntimeEnabledFeatures::pictureSizesEnabled()) 175 if (RuntimeEnabledFeatures::pictureSizesEnabled())
161 effectiveSize = SizesAttributeParser::findEffectiveSize(fastGetAttri bute(sizesAttr), MediaValuesCached::create(document())); 176 effectiveSize = SizesAttributeParser::findEffectiveSize(fastGetAttri bute(sizesAttr), MediaValuesCached::create(document()));
162 ImageCandidate candidate = bestFitSourceForImageAttributes(document().de vicePixelRatio(), effectiveSize, fastGetAttribute(srcAttr), fastGetAttribute(src setAttr)); 177 ImageCandidate candidate = bestFitSourceForImageAttributes(document().de vicePixelRatio(), effectiveSize, fastGetAttribute(srcAttr), fastGetAttribute(src setAttr));
163 m_bestFitImageURL = candidate.toAtomicString(); 178 setBestFitURLAndDPRFromImageCandidate(candidate);
164 float candidateScaleFactor = candidate.scaleFactor();
165 // FIXME: Make this ">0" part match the spec, once it settles.
166 if (candidateScaleFactor > 0)
167 m_imageDevicePixelRatio = 1 / candidateScaleFactor;
168 if (renderer() && renderer()->isImage())
169 toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePix elRatio);
170 m_imageLoader.updateFromElementIgnoringPreviousError(); 179 m_imageLoader.updateFromElementIgnoringPreviousError();
171 } else if (name == usemapAttr) { 180 } else if (name == usemapAttr) {
172 setIsLink(!value.isNull()); 181 setIsLink(!value.isNull());
173 } else if (name == compositeAttr) { 182 } else if (name == compositeAttr) {
174 // FIXME: images don't support blend modes in their compositing attribut e. 183 // FIXME: images don't support blend modes in their compositing attribut e.
175 blink::WebBlendMode blendOp = blink::WebBlendModeNormal; 184 blink::WebBlendMode blendOp = blink::WebBlendModeNormal;
176 if (!parseCompositeAndBlendOperator(value, m_compositeOperator, blendOp) ) 185 if (!parseCompositeAndBlendOperator(value, m_compositeOperator, blendOp) )
177 m_compositeOperator = CompositeSourceOver; 186 m_compositeOperator = CompositeSourceOver;
178 } else { 187 } else {
179 HTMLElement::parseAttribute(name, value); 188 HTMLElement::parseAttribute(name, value);
180 } 189 }
181 } 190 }
182 191
183 const AtomicString& HTMLImageElement::altText() const 192 const AtomicString& HTMLImageElement::altText() const
184 { 193 {
185 // lets figure out the alt text.. magic stuff 194 // lets figure out the alt text.. magic stuff
186 // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen 195 // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen
187 // also heavily discussed by Hixie on bugzilla 196 // also heavily discussed by Hixie on bugzilla
188 const AtomicString& alt = fastGetAttribute(altAttr); 197 const AtomicString& alt = fastGetAttribute(altAttr);
189 if (!alt.isNull()) 198 if (!alt.isNull())
190 return alt; 199 return alt;
191 // fall back to title attribute 200 // fall back to title attribute
192 return fastGetAttribute(titleAttr); 201 return fastGetAttribute(titleAttr);
193 } 202 }
194 203
204 static bool supportedImageType(const String& type)
205 {
206 return MIMETypeRegistry::isSupportedImageResourceMIMEType(type);
207 }
208
209 // http://picture.responsiveimages.org/#update-source-set
210 ImageCandidate HTMLImageElement::findBestFitImageFromPictureParent()
211 {
212 ASSERT(isMainThread());
213 Node* parent = parentNode();
214 if (!parent || !isHTMLPictureElement(*parent))
215 return ImageCandidate();
216 for (Node* child = parent->firstChild(); child; child = child->nextSibling() ) {
217 if (child == this)
218 return ImageCandidate();
219
220 if (!isHTMLSourceElement(*child))
221 continue;
222
223 HTMLSourceElement* source = toHTMLSourceElement(child);
224 String srcset = source->fastGetAttribute(srcsetAttr);
225 if (srcset.isEmpty())
226 continue;
227 String type = source->fastGetAttribute(typeAttr);
228 if (!type.isEmpty() && !supportedImageType(type))
229 continue;
230
231 String media = source->fastGetAttribute(mediaAttr);
232 if (!media.isEmpty()) {
233 RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(media);
234 if (!document().mediaQueryMatcher().evaluate(mediaQueries.get()))
235 continue;
236 }
237
238 unsigned effectiveSize = SizesAttributeParser::findEffectiveSize(source- >fastGetAttribute(sizesAttr), MediaValuesCached::create(document()));
239 ImageCandidate candidate = bestFitSourceForSrcsetAttribute(document().de vicePixelRatio(), effectiveSize, source->fastGetAttribute(srcsetAttr));
240 if (candidate.isEmpty())
241 continue;
242 return candidate;
243 }
244 return ImageCandidate();
245 }
246
195 RenderObject* HTMLImageElement::createRenderer(RenderStyle* style) 247 RenderObject* HTMLImageElement::createRenderer(RenderStyle* style)
196 { 248 {
197 if (style->hasContent()) 249 if (style->hasContent())
198 return RenderObject::createObject(this, style); 250 return RenderObject::createObject(this, style);
199 251
200 RenderImage* image = new RenderImage(this); 252 RenderImage* image = new RenderImage(this);
201 image->setImageResource(RenderImageResource::create()); 253 image->setImageResource(RenderImageResource::create());
202 image->setImageDevicePixelRatio(m_imageDevicePixelRatio); 254 image->setImageDevicePixelRatio(m_imageDevicePixelRatio);
203 return image; 255 return image;
204 } 256 }
(...skipping 24 matching lines...) Expand all
229 renderImageResource->setImageResource(m_imageLoader.image()); 281 renderImageResource->setImageResource(m_imageLoader.image());
230 282
231 } 283 }
232 } 284 }
233 285
234 Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode* insertionPoint) 286 Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode* insertionPoint)
235 { 287 {
236 if (!m_formWasSetByParser || insertionPoint->highestAncestorOrSelf() != m_fo rm->highestAncestorOrSelf()) 288 if (!m_formWasSetByParser || insertionPoint->highestAncestorOrSelf() != m_fo rm->highestAncestorOrSelf())
237 resetFormOwner(); 289 resetFormOwner();
238 290
291 bool imageWasModified = false;
292 if (RuntimeEnabledFeatures::pictureEnabled()) {
293 ImageCandidate candidate = findBestFitImageFromPictureParent();
294 if (!candidate.isEmpty()) {
295 setBestFitURLAndDPRFromImageCandidate(candidate);
296 imageWasModified = true;
297 }
298 }
299
239 // If we have been inserted from a renderer-less document, 300 // If we have been inserted from a renderer-less document,
240 // our loader may have not fetched the image, so do it now. 301 // our loader may have not fetched the image, so do it now.
241 if (insertionPoint->inDocument() && !m_imageLoader.image()) 302 if ((insertionPoint->inDocument() && !m_imageLoader.image()) || imageWasModi fied)
242 m_imageLoader.updateFromElement(); 303 m_imageLoader.updateFromElement();
243 304
244 return HTMLElement::insertedInto(insertionPoint); 305 return HTMLElement::insertedInto(insertionPoint);
245 } 306 }
246 307
247 void HTMLImageElement::removedFrom(ContainerNode* insertionPoint) 308 void HTMLImageElement::removedFrom(ContainerNode* insertionPoint)
248 { 309 {
249 if (!m_form || m_form->highestAncestorOrSelf() != highestAncestorOrSelf()) 310 if (!m_form || m_form->highestAncestorOrSelf() != highestAncestorOrSelf())
250 resetFormOwner(); 311 resetFormOwner();
251 HTMLElement::removedFrom(insertionPoint); 312 HTMLElement::removedFrom(insertionPoint);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 int HTMLImageElement::naturalHeight() const 369 int HTMLImageElement::naturalHeight() const
309 { 370 {
310 if (!m_imageLoader.image()) 371 if (!m_imageLoader.image())
311 return 0; 372 return 0;
312 373
313 return m_imageLoader.image()->imageSizeForRenderer(renderer(), 1.0f).height( ); 374 return m_imageLoader.image()->imageSizeForRenderer(renderer(), 1.0f).height( );
314 } 375 }
315 376
316 const AtomicString& HTMLImageElement::currentSrc() const 377 const AtomicString& HTMLImageElement::currentSrc() const
317 { 378 {
379 // FIXME: Need to absolutize the returned value.
318 return m_bestFitImageURL; 380 return m_bestFitImageURL;
319 } 381 }
320 382
321 bool HTMLImageElement::isURLAttribute(const Attribute& attribute) const 383 bool HTMLImageElement::isURLAttribute(const Attribute& attribute) const
322 { 384 {
323 return attribute.name() == srcAttr 385 return attribute.name() == srcAttr
324 || attribute.name() == lowsrcAttr 386 || attribute.name() == lowsrcAttr
325 || attribute.name() == longdescAttr 387 || attribute.name() == longdescAttr
326 || (attribute.name() == usemapAttr && attribute.value().string()[0] != ' #') 388 || (attribute.name() == usemapAttr && attribute.value().string()[0] != ' #')
327 || HTMLElement::isURLAttribute(attribute); 389 || HTMLElement::isURLAttribute(attribute);
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 if (!image) 537 if (!image)
476 return FloatSize(); 538 return FloatSize();
477 LayoutSize size; 539 LayoutSize size;
478 size = image->imageSizeForRenderer(renderer(), 1.0f); // FIXME: Not sure abo ut this. 540 size = image->imageSizeForRenderer(renderer(), 1.0f); // FIXME: Not sure abo ut this.
479 if (renderer() && renderer()->isRenderImage() && image->image() && !image->i mage()->hasRelativeWidth()) 541 if (renderer() && renderer()->isRenderImage() && image->image() && !image->i mage()->hasRelativeWidth())
480 size.scale(toRenderImage(renderer())->imageDevicePixelRatio()); 542 size.scale(toRenderImage(renderer())->imageDevicePixelRatio());
481 return size; 543 return size;
482 } 544 }
483 545
484 } 546 }
OLDNEW
« no previous file with comments | « Source/core/html/HTMLImageElement.h ('k') | Source/core/html/parser/HTMLSrcsetParser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698