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

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: Fixed algo bug and added tests 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') | no next file » | 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"
30 #include "core/css/MediaValuesCached.h" 31 #include "core/css/MediaValuesCached.h"
31 #include "core/css/parser/SizesAttributeParser.h" 32 #include "core/css/parser/SizesAttributeParser.h"
32 #include "core/dom/Attribute.h" 33 #include "core/dom/Attribute.h"
33 #include "core/fetch/ImageResource.h" 34 #include "core/fetch/ImageResource.h"
34 #include "core/html/HTMLAnchorElement.h" 35 #include "core/html/HTMLAnchorElement.h"
35 #include "core/html/HTMLCanvasElement.h" 36 #include "core/html/HTMLCanvasElement.h"
36 #include "core/html/HTMLFormElement.h" 37 #include "core/html/HTMLFormElement.h"
38 #include "core/html/HTMLSourceElement.h"
37 #include "core/html/canvas/CanvasRenderingContext.h" 39 #include "core/html/canvas/CanvasRenderingContext.h"
38 #include "core/html/parser/HTMLParserIdioms.h" 40 #include "core/html/parser/HTMLParserIdioms.h"
39 #include "core/html/parser/HTMLSrcsetParser.h" 41 #include "core/html/parser/HTMLSrcsetParser.h"
40 #include "core/rendering/RenderImage.h" 42 #include "core/rendering/RenderImage.h"
43 #include "platform/MIMETypeRegistry.h"
41 44
42 using namespace std; 45 using namespace std;
43 46
44 namespace WebCore { 47 namespace WebCore {
45 48
46 using namespace HTMLNames; 49 using namespace HTMLNames;
47 50
48 HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form) 51 HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form)
49 : HTMLElement(imgTag, document) 52 : HTMLElement(imgTag, document)
50 , m_imageLoader(this) 53 , m_imageLoader(this)
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 m_form->disassociate(*this); 146 m_form->disassociate(*this);
144 } 147 }
145 if (nearestForm) { 148 if (nearestForm) {
146 m_form = nearestForm->createWeakPtr(); 149 m_form = nearestForm->createWeakPtr();
147 m_form->associate(*this); 150 m_form->associate(*this);
148 } else { 151 } else {
149 m_form = WeakPtr<HTMLFormElement>(); 152 m_form = WeakPtr<HTMLFormElement>();
150 } 153 }
151 } 154 }
152 155
156 void HTMLImageElement::setBestFitURLAndDPRFromImageCandidate(const ImageCandidat e& candidate)
157 {
158 m_bestFitImageURL = candidate.toAtomicString();
159 float candidateScaleFactor = candidate.scaleFactor();
160 // FIXME: Make this ">0" part match the spec, once it settles.
161 if (candidateScaleFactor > 0)
162 m_imageDevicePixelRatio = 1 / candidateScaleFactor;
163 if (renderer() && renderer()->isImage())
164 toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRa tio);
165 }
166
153 void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value) 167 void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value)
154 { 168 {
155 if (name == altAttr) { 169 if (name == altAttr) {
156 if (renderer() && renderer()->isImage()) 170 if (renderer() && renderer()->isImage())
157 toRenderImage(renderer())->updateAltText(); 171 toRenderImage(renderer())->updateAltText();
158 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) { 172 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) {
159 int effectiveSize = 0; 173 unsigned effectiveSize = 0;
160 if (RuntimeEnabledFeatures::pictureSizesEnabled()) 174 if (RuntimeEnabledFeatures::pictureSizesEnabled())
161 effectiveSize = SizesAttributeParser::findEffectiveSize(fastGetAttri bute(sizesAttr), MediaValuesCached::create(document())); 175 effectiveSize = SizesAttributeParser::findEffectiveSize(fastGetAttri bute(sizesAttr), MediaValuesCached::create(document()));
162 ImageCandidate candidate = bestFitSourceForImageAttributes(document().de vicePixelRatio(), effectiveSize, fastGetAttribute(srcAttr), fastGetAttribute(src setAttr)); 176 ImageCandidate candidate = bestFitSourceForImageAttributes(document().de vicePixelRatio(), effectiveSize, fastGetAttribute(srcAttr), fastGetAttribute(src setAttr));
163 m_bestFitImageURL = candidate.toAtomicString(); 177 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(); 178 m_imageLoader.updateFromElementIgnoringPreviousError();
171 } else if (name == usemapAttr) { 179 } else if (name == usemapAttr) {
172 setIsLink(!value.isNull()); 180 setIsLink(!value.isNull());
173 } else if (name == compositeAttr) { 181 } else if (name == compositeAttr) {
174 // FIXME: images don't support blend modes in their compositing attribut e. 182 // FIXME: images don't support blend modes in their compositing attribut e.
175 blink::WebBlendMode blendOp = blink::WebBlendModeNormal; 183 blink::WebBlendMode blendOp = blink::WebBlendModeNormal;
176 if (!parseCompositeAndBlendOperator(value, m_compositeOperator, blendOp) ) 184 if (!parseCompositeAndBlendOperator(value, m_compositeOperator, blendOp) )
177 m_compositeOperator = CompositeSourceOver; 185 m_compositeOperator = CompositeSourceOver;
178 } else { 186 } else {
179 HTMLElement::parseAttribute(name, value); 187 HTMLElement::parseAttribute(name, value);
180 } 188 }
181 } 189 }
182 190
183 const AtomicString& HTMLImageElement::altText() const 191 const AtomicString& HTMLImageElement::altText() const
184 { 192 {
185 // lets figure out the alt text.. magic stuff 193 // lets figure out the alt text.. magic stuff
186 // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen 194 // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen
187 // also heavily discussed by Hixie on bugzilla 195 // also heavily discussed by Hixie on bugzilla
188 const AtomicString& alt = fastGetAttribute(altAttr); 196 const AtomicString& alt = fastGetAttribute(altAttr);
189 if (!alt.isNull()) 197 if (!alt.isNull())
190 return alt; 198 return alt;
191 // fall back to title attribute 199 // fall back to title attribute
192 return fastGetAttribute(titleAttr); 200 return fastGetAttribute(titleAttr);
193 } 201 }
194 202
203 static bool supportedImageType(const String& type)
204 {
205 return MIMETypeRegistry::isSupportedImageResourceMIMEType(type);
206 }
207
208 // http://picture.responsiveimages.org/#update-source-set
209 bool HTMLImageElement::getBestFitImageFromPictureParent()
esprehn 2014/05/16 23:31:57 This is pretty strange to start with "get", what d
210 {
211 ASSERT(isMainThread());
212 Node* parent = parentNode();
213 if (!parent || !isHTMLPictureElement(*parent))
214 return false;
215 for (Node* child = parent->firstChild(); child; child = child->nextSibling() ) {
esprehn 2014/05/16 23:31:57 You want Traversal<HTMLSourceElement> here.
216 if (child == this)
217 return false;
218
219 if (!isHTMLSourceElement(*child))
220 continue;
221
222 HTMLSourceElement* source = toHTMLSourceElement(child);
223 if (!source->fastHasAttribute(srcsetAttr))
224 continue;
225 if (source->fastHasAttribute(typeAttr) && !supportedImageType(source->fa stGetAttribute(typeAttr)))
esprehn 2014/05/16 23:31:57 ditto. Just unconditionally call get and make supp
226 continue;
227
228 if (source->fastHasAttribute(mediaAttr)) {
esprehn 2014/05/16 23:31:57 I'd suggest just calling fastGetAttribute() and lo
229 RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(source->f astGetAttribute(mediaAttr));
230 MediaQueryEvaluator mediaQueryEvaluator(MediaTypeNames::screen, docu ment().frame());
231 if (!mediaQueryEvaluator.eval(mediaQueries.get()))
esprehn 2014/05/16 23:31:57 Why are you not using document()->mediaQueryMatche
232 continue;
233 }
234
235 unsigned effectiveSize = SizesAttributeParser::findEffectiveSize(source- >fastGetAttribute(sizesAttr), MediaValuesCached::create(document()));
236 ImageCandidate candidate = bestFitSourceForSrcsetAttribute(document().de vicePixelRatio(), effectiveSize, source->fastGetAttribute(srcsetAttr));
237 if (candidate.isEmpty())
238 continue;
239 setBestFitURLAndDPRFromImageCandidate(candidate);
esprehn 2014/05/16 23:31:57 Lets just return the candidate instead. This metho
240 return true;
241 }
242 return false;
esprehn 2014/05/16 23:31:57 return 0;
243 }
244
195 RenderObject* HTMLImageElement::createRenderer(RenderStyle* style) 245 RenderObject* HTMLImageElement::createRenderer(RenderStyle* style)
196 { 246 {
197 if (style->hasContent()) 247 if (style->hasContent())
198 return RenderObject::createObject(this, style); 248 return RenderObject::createObject(this, style);
199 249
200 RenderImage* image = new RenderImage(this); 250 RenderImage* image = new RenderImage(this);
201 image->setImageResource(RenderImageResource::create()); 251 image->setImageResource(RenderImageResource::create());
202 image->setImageDevicePixelRatio(m_imageDevicePixelRatio); 252 image->setImageDevicePixelRatio(m_imageDevicePixelRatio);
203 return image; 253 return image;
204 } 254 }
(...skipping 24 matching lines...) Expand all
229 renderImageResource->setImageResource(m_imageLoader.image()); 279 renderImageResource->setImageResource(m_imageLoader.image());
230 280
231 } 281 }
232 } 282 }
233 283
234 Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode* insertionPoint) 284 Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode* insertionPoint)
235 { 285 {
236 if (!m_formWasSetByParser || insertionPoint->highestAncestorOrSelf() != m_fo rm->highestAncestorOrSelf()) 286 if (!m_formWasSetByParser || insertionPoint->highestAncestorOrSelf() != m_fo rm->highestAncestorOrSelf())
237 resetFormOwner(); 287 resetFormOwner();
238 288
289 bool imageWasModified = false;
290 if (RuntimeEnabledFeatures::pictureEnabled())
291 imageWasModified = getBestFitImageFromPictureParent();
esprehn 2014/05/16 23:31:57 getters don't start with "get", things that return
292
239 // If we have been inserted from a renderer-less document, 293 // If we have been inserted from a renderer-less document,
240 // our loader may have not fetched the image, so do it now. 294 // our loader may have not fetched the image, so do it now.
241 if (insertionPoint->inDocument() && !m_imageLoader.image()) 295 if ((insertionPoint->inDocument() && !m_imageLoader.image()) || imageWasModi fied)
242 m_imageLoader.updateFromElement(); 296 m_imageLoader.updateFromElement();
243 297
244 return HTMLElement::insertedInto(insertionPoint); 298 return HTMLElement::insertedInto(insertionPoint);
245 } 299 }
246 300
247 void HTMLImageElement::removedFrom(ContainerNode* insertionPoint) 301 void HTMLImageElement::removedFrom(ContainerNode* insertionPoint)
248 { 302 {
249 if (!m_form || m_form->highestAncestorOrSelf() != highestAncestorOrSelf()) 303 if (!m_form || m_form->highestAncestorOrSelf() != highestAncestorOrSelf())
250 resetFormOwner(); 304 resetFormOwner();
251 HTMLElement::removedFrom(insertionPoint); 305 HTMLElement::removedFrom(insertionPoint);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 int HTMLImageElement::naturalHeight() const 362 int HTMLImageElement::naturalHeight() const
309 { 363 {
310 if (!m_imageLoader.image()) 364 if (!m_imageLoader.image())
311 return 0; 365 return 0;
312 366
313 return m_imageLoader.image()->imageSizeForRenderer(renderer(), 1.0f).height( ); 367 return m_imageLoader.image()->imageSizeForRenderer(renderer(), 1.0f).height( );
314 } 368 }
315 369
316 const AtomicString& HTMLImageElement::currentSrc() const 370 const AtomicString& HTMLImageElement::currentSrc() const
317 { 371 {
372 // FIXME - Need to absolutize the returned value.
esprehn 2014/05/16 23:31:57 FIXME: not dash
318 return m_bestFitImageURL; 373 return m_bestFitImageURL;
319 } 374 }
320 375
321 bool HTMLImageElement::isURLAttribute(const Attribute& attribute) const 376 bool HTMLImageElement::isURLAttribute(const Attribute& attribute) const
322 { 377 {
323 return attribute.name() == srcAttr 378 return attribute.name() == srcAttr
324 || attribute.name() == lowsrcAttr 379 || attribute.name() == lowsrcAttr
325 || attribute.name() == longdescAttr 380 || attribute.name() == longdescAttr
326 || (attribute.name() == usemapAttr && attribute.value().string()[0] != ' #') 381 || (attribute.name() == usemapAttr && attribute.value().string()[0] != ' #')
327 || HTMLElement::isURLAttribute(attribute); 382 || HTMLElement::isURLAttribute(attribute);
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 if (!image) 530 if (!image)
476 return FloatSize(); 531 return FloatSize();
477 LayoutSize size; 532 LayoutSize size;
478 size = image->imageSizeForRenderer(renderer(), 1.0f); // FIXME: Not sure abo ut this. 533 size = image->imageSizeForRenderer(renderer(), 1.0f); // FIXME: Not sure abo ut this.
479 if (renderer() && renderer()->isRenderImage() && image->image() && !image->i mage()->hasRelativeWidth()) 534 if (renderer() && renderer()->isRenderImage() && image->image() && !image->i mage()->hasRelativeWidth())
480 size.scale(toRenderImage(renderer())->imageDevicePixelRatio()); 535 size.scale(toRenderImage(renderer())->imageDevicePixelRatio());
481 return size; 536 return size;
482 } 537 }
483 538
484 } 539 }
OLDNEW
« no previous file with comments | « Source/core/html/HTMLImageElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698