/src/mozilla-central/dom/html/HTMLHRElement.cpp
Line | Count | Source (jump to first uncovered line) |
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/. */ |
6 | | |
7 | | #include "mozilla/dom/HTMLHRElement.h" |
8 | | #include "mozilla/dom/HTMLHRElementBinding.h" |
9 | | |
10 | | #include "nsCSSProps.h" |
11 | | |
12 | | NS_IMPL_NS_NEW_HTML_ELEMENT(HR) |
13 | | |
14 | | namespace mozilla { |
15 | | namespace dom { |
16 | | |
17 | | HTMLHRElement::HTMLHRElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) |
18 | | : nsGenericHTMLElement(std::move(aNodeInfo)) |
19 | 0 | { |
20 | 0 | } |
21 | | |
22 | | HTMLHRElement::~HTMLHRElement() |
23 | 0 | { |
24 | 0 | } |
25 | | |
26 | | NS_IMPL_ELEMENT_CLONE(HTMLHRElement) |
27 | | |
28 | | |
29 | | bool |
30 | | HTMLHRElement::ParseAttribute(int32_t aNamespaceID, |
31 | | nsAtom* aAttribute, |
32 | | const nsAString& aValue, |
33 | | nsIPrincipal* aMaybeScriptedPrincipal, |
34 | | nsAttrValue& aResult) |
35 | 0 | { |
36 | 0 | static const nsAttrValue::EnumTable kAlignTable[] = { |
37 | 0 | { "left", NS_STYLE_TEXT_ALIGN_LEFT }, |
38 | 0 | { "right", NS_STYLE_TEXT_ALIGN_RIGHT }, |
39 | 0 | { "center", NS_STYLE_TEXT_ALIGN_CENTER }, |
40 | 0 | { nullptr, 0 } |
41 | 0 | }; |
42 | 0 |
|
43 | 0 | if (aNamespaceID == kNameSpaceID_None) { |
44 | 0 | if (aAttribute == nsGkAtoms::width) { |
45 | 0 | return aResult.ParseSpecialIntValue(aValue); |
46 | 0 | } |
47 | 0 | if (aAttribute == nsGkAtoms::size) { |
48 | 0 | return aResult.ParseIntWithBounds(aValue, 1, 1000); |
49 | 0 | } |
50 | 0 | if (aAttribute == nsGkAtoms::align) { |
51 | 0 | return aResult.ParseEnumValue(aValue, kAlignTable, false); |
52 | 0 | } |
53 | 0 | if (aAttribute == nsGkAtoms::color) { |
54 | 0 | return aResult.ParseColor(aValue); |
55 | 0 | } |
56 | 0 | } |
57 | 0 | |
58 | 0 | return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue, |
59 | 0 | aMaybeScriptedPrincipal, aResult); |
60 | 0 | } |
61 | | |
62 | | void |
63 | | HTMLHRElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes, |
64 | | MappedDeclarations& aDecls) |
65 | 0 | { |
66 | 0 | bool noshade = false; |
67 | 0 |
|
68 | 0 | const nsAttrValue* colorValue = aAttributes->GetAttr(nsGkAtoms::color); |
69 | 0 | nscolor color; |
70 | 0 | bool colorIsSet = colorValue && colorValue->GetColorValue(color); |
71 | 0 |
|
72 | 0 | if (colorIsSet) { |
73 | 0 | noshade = true; |
74 | 0 | } else { |
75 | 0 | noshade = !!aAttributes->GetAttr(nsGkAtoms::noshade); |
76 | 0 | } |
77 | 0 |
|
78 | 0 | // align: enum |
79 | 0 | const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align); |
80 | 0 | if (value && value->Type() == nsAttrValue::eEnum) { |
81 | 0 | // Map align attribute into auto side margins |
82 | 0 | switch (value->GetEnumValue()) { |
83 | 0 | case NS_STYLE_TEXT_ALIGN_LEFT: |
84 | 0 | aDecls.SetPixelValueIfUnset(eCSSProperty_margin_left, 0.0f); |
85 | 0 | aDecls.SetAutoValueIfUnset(eCSSProperty_margin_right); |
86 | 0 | break; |
87 | 0 | case NS_STYLE_TEXT_ALIGN_RIGHT: |
88 | 0 | aDecls.SetAutoValueIfUnset(eCSSProperty_margin_left); |
89 | 0 | aDecls.SetPixelValueIfUnset(eCSSProperty_margin_right, 0.0f); |
90 | 0 | break; |
91 | 0 | case NS_STYLE_TEXT_ALIGN_CENTER: |
92 | 0 | aDecls.SetAutoValueIfUnset(eCSSProperty_margin_left); |
93 | 0 | aDecls.SetAutoValueIfUnset(eCSSProperty_margin_right); |
94 | 0 | break; |
95 | 0 | } |
96 | 0 | } |
97 | 0 | if (!aDecls.PropertyIsSet(eCSSProperty_height)) { |
98 | 0 | // size: integer |
99 | 0 | if (noshade) { |
100 | 0 | // noshade case: size is set using the border |
101 | 0 | aDecls.SetAutoValue(eCSSProperty_height); |
102 | 0 | } else { |
103 | 0 | // normal case |
104 | 0 | // the height includes the top and bottom borders that are initially 1px. |
105 | 0 | // for size=1, html.css has a special case rule that makes this work by |
106 | 0 | // removing all but the top border. |
107 | 0 | const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::size); |
108 | 0 | if (value && value->Type() == nsAttrValue::eInteger) { |
109 | 0 | aDecls.SetPixelValue(eCSSProperty_height, (float)value->GetIntegerValue()); |
110 | 0 | } // else use default value from html.css |
111 | 0 | } |
112 | 0 | } |
113 | 0 |
|
114 | 0 | // if not noshade, border styles are dealt with by html.css |
115 | 0 | if (noshade) { |
116 | 0 | // size: integer |
117 | 0 | // if a size is set, use half of it per side, otherwise, use 1px per side |
118 | 0 | float sizePerSide; |
119 | 0 | bool allSides = true; |
120 | 0 | value = aAttributes->GetAttr(nsGkAtoms::size); |
121 | 0 | if (value && value->Type() == nsAttrValue::eInteger) { |
122 | 0 | sizePerSide = (float)value->GetIntegerValue() / 2.0f; |
123 | 0 | if (sizePerSide < 1.0f) { |
124 | 0 | // XXX When the pixel bug is fixed, all the special casing for |
125 | 0 | // subpixel borders should be removed. |
126 | 0 | // In the meantime, this makes http://www.microsoft.com/ look right. |
127 | 0 | sizePerSide = 1.0f; |
128 | 0 | allSides = false; |
129 | 0 | } |
130 | 0 | } else { |
131 | 0 | sizePerSide = 1.0f; // default to a 2px high line |
132 | 0 | } |
133 | 0 | aDecls.SetPixelValueIfUnset(eCSSProperty_border_top_width, sizePerSide); |
134 | 0 | if (allSides) { |
135 | 0 | aDecls.SetPixelValueIfUnset(eCSSProperty_border_right_width, sizePerSide); |
136 | 0 | aDecls.SetPixelValueIfUnset(eCSSProperty_border_bottom_width, sizePerSide); |
137 | 0 | aDecls.SetPixelValueIfUnset(eCSSProperty_border_left_width, sizePerSide); |
138 | 0 | } |
139 | 0 |
|
140 | 0 | if (!aDecls.PropertyIsSet(eCSSProperty_border_top_style)) |
141 | 0 | aDecls.SetKeywordValue(eCSSProperty_border_top_style, |
142 | 0 | NS_STYLE_BORDER_STYLE_SOLID); |
143 | 0 | if (allSides) { |
144 | 0 | aDecls.SetKeywordValueIfUnset(eCSSProperty_border_right_style, |
145 | 0 | NS_STYLE_BORDER_STYLE_SOLID); |
146 | 0 | aDecls.SetKeywordValueIfUnset(eCSSProperty_border_bottom_style, |
147 | 0 | NS_STYLE_BORDER_STYLE_SOLID); |
148 | 0 | aDecls.SetKeywordValueIfUnset(eCSSProperty_border_left_style, |
149 | 0 | NS_STYLE_BORDER_STYLE_SOLID); |
150 | 0 |
|
151 | 0 | // If it would be noticeable, set the border radius to |
152 | 0 | // 10000px on all corners; this triggers the clamping to make |
153 | 0 | // circular ends. This assumes the <hr> isn't larger than |
154 | 0 | // that in *both* dimensions. |
155 | 0 | for (const nsCSSPropertyID* props = |
156 | 0 | nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_radius); |
157 | 0 | *props != eCSSProperty_UNKNOWN; ++props) { |
158 | 0 | aDecls.SetPixelValueIfUnset(*props, 10000.0f); |
159 | 0 | } |
160 | 0 | } |
161 | 0 | } |
162 | 0 | // color: a color |
163 | 0 | // (we got the color attribute earlier) |
164 | 0 | if (colorIsSet) { |
165 | 0 | aDecls.SetColorValueIfUnset(eCSSProperty_color, color); |
166 | 0 | } |
167 | 0 |
|
168 | 0 | nsGenericHTMLElement::MapWidthAttributeInto(aAttributes, aDecls); |
169 | 0 | nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls); |
170 | 0 | } |
171 | | |
172 | | NS_IMETHODIMP_(bool) |
173 | | HTMLHRElement::IsAttributeMapped(const nsAtom* aAttribute) const |
174 | 0 | { |
175 | 0 | static const MappedAttributeEntry attributes[] = { |
176 | 0 | { &nsGkAtoms::align }, |
177 | 0 | { &nsGkAtoms::width }, |
178 | 0 | { &nsGkAtoms::size }, |
179 | 0 | { &nsGkAtoms::color }, |
180 | 0 | { &nsGkAtoms::noshade }, |
181 | 0 | { nullptr }, |
182 | 0 | }; |
183 | 0 |
|
184 | 0 | static const MappedAttributeEntry* const map[] = { |
185 | 0 | attributes, |
186 | 0 | sCommonAttributeMap, |
187 | 0 | }; |
188 | 0 |
|
189 | 0 | return FindAttributeDependence(aAttribute, map); |
190 | 0 | } |
191 | | |
192 | | |
193 | | nsMapRuleToAttributesFunc |
194 | | HTMLHRElement::GetAttributeMappingFunction() const |
195 | 0 | { |
196 | 0 | return &MapAttributesIntoRule; |
197 | 0 | } |
198 | | |
199 | | JSObject* |
200 | | HTMLHRElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) |
201 | 0 | { |
202 | 0 | return HTMLHRElement_Binding::Wrap(aCx, this, aGivenProto); |
203 | 0 | } |
204 | | |
205 | | } // namespace dom |
206 | | } // namespace mozilla |