Chromium Code Reviews| 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 |