Index: Source/core/html/HTMLImageElement.cpp |
diff --git a/Source/core/html/HTMLImageElement.cpp b/Source/core/html/HTMLImageElement.cpp |
index 11dbf5900f5bfb702b0ce14706a5d21970ab80a1..92c21f2dfee2a94af57fc5615c02fe47657c1bbf 100644 |
--- a/Source/core/html/HTMLImageElement.cpp |
+++ b/Source/core/html/HTMLImageElement.cpp |
@@ -37,11 +37,13 @@ |
#include "core/html/HTMLAnchorElement.h" |
#include "core/html/HTMLCanvasElement.h" |
#include "core/html/HTMLFormElement.h" |
+#include "core/html/HTMLImageFallbackHelper.h" |
#include "core/html/HTMLSourceElement.h" |
#include "core/html/canvas/CanvasRenderingContext.h" |
#include "core/html/parser/HTMLParserIdioms.h" |
#include "core/html/parser/HTMLSrcsetParser.h" |
#include "core/inspector/ConsoleMessage.h" |
+#include "core/rendering/RenderBlockFlow.h" |
#include "core/rendering/RenderImage.h" |
#include "platform/MIMETypeRegistry.h" |
#include "platform/RuntimeEnabledFeatures.h" |
@@ -79,14 +81,18 @@ private: |
HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form, bool createdByParser) |
: HTMLElement(imgTag, document) |
, m_imageLoader(HTMLImageLoader::create(this)) |
+ , m_altTextNode(0) |
, m_compositeOperator(CompositeSourceOver) |
, m_imageDevicePixelRatio(1.0f) |
, m_formWasSetByParser(false) |
, m_elementCreatedByParser(createdByParser) |
, m_intrinsicSizingViewportDependant(false) |
, m_effectiveSizeViewportDependant(false) |
+ , m_useFallbackContent(false) |
+ , m_isFallbackImage(false) |
{ |
ScriptWrappable::init(this); |
+ setHasCustomStyleCallbacks(); |
if (form && form->inDocument()) { |
#if ENABLE(OILPAN) |
m_form = form; |
@@ -237,9 +243,12 @@ void HTMLImageElement::setBestFitURLAndDPRFromImageCandidate(const ImageCandidat |
void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicString& value) |
{ |
- if (name == altAttr) { |
- if (renderer() && renderer()->isImage()) |
- toRenderImage(renderer())->updateAltText(); |
+ if (name == altAttr || name == titleAttr) { |
+ if (Text* text = altTextNode()) { |
+ String alt = altText(); |
+ if (text->data() != alt) |
+ text->setData(alt); |
+ } |
} else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) { |
selectSourceURL(ImageLoader::UpdateIgnorePreviousError); |
} else if (name == usemapAttr) { |
@@ -255,7 +264,7 @@ void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr |
} |
} |
-const AtomicString& HTMLImageElement::altText() const |
+String HTMLImageElement::altText() const |
{ |
// lets figure out the alt text.. magic stuff |
// http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen |
@@ -318,6 +327,9 @@ RenderObject* HTMLImageElement::createRenderer(RenderStyle* style) |
if (style->hasContent()) |
return RenderObject::createObject(this, style); |
+ if (m_useFallbackContent) |
+ return new RenderBlockFlow(this); |
+ |
RenderImage* image = new RenderImage(this); |
image->setImageResource(RenderImageResource::create()); |
image->setImageDevicePixelRatio(m_imageDevicePixelRatio); |
@@ -342,13 +354,9 @@ void HTMLImageElement::attach(const AttachContext& context) |
if (renderImageResource->hasImage()) |
return; |
- // If we have no image at all because we have no src attribute, set |
- // image height and width for the alt text instead. |
if (!imageLoader().image() && !renderImageResource->cachedImage()) |
- renderImage->setImageSizeForAltText(); |
- else |
- renderImageResource->setImageResource(imageLoader().image()); |
- |
+ return; |
+ renderImageResource->setImageResource(imageLoader().image()); |
} |
} |
@@ -648,6 +656,11 @@ void HTMLImageElement::selectSourceURL(ImageLoader::UpdateFromElementBehavior be |
document().mediaQueryMatcher().addViewportListener(m_listener); |
} |
imageLoader().updateFromElement(behavior); |
+ |
+ if (imageLoader().image() || (imageLoader().hasPendingActivity() && !imageSourceURL().isEmpty())) |
+ ensurePrimaryContent(); |
+ else |
+ ensureFallbackContent(); |
} |
const KURL& HTMLImageElement::sourceURL() const |
@@ -655,4 +668,43 @@ const KURL& HTMLImageElement::sourceURL() const |
return cachedImage()->response().url(); |
} |
+void HTMLImageElement::didAddUserAgentShadowRoot(ShadowRoot&) |
+{ |
+ m_altTextNode = createAltTextShadowTree(*this); |
+} |
+ |
+void HTMLImageElement::ensureFallbackContent() |
+{ |
+ if (m_useFallbackContent || m_isFallbackImage) |
+ return; |
+ setUseFallbackContent(); |
+ reattachFallbackContent(); |
+} |
+ |
+void HTMLImageElement::ensurePrimaryContent() |
+{ |
+ if (!m_useFallbackContent) |
+ return; |
+ m_useFallbackContent = false; |
+ reattachFallbackContent(); |
+} |
+ |
+void HTMLImageElement::reattachFallbackContent() |
+{ |
+ // This can happen inside of attach() in the middle of a recalcStyle so we need to |
+ // reattach synchronously here. |
+ if (document().inStyleRecalc()) |
+ reattach(); |
+ else |
+ lazyReattachIfAttached(); |
+} |
+ |
+PassRefPtr<RenderStyle> HTMLImageElement::customStyleForRenderer() |
+{ |
+ RefPtr<RenderStyle> newStyle = originalStyleForRenderer(); |
+ |
+ if (!m_useFallbackContent) |
+ return newStyle; |
+ return customStyleForAltText(*this, newStyle); |
+} |
} |