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