Bug 1880216 - Migrate Fenix docs into Sphinx. r=owlish,geckoview-reviewers,android...
[gecko.git] / dom / html / HTMLHRElement.cpp
blobe433478a872253ef319e69483c3dae6d8c807cbb
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/HTMLHRElement.h"
8 #include "mozilla/dom/HTMLHRElementBinding.h"
10 #include "nsCSSProps.h"
11 #include "nsStyleConsts.h"
12 #include "mozilla/MappedDeclarationsBuilder.h"
14 NS_IMPL_NS_NEW_HTML_ELEMENT(HR)
16 namespace mozilla::dom {
18 HTMLHRElement::HTMLHRElement(
19 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
20 : nsGenericHTMLElement(std::move(aNodeInfo)) {}
22 HTMLHRElement::~HTMLHRElement() = default;
24 NS_IMPL_ELEMENT_CLONE(HTMLHRElement)
26 bool HTMLHRElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
27 const nsAString& aValue,
28 nsIPrincipal* aMaybeScriptedPrincipal,
29 nsAttrValue& aResult) {
30 static const nsAttrValue::EnumTable kAlignTable[] = {
31 {"left", StyleTextAlign::Left},
32 {"right", StyleTextAlign::Right},
33 {"center", StyleTextAlign::Center},
34 {nullptr, 0}};
36 if (aNamespaceID == kNameSpaceID_None) {
37 if (aAttribute == nsGkAtoms::width) {
38 return aResult.ParseHTMLDimension(aValue);
40 if (aAttribute == nsGkAtoms::size) {
41 return aResult.ParseIntWithBounds(aValue, 1, 1000);
43 if (aAttribute == nsGkAtoms::align) {
44 return aResult.ParseEnumValue(aValue, kAlignTable, false);
46 if (aAttribute == nsGkAtoms::color) {
47 return aResult.ParseColor(aValue);
51 return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
52 aMaybeScriptedPrincipal, aResult);
55 void HTMLHRElement::MapAttributesIntoRule(MappedDeclarationsBuilder& aBuilder) {
56 bool noshade = false;
58 const nsAttrValue* colorValue = aBuilder.GetAttr(nsGkAtoms::color);
59 nscolor color;
60 bool colorIsSet = colorValue && colorValue->GetColorValue(color);
62 if (colorIsSet) {
63 noshade = true;
64 } else {
65 noshade = !!aBuilder.GetAttr(nsGkAtoms::noshade);
68 // align: enum
69 const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::align);
70 if (value && value->Type() == nsAttrValue::eEnum) {
71 // Map align attribute into auto side margins
72 switch (StyleTextAlign(value->GetEnumValue())) {
73 case StyleTextAlign::Left:
74 aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_left, 0.0f);
75 aBuilder.SetAutoValueIfUnset(eCSSProperty_margin_right);
76 break;
77 case StyleTextAlign::Right:
78 aBuilder.SetAutoValueIfUnset(eCSSProperty_margin_left);
79 aBuilder.SetPixelValueIfUnset(eCSSProperty_margin_right, 0.0f);
80 break;
81 case StyleTextAlign::Center:
82 aBuilder.SetAutoValueIfUnset(eCSSProperty_margin_left);
83 aBuilder.SetAutoValueIfUnset(eCSSProperty_margin_right);
84 break;
85 default:
86 MOZ_ASSERT_UNREACHABLE("Unknown <hr align> value");
87 break;
90 if (!aBuilder.PropertyIsSet(eCSSProperty_height)) {
91 // size: integer
92 if (noshade) {
93 // noshade case: size is set using the border
94 aBuilder.SetAutoValue(eCSSProperty_height);
95 } else {
96 // normal case
97 // the height includes the top and bottom borders that are initially 1px.
98 // for size=1, html.css has a special case rule that makes this work by
99 // removing all but the top border.
100 const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::size);
101 if (value && value->Type() == nsAttrValue::eInteger) {
102 aBuilder.SetPixelValue(eCSSProperty_height,
103 (float)value->GetIntegerValue());
104 } // else use default value from html.css
108 // if not noshade, border styles are dealt with by html.css
109 if (noshade) {
110 // size: integer
111 // if a size is set, use half of it per side, otherwise, use 1px per side
112 float sizePerSide;
113 bool allSides = true;
114 value = aBuilder.GetAttr(nsGkAtoms::size);
115 if (value && value->Type() == nsAttrValue::eInteger) {
116 sizePerSide = (float)value->GetIntegerValue() / 2.0f;
117 if (sizePerSide < 1.0f) {
118 // XXX When the pixel bug is fixed, all the special casing for
119 // subpixel borders should be removed.
120 // In the meantime, this makes http://www.microsoft.com/ look right.
121 sizePerSide = 1.0f;
122 allSides = false;
124 } else {
125 sizePerSide = 1.0f; // default to a 2px high line
127 aBuilder.SetPixelValueIfUnset(eCSSProperty_border_top_width, sizePerSide);
128 if (allSides) {
129 aBuilder.SetPixelValueIfUnset(eCSSProperty_border_right_width,
130 sizePerSide);
131 aBuilder.SetPixelValueIfUnset(eCSSProperty_border_bottom_width,
132 sizePerSide);
133 aBuilder.SetPixelValueIfUnset(eCSSProperty_border_left_width,
134 sizePerSide);
137 if (!aBuilder.PropertyIsSet(eCSSProperty_border_top_style)) {
138 aBuilder.SetKeywordValue(eCSSProperty_border_top_style,
139 StyleBorderStyle::Solid);
141 if (allSides) {
142 aBuilder.SetKeywordValueIfUnset(eCSSProperty_border_right_style,
143 StyleBorderStyle::Solid);
144 aBuilder.SetKeywordValueIfUnset(eCSSProperty_border_bottom_style,
145 StyleBorderStyle::Solid);
146 aBuilder.SetKeywordValueIfUnset(eCSSProperty_border_left_style,
147 StyleBorderStyle::Solid);
149 // If it would be noticeable, set the border radius to
150 // 10000px on all corners; this triggers the clamping to make
151 // circular ends. This assumes the <hr> isn't larger than
152 // that in *both* dimensions.
153 for (const nsCSSPropertyID* props =
154 nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_radius);
155 *props != eCSSProperty_UNKNOWN; ++props) {
156 aBuilder.SetPixelValueIfUnset(*props, 10000.0f);
160 // color: a color
161 // (we got the color attribute earlier)
162 if (colorIsSet) {
163 aBuilder.SetColorValueIfUnset(eCSSProperty_color, color);
165 MapWidthAttributeInto(aBuilder);
166 MapCommonAttributesInto(aBuilder);
169 NS_IMETHODIMP_(bool)
170 HTMLHRElement::IsAttributeMapped(const nsAtom* aAttribute) const {
171 static const MappedAttributeEntry attributes[] = {
172 {nsGkAtoms::align}, {nsGkAtoms::width}, {nsGkAtoms::size},
173 {nsGkAtoms::color}, {nsGkAtoms::noshade}, {nullptr},
176 static const MappedAttributeEntry* const map[] = {
177 attributes,
178 sCommonAttributeMap,
181 return FindAttributeDependence(aAttribute, map);
184 nsMapRuleToAttributesFunc HTMLHRElement::GetAttributeMappingFunction() const {
185 return &MapAttributesIntoRule;
188 JSObject* HTMLHRElement::WrapNode(JSContext* aCx,
189 JS::Handle<JSObject*> aGivenProto) {
190 return HTMLHRElement_Binding::Wrap(aCx, this, aGivenProto);
193 } // namespace mozilla::dom