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

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLImageFallbackHelper.cpp

Issue 2593263003: Use a non-replaced inline container for image alt text (Closed)
Patch Set: bug 644802 Created 3 years, 9 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/html/HTMLImageFallbackHelper.h" 5 #include "core/html/HTMLImageFallbackHelper.h"
6 6
7 #include "core/HTMLNames.h" 7 #include "core/HTMLNames.h"
8 #include "core/InputTypeNames.h" 8 #include "core/InputTypeNames.h"
9 #include "core/dom/ElementRareData.h" 9 #include "core/dom/ElementRareData.h"
10 #include "core/dom/Text.h" 10 #include "core/dom/Text.h"
11 #include "core/dom/shadow/ShadowRoot.h" 11 #include "core/dom/shadow/ShadowRoot.h"
12 #include "core/html/HTMLDivElement.h"
13 #include "core/html/HTMLElement.h" 12 #include "core/html/HTMLElement.h"
14 #include "core/html/HTMLImageElement.h" 13 #include "core/html/HTMLImageElement.h"
15 #include "core/html/HTMLImageLoader.h" 14 #include "core/html/HTMLImageLoader.h"
16 #include "core/html/HTMLInputElement.h" 15 #include "core/html/HTMLInputElement.h"
16 #include "core/html/HTMLSpanElement.h"
17 #include "core/html/HTMLStyleElement.h" 17 #include "core/html/HTMLStyleElement.h"
18 #include "wtf/text/StringBuilder.h" 18 #include "wtf/text/StringBuilder.h"
19 19
20 namespace blink { 20 namespace blink {
21 21
22 using namespace HTMLNames; 22 using namespace HTMLNames;
23 23
24 static bool noImageSourceSpecified(const Element& element) { 24 static bool imageSmallerThanAltImage(int pixelsForAltImage,
25 bool noSrcSpecified = !element.hasAttribute(srcAttr) || 25 const Length width,
26 element.getAttribute(srcAttr).isNull() || 26 const Length height) {
27 element.getAttribute(srcAttr).isEmpty(); 27 // We don't have a layout tree so can't compute the size of an image
28 bool noSrcsetSpecified = !element.hasAttribute(srcsetAttr) || 28 // relative dimensions - so we just assume we should display the alt image.
29 element.getAttribute(srcsetAttr).isNull() || 29 if (!width.isFixed() && !height.isFixed())
30 element.getAttribute(srcsetAttr).isEmpty(); 30 return false;
31 return noSrcSpecified && noSrcsetSpecified; 31 if (height.isFixed())
32 return height.value() < pixelsForAltImage;
33 return width.value() < pixelsForAltImage;
32 } 34 }
33 35
34 void HTMLImageFallbackHelper::createAltTextShadowTree(Element& element) { 36 void HTMLImageFallbackHelper::createAltTextShadowTree(Element& element) {
35 ShadowRoot& root = element.ensureUserAgentShadowRoot(); 37 ShadowRoot& root = element.ensureUserAgentShadowRoot();
36 38
37 HTMLDivElement* container = HTMLDivElement::create(element.document()); 39 HTMLSpanElement* container = HTMLSpanElement::create(element.document());
38 root.appendChild(container); 40 root.appendChild(container);
39 container->setAttribute(idAttr, AtomicString("alttext-container")); 41 container->setAttribute(idAttr, AtomicString("alttext-container"));
40 container->setInlineStyleProperty(CSSPropertyOverflow, CSSValueHidden);
41 container->setInlineStyleProperty(CSSPropertyBorderWidth, 1,
42 CSSPrimitiveValue::UnitType::Pixels);
43 container->setInlineStyleProperty(CSSPropertyBorderStyle, CSSValueSolid);
44 container->setInlineStyleProperty(CSSPropertyBorderColor, CSSValueSilver);
45 container->setInlineStyleProperty(CSSPropertyDisplay, CSSValueInlineBlock);
46 container->setInlineStyleProperty(CSSPropertyBoxSizing, CSSValueBorderBox);
47 container->setInlineStyleProperty(CSSPropertyPadding, 1,
48 CSSPrimitiveValue::UnitType::Pixels);
49 42
50 HTMLImageElement* brokenImage = HTMLImageElement::create(element.document()); 43 HTMLImageElement* brokenImage = HTMLImageElement::create(element.document());
51 container->appendChild(brokenImage); 44 container->appendChild(brokenImage);
52 brokenImage->setIsFallbackImage(); 45 brokenImage->setIsFallbackImage();
53 brokenImage->setAttribute(idAttr, AtomicString("alttext-image")); 46 brokenImage->setAttribute(idAttr, AtomicString("alttext-image"));
54 brokenImage->setAttribute(widthAttr, AtomicString("16")); 47 brokenImage->setAttribute(widthAttr, AtomicString("16"));
55 brokenImage->setAttribute(heightAttr, AtomicString("16")); 48 brokenImage->setAttribute(heightAttr, AtomicString("16"));
56 brokenImage->setAttribute(alignAttr, AtomicString("left")); 49 brokenImage->setAttribute(alignAttr, AtomicString("left"));
57 brokenImage->setInlineStyleProperty(CSSPropertyMargin, 0, 50 brokenImage->setInlineStyleProperty(CSSPropertyMargin, 0,
58 CSSPrimitiveValue::UnitType::Pixels); 51 CSSPrimitiveValue::UnitType::Pixels);
59 52
60 HTMLDivElement* altText = HTMLDivElement::create(element.document()); 53 HTMLSpanElement* altText = HTMLSpanElement::create(element.document());
61 container->appendChild(altText); 54 container->appendChild(altText);
62 altText->setAttribute(idAttr, AtomicString("alttext")); 55 altText->setAttribute(idAttr, AtomicString("alttext"));
63 altText->setInlineStyleProperty(CSSPropertyOverflow, CSSValueHidden);
pdr. 2017/03/24 02:12:50 The change to LayoutTests/tables/mozilla_expected_
64 altText->setInlineStyleProperty(CSSPropertyDisplay, CSSValueBlock);
65 56
66 Text* text = 57 Text* text =
67 Text::create(element.document(), toHTMLElement(element).altText()); 58 Text::create(element.document(), toHTMLElement(element).altText());
68 altText->appendChild(text); 59 altText->appendChild(text);
69 } 60 }
70 61
71 PassRefPtr<ComputedStyle> HTMLImageFallbackHelper::customStyleForAltText( 62 PassRefPtr<ComputedStyle> HTMLImageFallbackHelper::customStyleForAltText(
72 Element& element, 63 Element& element,
73 PassRefPtr<ComputedStyle> newStyle) { 64 PassRefPtr<ComputedStyle> newStyle) {
74 // If we have an author shadow root or have not created the UA shadow root 65 // If we have an author shadow root or have not created the UA shadow root
(...skipping 20 matching lines...) Expand all
95 else if (newStyle->height().isSpecifiedOrIntrinsic() && 86 else if (newStyle->height().isSpecifiedOrIntrinsic() &&
96 newStyle->width().isAuto()) 87 newStyle->width().isAuto())
97 newStyle->setWidth(newStyle->height()); 88 newStyle->setWidth(newStyle->height());
98 if (newStyle->width().isSpecifiedOrIntrinsic() && 89 if (newStyle->width().isSpecifiedOrIntrinsic() &&
99 newStyle->height().isSpecifiedOrIntrinsic()) { 90 newStyle->height().isSpecifiedOrIntrinsic()) {
100 placeHolder->setInlineStyleProperty(CSSPropertyVerticalAlign, 91 placeHolder->setInlineStyleProperty(CSSPropertyVerticalAlign,
101 CSSValueBaseline); 92 CSSValueBaseline);
102 } 93 }
103 } 94 }
104 95
105 // If the image has specified dimensions allow the alt-text container expand 96 bool imageHasIntrinsicDimensions =
106 // to fill them. 97 newStyle->width().isSpecifiedOrIntrinsic() &&
107 if (newStyle->width().isSpecifiedOrIntrinsic() && 98 newStyle->height().isSpecifiedOrIntrinsic();
108 newStyle->height().isSpecifiedOrIntrinsic()) { 99 bool imageHasNoAltAttribute = toHTMLElement(element).altText().isNull();
109 placeHolder->setInlineStyleProperty( 100 bool treatAsReplaced =
110 CSSPropertyWidth, 100, CSSPrimitiveValue::UnitType::Percentage); 101 imageHasIntrinsicDimensions &&
111 placeHolder->setInlineStyleProperty( 102 (element.document().inQuirksMode() || imageHasNoAltAttribute);
112 CSSPropertyHeight, 100, CSSPrimitiveValue::UnitType::Percentage); 103 // 16px for the image and 2px for its border/padding offset.
104 int pixelsForAltImage = 18;
pdr. 2017/03/24 02:15:45 Should this be 1 + 1 + 16 + 1 + 1 = 20 to account
105 if (treatAsReplaced &&
106 !imageSmallerThanAltImage(pixelsForAltImage, newStyle->width(),
107 newStyle->height())) {
108 // https://html.spec.whatwg.org/multipage/rendering.html#images-3:
109 // "If the element does not represent an image, but the element already has
110 // intrinsic dimensions (e.g. from the dimension attributes or CSS rules),
111 // and either: the user agent has reason to believe that the image will
112 // become available and be rendered in due course, or the element has no alt
113 // attribute, or the Document is in quirks mode The user agent is expected
114 // to treat the element as a replaced element whose content is the text that
115 // the element represents, if any."
116 placeHolder->setInlineStyleProperty(CSSPropertyDisplay,
117 CSSValueInlineBlock);
118 placeHolder->setInlineStyleProperty(CSSPropertyBorderWidth, 1,
119 CSSPrimitiveValue::UnitType::Pixels);
120 placeHolder->setInlineStyleProperty(CSSPropertyBorderStyle, CSSValueSolid);
121 placeHolder->setInlineStyleProperty(CSSPropertyBorderColor, CSSValueSilver);
122 placeHolder->setInlineStyleProperty(CSSPropertyPadding, 1,
123 CSSPrimitiveValue::UnitType::Pixels);
124 placeHolder->setInlineStyleProperty(CSSPropertyBoxSizing,
125 CSSValueBorderBox);
126 CSSPrimitiveValue::UnitType unit =
127 newStyle->height().isPercent() ? CSSPrimitiveValue::UnitType::Percentage
128 : CSSPrimitiveValue::UnitType::Pixels;
129 placeHolder->setInlineStyleProperty(CSSPropertyHeight,
130 newStyle->height().value(), unit);
131 placeHolder->setInlineStyleProperty(CSSPropertyWidth,
132 newStyle->width().value(), unit);
133 brokenImage->setInlineStyleProperty(CSSPropertyDisplay, CSSValueInline);
134 // Make sure the broken image icon appears on the appropriate side of the
135 // image for the element's writing direction.
136 brokenImage->setInlineStyleProperty(
137 CSSPropertyFloat,
138 AtomicString(newStyle->direction() == TextDirection::kLtr ? "left"
139 : "right"));
140 } else {
141 // "If the element is an img element that represents nothing and the user
142 // agent does not expect this to change the user agent is expected to treat
143 // the element as an empty inline element."
144 // - We achieve this by hiding the broken image so that the span is empty.
145 // "If the element is an img element that represents some text and the user
146 // agent does not expect this to change the user agent is expected to treat
147 // the element as a non-replaced phrasing element whose content is the text,
148 // optionally with an icon indicating that an image is missing, so that the
149 // user can request the image be displayed or investigate why it is not
150 // rendering."
151 // - We opt not to display an icon, like Firefox.
152 if (!treatAsReplaced && newStyle->display() == EDisplay::kInline) {
153 newStyle->setWidth(Length());
154 newStyle->setHeight(Length());
pdr. 2017/03/24 02:12:49 In tables/mozilla/bugs/bug56201.html it looks like
155 }
156 brokenImage->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
113 } 157 }
114 158
115 // Make sure the broken image icon appears on the appropriate side of the
116 // image for the element's writing direction.
117 brokenImage->setInlineStyleProperty(
118 CSSPropertyFloat,
119 AtomicString(newStyle->direction() == TextDirection::kLtr ? "left"
120 : "right"));
121
122 // This is an <img> with no attributes, so don't display anything.
123 if (noImageSourceSpecified(element) &&
124 !newStyle->width().isSpecifiedOrIntrinsic() &&
125 !newStyle->height().isSpecifiedOrIntrinsic() &&
126 toHTMLElement(element).altText().isEmpty())
127 newStyle->setDisplay(EDisplay::kNone);
128
129 // This preserves legacy behaviour originally defined when alt-text was
130 // managed by LayoutImage.
131 if (noImageSourceSpecified(element))
132 brokenImage->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
133 else
134 brokenImage->setInlineStyleProperty(CSSPropertyDisplay, CSSValueInline);
135
136 return newStyle; 159 return newStyle;
137 } 160 }
138 161
139 } // namespace blink 162 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698