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

Unified Diff: third_party/WebKit/Source/core/html/HTMLImageFallbackHelper.cpp

Issue 2593263003: Use a non-replaced inline container for image alt text (Closed)
Patch Set: Use a non-replaced inline container for image alt text Created 3 years, 8 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 side-by-side diff with in-line comments
Download patch
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;
}

Powered by Google App Engine
This is Rietveld 408576698