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