| Index: third_party/WebKit/Source/core/html/HTMLImageFallbackHelper.cpp
|
| diff --git a/third_party/WebKit/Source/core/html/HTMLImageFallbackHelper.cpp b/third_party/WebKit/Source/core/html/HTMLImageFallbackHelper.cpp
|
| index 3c1223c6a28e30c2fcd394c988b6f26892aad0e2..2f7e825015e7cd93d8ddf2262b57e9998daa2c51 100644
|
| --- a/third_party/WebKit/Source/core/html/HTMLImageFallbackHelper.cpp
|
| +++ b/third_party/WebKit/Source/core/html/HTMLImageFallbackHelper.cpp
|
| @@ -9,11 +9,11 @@
|
| #include "core/dom/ElementRareData.h"
|
| #include "core/dom/Text.h"
|
| #include "core/dom/shadow/ShadowRoot.h"
|
| -#include "core/html/HTMLDivElement.h"
|
| #include "core/html/HTMLElement.h"
|
| #include "core/html/HTMLImageElement.h"
|
| #include "core/html/HTMLImageLoader.h"
|
| #include "core/html/HTMLInputElement.h"
|
| +#include "core/html/HTMLSpanElement.h"
|
| #include "core/html/HTMLStyleElement.h"
|
| #include "platform/wtf/text/StringBuilder.h"
|
|
|
| @@ -21,31 +21,24 @@ namespace blink {
|
|
|
| using namespace HTMLNames;
|
|
|
| -static bool NoImageSourceSpecified(const Element& element) {
|
| - bool no_src_specified = !element.hasAttribute(srcAttr) ||
|
| - element.getAttribute(srcAttr).IsNull() ||
|
| - element.getAttribute(srcAttr).IsEmpty();
|
| - bool no_srcset_specified = !element.hasAttribute(srcsetAttr) ||
|
| - element.getAttribute(srcsetAttr).IsNull() ||
|
| - element.getAttribute(srcsetAttr).IsEmpty();
|
| - return no_src_specified && no_srcset_specified;
|
| +static bool ImageSmallerThanAltImage(int pixels_for_alt_image,
|
| + const Length width,
|
| + const Length height) {
|
| + // We don't have a layout tree so can't compute the size of an image
|
| + // relative dimensions - so we just assume we should display the alt image.
|
| + if (!width.IsFixed() && !height.IsFixed())
|
| + return false;
|
| + if (height.IsFixed() && height.Value() < pixels_for_alt_image)
|
| + return true;
|
| + return width.IsFixed() && width.Value() < pixels_for_alt_image;
|
| }
|
|
|
| void HTMLImageFallbackHelper::CreateAltTextShadowTree(Element& element) {
|
| ShadowRoot& root = element.EnsureUserAgentShadowRoot();
|
|
|
| - HTMLDivElement* container = HTMLDivElement::Create(element.GetDocument());
|
| + HTMLSpanElement* container = HTMLSpanElement::Create(element.GetDocument());
|
| root.AppendChild(container);
|
| container->setAttribute(idAttr, AtomicString("alttext-container"));
|
| - container->SetInlineStyleProperty(CSSPropertyOverflow, CSSValueHidden);
|
| - container->SetInlineStyleProperty(CSSPropertyBorderWidth, 1,
|
| - CSSPrimitiveValue::UnitType::kPixels);
|
| - container->SetInlineStyleProperty(CSSPropertyBorderStyle, CSSValueSolid);
|
| - container->SetInlineStyleProperty(CSSPropertyBorderColor, CSSValueSilver);
|
| - container->SetInlineStyleProperty(CSSPropertyDisplay, CSSValueInlineBlock);
|
| - container->SetInlineStyleProperty(CSSPropertyBoxSizing, CSSValueBorderBox);
|
| - container->SetInlineStyleProperty(CSSPropertyPadding, 1,
|
| - CSSPrimitiveValue::UnitType::kPixels);
|
|
|
| HTMLImageElement* broken_image =
|
| HTMLImageElement::Create(element.GetDocument());
|
| @@ -58,11 +51,9 @@ void HTMLImageFallbackHelper::CreateAltTextShadowTree(Element& element) {
|
| broken_image->SetInlineStyleProperty(CSSPropertyMargin, 0,
|
| CSSPrimitiveValue::UnitType::kPixels);
|
|
|
| - HTMLDivElement* alt_text = HTMLDivElement::Create(element.GetDocument());
|
| + HTMLSpanElement* alt_text = HTMLSpanElement::Create(element.GetDocument());
|
| container->AppendChild(alt_text);
|
| alt_text->setAttribute(idAttr, AtomicString("alttext"));
|
| - alt_text->SetInlineStyleProperty(CSSPropertyOverflow, CSSValueHidden);
|
| - alt_text->SetInlineStyleProperty(CSSPropertyDisplay, CSSValueBlock);
|
|
|
| Text* text =
|
| Text::Create(element.GetDocument(), ToHTMLElement(element).AltText());
|
| @@ -103,36 +94,71 @@ PassRefPtr<ComputedStyle> HTMLImageFallbackHelper::CustomStyleForAltText(
|
| }
|
| }
|
|
|
| - // If the image has specified dimensions allow the alt-text container expand
|
| - // to fill them.
|
| - if (new_style->Width().IsSpecifiedOrIntrinsic() &&
|
| - new_style->Height().IsSpecifiedOrIntrinsic()) {
|
| - place_holder->SetInlineStyleProperty(
|
| - CSSPropertyWidth, 100, CSSPrimitiveValue::UnitType::kPercentage);
|
| - place_holder->SetInlineStyleProperty(
|
| - CSSPropertyHeight, 100, CSSPrimitiveValue::UnitType::kPercentage);
|
| - }
|
| -
|
| - // Make sure the broken image icon appears on the appropriate side of the
|
| - // image for the element's writing direction.
|
| - broken_image->SetInlineStyleProperty(
|
| - CSSPropertyFloat,
|
| - AtomicString(new_style->Direction() == TextDirection::kLtr ? "left"
|
| - : "right"));
|
| -
|
| - // This is an <img> with no attributes, so don't display anything.
|
| - if (NoImageSourceSpecified(element) &&
|
| - !new_style->Width().IsSpecifiedOrIntrinsic() &&
|
| - !new_style->Height().IsSpecifiedOrIntrinsic() &&
|
| - ToHTMLElement(element).AltText().IsEmpty())
|
| - new_style->SetDisplay(EDisplay::kNone);
|
| -
|
| - // This preserves legacy behaviour originally defined when alt-text was
|
| - // managed by LayoutImage.
|
| - if (NoImageSourceSpecified(element))
|
| - broken_image->SetInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
|
| - else
|
| + bool image_has_intrinsic_dimensions =
|
| + new_style->Width().IsSpecifiedOrIntrinsic() &&
|
| + new_style->Height().IsSpecifiedOrIntrinsic();
|
| + bool image_has_no_alt_attribute = ToHTMLElement(element).AltText().IsNull();
|
| + bool treat_as_replaced =
|
| + image_has_intrinsic_dimensions &&
|
| + (element.GetDocument().InQuirksMode() || image_has_no_alt_attribute);
|
| + // 16px for the image and 2px for its top/left border/padding offset.
|
| + int pixels_for_alt_image = 18;
|
| + if (treat_as_replaced &&
|
| + !ImageSmallerThanAltImage(pixels_for_alt_image, new_style->Width(),
|
| + new_style->Height())) {
|
| + // https://html.spec.whatwg.org/multipage/rendering.html#images-3:
|
| + // "If the element does not represent an image, but the element already has
|
| + // intrinsic dimensions (e.g. from the dimension attributes or CSS rules),
|
| + // and either: the user agent has reason to believe that the image will
|
| + // become available and be rendered in due course, or the element has no alt
|
| + // attribute, or the Document is in quirks mode The user agent is expected
|
| + // to treat the element as a replaced element whose content is the text that
|
| + // the element represents, if any."
|
| + place_holder->SetInlineStyleProperty(CSSPropertyOverflow, CSSValueHidden);
|
| + place_holder->SetInlineStyleProperty(CSSPropertyDisplay,
|
| + CSSValueInlineBlock);
|
| + place_holder->SetInlineStyleProperty(CSSPropertyBorderWidth, 1,
|
| + CSSPrimitiveValue::UnitType::kPixels);
|
| + place_holder->SetInlineStyleProperty(CSSPropertyBorderStyle, CSSValueSolid);
|
| + place_holder->SetInlineStyleProperty(CSSPropertyBorderColor,
|
| + CSSValueSilver);
|
| + place_holder->SetInlineStyleProperty(CSSPropertyPadding, 1,
|
| + CSSPrimitiveValue::UnitType::kPixels);
|
| + place_holder->SetInlineStyleProperty(CSSPropertyBoxSizing,
|
| + CSSValueBorderBox);
|
| + CSSPrimitiveValue::UnitType unit =
|
| + new_style->Height().IsPercent()
|
| + ? CSSPrimitiveValue::UnitType::kPercentage
|
| + : CSSPrimitiveValue::UnitType::kPixels;
|
| + place_holder->SetInlineStyleProperty(CSSPropertyHeight,
|
| + new_style->Height().Value(), unit);
|
| + place_holder->SetInlineStyleProperty(CSSPropertyWidth,
|
| + new_style->Width().Value(), unit);
|
| broken_image->SetInlineStyleProperty(CSSPropertyDisplay, CSSValueInline);
|
| + // Make sure the broken image icon appears on the appropriate side of the
|
| + // image for the element's writing direction.
|
| + broken_image->SetInlineStyleProperty(
|
| + CSSPropertyFloat,
|
| + AtomicString(new_style->Direction() == TextDirection::kLtr ? "left"
|
| + : "right"));
|
| + } else {
|
| + // "If the element is an img element that represents nothing and the user
|
| + // agent does not expect this to change the user agent is expected to treat
|
| + // the element as an empty inline element."
|
| + // - We achieve this by hiding the broken image so that the span is empty.
|
| + // "If the element is an img element that represents some text and the user
|
| + // agent does not expect this to change the user agent is expected to treat
|
| + // the element as a non-replaced phrasing element whose content is the text,
|
| + // optionally with an icon indicating that an image is missing, so that the
|
| + // user can request the image be displayed or investigate why it is not
|
| + // rendering."
|
| + // - We opt not to display an icon, like Firefox.
|
| + if (!treat_as_replaced && new_style->Display() == EDisplay::kInline) {
|
| + new_style->SetWidth(Length());
|
| + new_style->SetHeight(Length());
|
| + }
|
| + broken_image->SetInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
|
| + }
|
|
|
| return new_style;
|
| }
|
|
|