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

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

Issue 481753002: Use Shadow DOM to display fallback content for images (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Updated Created 6 years, 3 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 | Annotate | Revision Log
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.
(...skipping 19 matching lines...) Expand all
30 #include "core/css/MediaQueryMatcher.h" 30 #include "core/css/MediaQueryMatcher.h"
31 #include "core/css/MediaValuesDynamic.h" 31 #include "core/css/MediaValuesDynamic.h"
32 #include "core/css/parser/SizesAttributeParser.h" 32 #include "core/css/parser/SizesAttributeParser.h"
33 #include "core/dom/Attribute.h" 33 #include "core/dom/Attribute.h"
34 #include "core/dom/NodeTraversal.h" 34 #include "core/dom/NodeTraversal.h"
35 #include "core/fetch/ImageResource.h" 35 #include "core/fetch/ImageResource.h"
36 #include "core/frame/UseCounter.h" 36 #include "core/frame/UseCounter.h"
37 #include "core/html/HTMLAnchorElement.h" 37 #include "core/html/HTMLAnchorElement.h"
38 #include "core/html/HTMLCanvasElement.h" 38 #include "core/html/HTMLCanvasElement.h"
39 #include "core/html/HTMLFormElement.h" 39 #include "core/html/HTMLFormElement.h"
40 #include "core/html/HTMLImageFallbackHelper.h"
40 #include "core/html/HTMLSourceElement.h" 41 #include "core/html/HTMLSourceElement.h"
41 #include "core/html/canvas/CanvasRenderingContext.h" 42 #include "core/html/canvas/CanvasRenderingContext.h"
42 #include "core/html/parser/HTMLParserIdioms.h" 43 #include "core/html/parser/HTMLParserIdioms.h"
43 #include "core/html/parser/HTMLSrcsetParser.h" 44 #include "core/html/parser/HTMLSrcsetParser.h"
44 #include "core/inspector/ConsoleMessage.h" 45 #include "core/inspector/ConsoleMessage.h"
46 #include "core/rendering/RenderBlockFlow.h"
45 #include "core/rendering/RenderImage.h" 47 #include "core/rendering/RenderImage.h"
46 #include "platform/MIMETypeRegistry.h" 48 #include "platform/MIMETypeRegistry.h"
47 #include "platform/RuntimeEnabledFeatures.h" 49 #include "platform/RuntimeEnabledFeatures.h"
48 50
49 namespace blink { 51 namespace blink {
50 52
51 using namespace HTMLNames; 53 using namespace HTMLNames;
52 54
53 class HTMLImageElement::ViewportChangeListener FINAL : public MediaQueryListList ener { 55 class HTMLImageElement::ViewportChangeListener FINAL : public MediaQueryListList ener {
54 public: 56 public:
(...skipping 17 matching lines...) Expand all
72 MediaQueryListListener::trace(visitor); 74 MediaQueryListListener::trace(visitor);
73 } 75 }
74 private: 76 private:
75 explicit ViewportChangeListener(HTMLImageElement* element) : m_element(eleme nt) { } 77 explicit ViewportChangeListener(HTMLImageElement* element) : m_element(eleme nt) { }
76 RawPtrWillBeMember<HTMLImageElement> m_element; 78 RawPtrWillBeMember<HTMLImageElement> m_element;
77 }; 79 };
78 80
79 HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form, bo ol createdByParser) 81 HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form, bo ol createdByParser)
80 : HTMLElement(imgTag, document) 82 : HTMLElement(imgTag, document)
81 , m_imageLoader(HTMLImageLoader::create(this)) 83 , m_imageLoader(HTMLImageLoader::create(this))
84 , m_altTextNode(0)
82 , m_compositeOperator(CompositeSourceOver) 85 , m_compositeOperator(CompositeSourceOver)
83 , m_imageDevicePixelRatio(1.0f) 86 , m_imageDevicePixelRatio(1.0f)
84 , m_formWasSetByParser(false) 87 , m_formWasSetByParser(false)
85 , m_elementCreatedByParser(createdByParser) 88 , m_elementCreatedByParser(createdByParser)
86 , m_intrinsicSizingViewportDependant(false) 89 , m_intrinsicSizingViewportDependant(false)
87 , m_effectiveSizeViewportDependant(false) 90 , m_effectiveSizeViewportDependant(false)
91 , m_useFallbackContent(false)
92 , m_isFallbackImage(false)
88 { 93 {
89 ScriptWrappable::init(this); 94 ScriptWrappable::init(this);
95 setHasCustomStyleCallbacks();
90 if (form && form->inDocument()) { 96 if (form && form->inDocument()) {
91 #if ENABLE(OILPAN) 97 #if ENABLE(OILPAN)
92 m_form = form; 98 m_form = form;
93 #else 99 #else
94 m_form = form->createWeakPtr(); 100 m_form = form->createWeakPtr();
95 #endif 101 #endif
96 m_formWasSetByParser = true; 102 m_formWasSetByParser = true;
97 m_form->associate(*this); 103 m_form->associate(*this);
98 m_form->didAssociateByParser(); 104 m_form->didAssociateByParser();
99 } 105 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 UseCounter::count(document(), UseCounter::SrcsetWDescriptor); 236 UseCounter::count(document(), UseCounter::SrcsetWDescriptor);
231 } else if (!candidate.srcOrigin()) { 237 } else if (!candidate.srcOrigin()) {
232 UseCounter::count(document(), UseCounter::SrcsetXDescriptor); 238 UseCounter::count(document(), UseCounter::SrcsetXDescriptor);
233 } 239 }
234 if (renderer() && renderer()->isImage()) 240 if (renderer() && renderer()->isImage())
235 toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRa tio); 241 toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRa tio);
236 } 242 }
237 243
238 void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value) 244 void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value)
239 { 245 {
240 if (name == altAttr) { 246 if (name == altAttr || name == titleAttr) {
241 if (renderer() && renderer()->isImage()) 247 if (Text* text = altTextNode()) {
242 toRenderImage(renderer())->updateAltText(); 248 String alt = altText();
249 if (text->data() != alt)
250 text->setData(alt);
251 }
243 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) { 252 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) {
244 selectSourceURL(ImageLoader::UpdateIgnorePreviousError); 253 selectSourceURL(ImageLoader::UpdateIgnorePreviousError);
245 } else if (name == usemapAttr) { 254 } else if (name == usemapAttr) {
246 setIsLink(!value.isNull()); 255 setIsLink(!value.isNull());
247 } else if (name == compositeAttr) { 256 } else if (name == compositeAttr) {
248 blink::WebBlendMode blendOp = blink::WebBlendModeNormal; 257 blink::WebBlendMode blendOp = blink::WebBlendModeNormal;
249 if (!parseCompositeAndBlendOperator(value, m_compositeOperator, blendOp) ) 258 if (!parseCompositeAndBlendOperator(value, m_compositeOperator, blendOp) )
250 m_compositeOperator = CompositeSourceOver; 259 m_compositeOperator = CompositeSourceOver;
251 else if (m_compositeOperator != CompositeSourceOver) 260 else if (m_compositeOperator != CompositeSourceOver)
252 UseCounter::count(document(), UseCounter::HTMLImageElementComposite) ; 261 UseCounter::count(document(), UseCounter::HTMLImageElementComposite) ;
253 } else { 262 } else {
254 HTMLElement::parseAttribute(name, value); 263 HTMLElement::parseAttribute(name, value);
255 } 264 }
256 } 265 }
257 266
258 const AtomicString& HTMLImageElement::altText() const 267 String HTMLImageElement::altText() const
259 { 268 {
260 // lets figure out the alt text.. magic stuff 269 // lets figure out the alt text.. magic stuff
261 // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen 270 // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen
262 // also heavily discussed by Hixie on bugzilla 271 // also heavily discussed by Hixie on bugzilla
263 const AtomicString& alt = fastGetAttribute(altAttr); 272 const AtomicString& alt = fastGetAttribute(altAttr);
264 if (!alt.isNull()) 273 if (!alt.isNull())
265 return alt; 274 return alt;
266 // fall back to title attribute 275 // fall back to title attribute
267 return fastGetAttribute(titleAttr); 276 return fastGetAttribute(titleAttr);
268 } 277 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 return candidate; 320 return candidate;
312 } 321 }
313 return ImageCandidate(); 322 return ImageCandidate();
314 } 323 }
315 324
316 RenderObject* HTMLImageElement::createRenderer(RenderStyle* style) 325 RenderObject* HTMLImageElement::createRenderer(RenderStyle* style)
317 { 326 {
318 if (style->hasContent()) 327 if (style->hasContent())
319 return RenderObject::createObject(this, style); 328 return RenderObject::createObject(this, style);
320 329
330 if (m_useFallbackContent)
331 return new RenderBlockFlow(this);
332
321 RenderImage* image = new RenderImage(this); 333 RenderImage* image = new RenderImage(this);
322 image->setImageResource(RenderImageResource::create()); 334 image->setImageResource(RenderImageResource::create());
323 image->setImageDevicePixelRatio(m_imageDevicePixelRatio); 335 image->setImageDevicePixelRatio(m_imageDevicePixelRatio);
324 return image; 336 return image;
325 } 337 }
326 338
327 bool HTMLImageElement::canStartSelection() const 339 bool HTMLImageElement::canStartSelection() const
328 { 340 {
329 if (shadow()) 341 if (shadow())
330 return HTMLElement::canStartSelection(); 342 return HTMLElement::canStartSelection();
331 343
332 return false; 344 return false;
333 } 345 }
334 346
335 void HTMLImageElement::attach(const AttachContext& context) 347 void HTMLImageElement::attach(const AttachContext& context)
336 { 348 {
337 HTMLElement::attach(context); 349 HTMLElement::attach(context);
338 350
339 if (renderer() && renderer()->isImage()) { 351 if (renderer() && renderer()->isImage()) {
340 RenderImage* renderImage = toRenderImage(renderer()); 352 RenderImage* renderImage = toRenderImage(renderer());
341 RenderImageResource* renderImageResource = renderImage->imageResource(); 353 RenderImageResource* renderImageResource = renderImage->imageResource();
342 if (renderImageResource->hasImage()) 354 if (renderImageResource->hasImage())
343 return; 355 return;
344 356
345 // If we have no image at all because we have no src attribute, set
346 // image height and width for the alt text instead.
347 if (!imageLoader().image() && !renderImageResource->cachedImage()) 357 if (!imageLoader().image() && !renderImageResource->cachedImage())
348 renderImage->setImageSizeForAltText(); 358 return;
349 else 359 renderImageResource->setImageResource(imageLoader().image());
350 renderImageResource->setImageResource(imageLoader().image());
351
352 } 360 }
353 } 361 }
354 362
355 Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode* insertionPoint) 363 Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode* insertionPoint)
356 { 364 {
357 if (!m_formWasSetByParser || NodeTraversal::highestAncestorOrSelf(*insertion Point) != NodeTraversal::highestAncestorOrSelf(*m_form.get())) 365 if (!m_formWasSetByParser || NodeTraversal::highestAncestorOrSelf(*insertion Point) != NodeTraversal::highestAncestorOrSelf(*m_form.get()))
358 resetFormOwner(); 366 resetFormOwner();
359 if (m_listener) 367 if (m_listener)
360 document().mediaQueryMatcher().addViewportListener(m_listener); 368 document().mediaQueryMatcher().addViewportListener(m_listener);
361 369
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 m_effectiveSizeViewportDependant = parser.viewportDependant(); 649 m_effectiveSizeViewportDependant = parser.viewportDependant();
642 } 650 }
643 ImageCandidate candidate = bestFitSourceForImageAttributes(document().de vicePixelRatio(), effectiveSize, fastGetAttribute(srcAttr), fastGetAttribute(src setAttr)); 651 ImageCandidate candidate = bestFitSourceForImageAttributes(document().de vicePixelRatio(), effectiveSize, fastGetAttribute(srcAttr), fastGetAttribute(src setAttr));
644 setBestFitURLAndDPRFromImageCandidate(candidate); 652 setBestFitURLAndDPRFromImageCandidate(candidate);
645 } 653 }
646 if (m_intrinsicSizingViewportDependant && m_effectiveSizeViewportDependant & & !m_listener) { 654 if (m_intrinsicSizingViewportDependant && m_effectiveSizeViewportDependant & & !m_listener) {
647 m_listener = ViewportChangeListener::create(this); 655 m_listener = ViewportChangeListener::create(this);
648 document().mediaQueryMatcher().addViewportListener(m_listener); 656 document().mediaQueryMatcher().addViewportListener(m_listener);
649 } 657 }
650 imageLoader().updateFromElement(behavior); 658 imageLoader().updateFromElement(behavior);
659
660 if (imageLoader().image() || (imageLoader().hasPendingActivity() && !imageSo urceURL().isEmpty()))
661 ensurePrimaryContent();
662 else
663 ensureFallbackContent();
651 } 664 }
652 665
653 const KURL& HTMLImageElement::sourceURL() const 666 const KURL& HTMLImageElement::sourceURL() const
654 { 667 {
655 return cachedImage()->response().url(); 668 return cachedImage()->response().url();
656 } 669 }
657 670
671 void HTMLImageElement::didAddUserAgentShadowRoot(ShadowRoot&)
672 {
673 m_altTextNode = createAltTextShadowTree(*this);
658 } 674 }
675
676 void HTMLImageElement::ensureFallbackContent()
677 {
678 if (m_useFallbackContent || m_isFallbackImage)
679 return;
680 setUseFallbackContent();
681 reattachFallbackContent();
682 }
683
684 void HTMLImageElement::ensurePrimaryContent()
685 {
686 if (!m_useFallbackContent)
687 return;
688 m_useFallbackContent = false;
689 reattachFallbackContent();
690 }
691
692 void HTMLImageElement::reattachFallbackContent()
693 {
694 // This can happen inside of attach() in the middle of a recalcStyle so we n eed to
695 // reattach synchronously here.
696 if (document().inStyleRecalc())
697 reattach();
698 else
699 lazyReattachIfAttached();
700 }
701
702 PassRefPtr<RenderStyle> HTMLImageElement::customStyleForRenderer()
703 {
704 RefPtr<RenderStyle> newStyle = originalStyleForRenderer();
705
706 if (!m_useFallbackContent)
707 return newStyle;
708 return customStyleForAltText(*this, newStyle);
709 }
710 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698