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. |
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 Loading... | |
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.toAtomicString(); | |
esprehn
2014/05/20 06:54:05
toAtomicString is weird, I think you want 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 Loading... | |
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 Loading... | |
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. | |
esprehn
2014/05/20 06:54:05
Is there a bug for this?
| |
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 Loading... | |
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 } |
OLD | NEW |