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

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, 1 month 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 14 matching lines...) Expand all
25 25
26 #include "bindings/core/v8/ScriptEventListener.h" 26 #include "bindings/core/v8/ScriptEventListener.h"
27 #include "core/CSSPropertyNames.h" 27 #include "core/CSSPropertyNames.h"
28 #include "core/HTMLNames.h" 28 #include "core/HTMLNames.h"
29 #include "core/MediaTypeNames.h" 29 #include "core/MediaTypeNames.h"
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/dom/shadow/ShadowRoot.h"
35 #include "core/fetch/ImageResource.h" 36 #include "core/fetch/ImageResource.h"
36 #include "core/frame/UseCounter.h" 37 #include "core/frame/UseCounter.h"
37 #include "core/html/HTMLAnchorElement.h" 38 #include "core/html/HTMLAnchorElement.h"
38 #include "core/html/HTMLCanvasElement.h" 39 #include "core/html/HTMLCanvasElement.h"
39 #include "core/html/HTMLFormElement.h" 40 #include "core/html/HTMLFormElement.h"
41 #include "core/html/HTMLImageFallbackHelper.h"
40 #include "core/html/HTMLSourceElement.h" 42 #include "core/html/HTMLSourceElement.h"
41 #include "core/html/canvas/CanvasRenderingContext.h" 43 #include "core/html/canvas/CanvasRenderingContext.h"
42 #include "core/html/parser/HTMLParserIdioms.h" 44 #include "core/html/parser/HTMLParserIdioms.h"
43 #include "core/html/parser/HTMLSrcsetParser.h" 45 #include "core/html/parser/HTMLSrcsetParser.h"
44 #include "core/inspector/ConsoleMessage.h" 46 #include "core/inspector/ConsoleMessage.h"
47 #include "core/rendering/RenderBlockFlow.h"
45 #include "core/rendering/RenderImage.h" 48 #include "core/rendering/RenderImage.h"
46 #include "platform/ContentType.h" 49 #include "platform/ContentType.h"
47 #include "platform/MIMETypeRegistry.h" 50 #include "platform/MIMETypeRegistry.h"
48 #include "platform/RuntimeEnabledFeatures.h" 51 #include "platform/RuntimeEnabledFeatures.h"
49 52
50 namespace blink { 53 namespace blink {
51 54
52 using namespace HTMLNames; 55 using namespace HTMLNames;
53 56
54 class HTMLImageElement::ViewportChangeListener final : public MediaQueryListList ener { 57 class HTMLImageElement::ViewportChangeListener final : public MediaQueryListList ener {
(...skipping 22 matching lines...) Expand all
77 RawPtrWillBeMember<HTMLImageElement> m_element; 80 RawPtrWillBeMember<HTMLImageElement> m_element;
78 }; 81 };
79 82
80 HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form, bo ol createdByParser) 83 HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form, bo ol createdByParser)
81 : HTMLElement(imgTag, document) 84 : HTMLElement(imgTag, document)
82 , m_imageLoader(HTMLImageLoader::create(this)) 85 , m_imageLoader(HTMLImageLoader::create(this))
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)
90 , m_useFallbackContent(false)
91 , m_isFallbackImage(false)
87 { 92 {
93 setHasCustomStyleCallbacks();
88 if (form && form->inDocument()) { 94 if (form && form->inDocument()) {
89 #if ENABLE(OILPAN) 95 #if ENABLE(OILPAN)
90 m_form = form; 96 m_form = form;
91 #else 97 #else
92 m_form = form->createWeakPtr(); 98 m_form = form->createWeakPtr();
93 #endif 99 #endif
94 m_formWasSetByParser = true; 100 m_formWasSetByParser = true;
95 m_form->associate(*this); 101 m_form->associate(*this);
96 m_form->didAssociateByParser(); 102 m_form->didAssociateByParser();
97 } 103 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 UseCounter::count(document(), UseCounter::SrcsetWDescriptor); 234 UseCounter::count(document(), UseCounter::SrcsetWDescriptor);
229 } else if (!candidate.srcOrigin()) { 235 } else if (!candidate.srcOrigin()) {
230 UseCounter::count(document(), UseCounter::SrcsetXDescriptor); 236 UseCounter::count(document(), UseCounter::SrcsetXDescriptor);
231 } 237 }
232 if (renderer() && renderer()->isImage()) 238 if (renderer() && renderer()->isImage())
233 toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRa tio); 239 toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRa tio);
234 } 240 }
235 241
236 void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value) 242 void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value)
237 { 243 {
238 if (name == altAttr) { 244 if (name == altAttr || name == titleAttr) {
239 if (renderer() && renderer()->isImage()) 245 if (userAgentShadowRoot()) {
240 toRenderImage(renderer())->updateAltText(); 246 Element* text = userAgentShadowRoot()->getElementById("alttext");
247 String value = altText();
248 if (text && text->textContent() != value)
249 text->setTextContent(altText());
250 }
241 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) { 251 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) {
242 selectSourceURL(ImageLoader::UpdateIgnorePreviousError); 252 selectSourceURL(ImageLoader::UpdateIgnorePreviousError);
243 } else if (name == usemapAttr) { 253 } else if (name == usemapAttr) {
244 setIsLink(!value.isNull()); 254 setIsLink(!value.isNull());
245 } else { 255 } else {
246 HTMLElement::parseAttribute(name, value); 256 HTMLElement::parseAttribute(name, value);
247 } 257 }
248 } 258 }
249 259
250 const AtomicString& HTMLImageElement::altText() const 260 String HTMLImageElement::altText() const
251 { 261 {
252 // lets figure out the alt text.. magic stuff 262 // lets figure out the alt text.. magic stuff
253 // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen 263 // http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen
254 // also heavily discussed by Hixie on bugzilla 264 // also heavily discussed by Hixie on bugzilla
255 const AtomicString& alt = fastGetAttribute(altAttr); 265 const AtomicString& alt = fastGetAttribute(altAttr);
256 if (!alt.isNull()) 266 if (!alt.isNull())
257 return alt; 267 return alt;
258 // fall back to title attribute 268 // fall back to title attribute
259 return fastGetAttribute(titleAttr); 269 return fastGetAttribute(titleAttr);
260 } 270 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 return candidate; 316 return candidate;
307 } 317 }
308 return ImageCandidate(); 318 return ImageCandidate();
309 } 319 }
310 320
311 RenderObject* HTMLImageElement::createRenderer(RenderStyle* style) 321 RenderObject* HTMLImageElement::createRenderer(RenderStyle* style)
312 { 322 {
313 if (style->hasContent()) 323 if (style->hasContent())
314 return RenderObject::createObject(this, style); 324 return RenderObject::createObject(this, style);
315 325
326 if (m_useFallbackContent)
327 return new RenderBlockFlow(this);
328
316 RenderImage* image = new RenderImage(this); 329 RenderImage* image = new RenderImage(this);
317 image->setImageResource(RenderImageResource::create()); 330 image->setImageResource(RenderImageResource::create());
318 image->setImageDevicePixelRatio(m_imageDevicePixelRatio); 331 image->setImageDevicePixelRatio(m_imageDevicePixelRatio);
319 return image; 332 return image;
320 } 333 }
321 334
322 bool HTMLImageElement::canStartSelection() const 335 bool HTMLImageElement::canStartSelection() const
323 { 336 {
324 if (shadow()) 337 if (shadow())
325 return HTMLElement::canStartSelection(); 338 return HTMLElement::canStartSelection();
326 339
327 return false; 340 return false;
328 } 341 }
329 342
330 void HTMLImageElement::attach(const AttachContext& context) 343 void HTMLImageElement::attach(const AttachContext& context)
331 { 344 {
332 HTMLElement::attach(context); 345 HTMLElement::attach(context);
333 346
334 if (renderer() && renderer()->isImage()) { 347 if (renderer() && renderer()->isImage()) {
335 RenderImage* renderImage = toRenderImage(renderer()); 348 RenderImage* renderImage = toRenderImage(renderer());
336 RenderImageResource* renderImageResource = renderImage->imageResource(); 349 RenderImageResource* renderImageResource = renderImage->imageResource();
337 if (renderImageResource->hasImage()) 350 if (renderImageResource->hasImage())
338 return; 351 return;
339 352
340 // If we have no image at all because we have no src attribute, set
341 // image height and width for the alt text instead.
342 if (!imageLoader().image() && !renderImageResource->cachedImage()) 353 if (!imageLoader().image() && !renderImageResource->cachedImage())
343 renderImage->setImageSizeForAltText(); 354 return;
344 else 355 renderImageResource->setImageResource(imageLoader().image());
345 renderImageResource->setImageResource(imageLoader().image());
346
347 } 356 }
348 } 357 }
349 358
350 Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode* insertionPoint) 359 Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode* insertionPoint)
351 { 360 {
352 if (!m_formWasSetByParser || NodeTraversal::highestAncestorOrSelf(*insertion Point) != NodeTraversal::highestAncestorOrSelf(*m_form.get())) 361 if (!m_formWasSetByParser || NodeTraversal::highestAncestorOrSelf(*insertion Point) != NodeTraversal::highestAncestorOrSelf(*m_form.get()))
353 resetFormOwner(); 362 resetFormOwner();
354 if (m_listener) 363 if (m_listener)
355 document().mediaQueryMatcher().addViewportListener(m_listener); 364 document().mediaQueryMatcher().addViewportListener(m_listener);
356 365
357 bool imageWasModified = false; 366 bool imageWasModified = false;
358 if (RuntimeEnabledFeatures::pictureEnabled() && document().isActive()) { 367 if (RuntimeEnabledFeatures::pictureEnabled() && document().isActive()) {
359 ImageCandidate candidate = findBestFitImageFromPictureParent(); 368 ImageCandidate candidate = findBestFitImageFromPictureParent();
360 if (!candidate.isEmpty()) { 369 if (!candidate.isEmpty()) {
361 setBestFitURLAndDPRFromImageCandidate(candidate); 370 setBestFitURLAndDPRFromImageCandidate(candidate);
362 imageWasModified = true; 371 imageWasModified = true;
363 } 372 }
364 } 373 }
365 374
366 // If we have been inserted from a renderer-less document, 375 // If we have been inserted from a renderer-less document,
367 // our loader may have not fetched the image, so do it now. 376 // our loader may have not fetched the image, so do it now.
368 if ((insertionPoint->inDocument() && !imageLoader().image()) || imageWasModi fied) 377 if ((insertionPoint->inDocument() && !imageLoader().image()) || imageWasModi fied)
369 imageLoader().updateFromElement(ImageLoader::UpdateNormal, m_elementCrea tedByParser ? ImageLoader::ForceLoadImmediately : ImageLoader::LoadNormally); 378 imageLoader().updateFromElement(ImageLoader::UpdateNormal);
370 379
371 return HTMLElement::insertedInto(insertionPoint); 380 return HTMLElement::insertedInto(insertionPoint);
372 } 381 }
373 382
374 void HTMLImageElement::removedFrom(ContainerNode* insertionPoint) 383 void HTMLImageElement::removedFrom(ContainerNode* insertionPoint)
375 { 384 {
376 if (!m_form || NodeTraversal::highestAncestorOrSelf(*m_form.get()) != NodeTr aversal::highestAncestorOrSelf(*this)) 385 if (!m_form || NodeTraversal::highestAncestorOrSelf(*m_form.get()) != NodeTr aversal::highestAncestorOrSelf(*this))
377 resetFormOwner(); 386 resetFormOwner();
378 if (m_listener) 387 if (m_listener)
379 document().mediaQueryMatcher().removeViewportListener(m_listener); 388 document().mediaQueryMatcher().removeViewportListener(m_listener);
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 effectiveSize = parser.length(); 647 effectiveSize = parser.length();
639 } 648 }
640 ImageCandidate candidate = bestFitSourceForImageAttributes(document().de vicePixelRatio(), effectiveSize, fastGetAttribute(srcAttr), fastGetAttribute(src setAttr), &document()); 649 ImageCandidate candidate = bestFitSourceForImageAttributes(document().de vicePixelRatio(), effectiveSize, fastGetAttribute(srcAttr), fastGetAttribute(src setAttr), &document());
641 setBestFitURLAndDPRFromImageCandidate(candidate); 650 setBestFitURLAndDPRFromImageCandidate(candidate);
642 } 651 }
643 if (m_intrinsicSizingViewportDependant && !m_listener) { 652 if (m_intrinsicSizingViewportDependant && !m_listener) {
644 m_listener = ViewportChangeListener::create(this); 653 m_listener = ViewportChangeListener::create(this);
645 document().mediaQueryMatcher().addViewportListener(m_listener); 654 document().mediaQueryMatcher().addViewportListener(m_listener);
646 } 655 }
647 imageLoader().updateFromElement(behavior); 656 imageLoader().updateFromElement(behavior);
657
658 if (imageLoader().image() || (imageLoader().hasPendingActivity() && !imageSo urceURL().isEmpty()))
659 ensurePrimaryContent();
660 else
661 ensureFallbackContent();
648 } 662 }
649 663
650 const KURL& HTMLImageElement::sourceURL() const 664 const KURL& HTMLImageElement::sourceURL() const
651 { 665 {
652 return cachedImage()->response().url(); 666 return cachedImage()->response().url();
653 } 667 }
654 668
669 void HTMLImageElement::didAddUserAgentShadowRoot(ShadowRoot&)
670 {
671 HTMLImageFallbackHelper::createAltTextShadowTree(*this);
655 } 672 }
673
674 void HTMLImageElement::ensureFallbackContent()
675 {
676 if (m_useFallbackContent || m_isFallbackImage)
677 return;
678 setUseFallbackContent();
679 reattachFallbackContent();
680 }
681
682 void HTMLImageElement::ensurePrimaryContent()
683 {
684 if (!m_useFallbackContent)
685 return;
686 m_useFallbackContent = false;
687 reattachFallbackContent();
688 }
689
690 void HTMLImageElement::reattachFallbackContent()
691 {
692 // This can happen inside of attach() in the middle of a recalcStyle so we n eed to
693 // reattach synchronously here.
694 if (document().inStyleRecalc())
695 reattach();
696 else
697 lazyReattachIfAttached();
698 }
699
700 PassRefPtr<RenderStyle> HTMLImageElement::customStyleForRenderer()
701 {
702 RefPtr<RenderStyle> newStyle = originalStyleForRenderer();
703
704 if (!m_useFallbackContent)
705 return newStyle;
706 return HTMLImageFallbackHelper::customStyleForAltText(*this, newStyle);
707 }
708
709 void HTMLImageElement::setUseFallbackContent()
710 {
711 m_useFallbackContent = true;
712 if (document().inStyleRecalc())
713 return;
714 ensureUserAgentShadowRoot();
715 }
716 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698