summaryrefslogtreecommitdiffstats
path: root/dom/html/HTMLHRElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/html/HTMLHRElement.cpp')
-rw-r--r--dom/html/HTMLHRElement.cpp267
1 files changed, 267 insertions, 0 deletions
diff --git a/dom/html/HTMLHRElement.cpp b/dom/html/HTMLHRElement.cpp
new file mode 100644
index 000000000..fb5dbe618
--- /dev/null
+++ b/dom/html/HTMLHRElement.cpp
@@ -0,0 +1,267 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/dom/HTMLHRElement.h"
+#include "mozilla/dom/HTMLHRElementBinding.h"
+
+NS_IMPL_NS_NEW_HTML_ELEMENT(HR)
+
+namespace mozilla {
+namespace dom {
+
+HTMLHRElement::HTMLHRElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
+ : nsGenericHTMLElement(aNodeInfo)
+{
+}
+
+HTMLHRElement::~HTMLHRElement()
+{
+}
+
+NS_IMPL_ISUPPORTS_INHERITED(HTMLHRElement, nsGenericHTMLElement,
+ nsIDOMHTMLHRElement)
+
+NS_IMPL_ELEMENT_CLONE(HTMLHRElement)
+
+
+NS_IMPL_STRING_ATTR(HTMLHRElement, Align, align)
+NS_IMPL_BOOL_ATTR(HTMLHRElement, NoShade, noshade)
+NS_IMPL_STRING_ATTR(HTMLHRElement, Size, size)
+NS_IMPL_STRING_ATTR(HTMLHRElement, Width, width)
+NS_IMPL_STRING_ATTR(HTMLHRElement, Color, color)
+
+bool
+HTMLHRElement::ParseAttribute(int32_t aNamespaceID,
+ nsIAtom* aAttribute,
+ const nsAString& aValue,
+ nsAttrValue& aResult)
+{
+ static const nsAttrValue::EnumTable kAlignTable[] = {
+ { "left", NS_STYLE_TEXT_ALIGN_LEFT },
+ { "right", NS_STYLE_TEXT_ALIGN_RIGHT },
+ { "center", NS_STYLE_TEXT_ALIGN_CENTER },
+ { nullptr, 0 }
+ };
+
+ if (aNamespaceID == kNameSpaceID_None) {
+ if (aAttribute == nsGkAtoms::width) {
+ return aResult.ParseSpecialIntValue(aValue);
+ }
+ if (aAttribute == nsGkAtoms::size) {
+ return aResult.ParseIntWithBounds(aValue, 1, 1000);
+ }
+ if (aAttribute == nsGkAtoms::align) {
+ return aResult.ParseEnumValue(aValue, kAlignTable, false);
+ }
+ if (aAttribute == nsGkAtoms::color) {
+ return aResult.ParseColor(aValue);
+ }
+ }
+
+ return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
+ aResult);
+}
+
+void
+HTMLHRElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
+ nsRuleData* aData)
+{
+ bool noshade = false;
+
+ const nsAttrValue* colorValue = aAttributes->GetAttr(nsGkAtoms::color);
+ nscolor color;
+ bool colorIsSet = colorValue && colorValue->GetColorValue(color);
+
+ if (aData->mSIDs & (NS_STYLE_INHERIT_BIT(Position) |
+ NS_STYLE_INHERIT_BIT(Border))) {
+ if (colorIsSet) {
+ noshade = true;
+ } else {
+ noshade = !!aAttributes->GetAttr(nsGkAtoms::noshade);
+ }
+ }
+
+ if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Margin)) {
+ // align: enum
+ const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
+ if (value && value->Type() == nsAttrValue::eEnum) {
+ // Map align attribute into auto side margins
+ nsCSSValue* marginLeft = aData->ValueForMarginLeft();
+ nsCSSValue* marginRight = aData->ValueForMarginRight();
+ switch (value->GetEnumValue()) {
+ case NS_STYLE_TEXT_ALIGN_LEFT:
+ if (marginLeft->GetUnit() == eCSSUnit_Null)
+ marginLeft->SetFloatValue(0.0f, eCSSUnit_Pixel);
+ if (marginRight->GetUnit() == eCSSUnit_Null)
+ marginRight->SetAutoValue();
+ break;
+ case NS_STYLE_TEXT_ALIGN_RIGHT:
+ if (marginLeft->GetUnit() == eCSSUnit_Null)
+ marginLeft->SetAutoValue();
+ if (marginRight->GetUnit() == eCSSUnit_Null)
+ marginRight->SetFloatValue(0.0f, eCSSUnit_Pixel);
+ break;
+ case NS_STYLE_TEXT_ALIGN_CENTER:
+ if (marginLeft->GetUnit() == eCSSUnit_Null)
+ marginLeft->SetAutoValue();
+ if (marginRight->GetUnit() == eCSSUnit_Null)
+ marginRight->SetAutoValue();
+ break;
+ }
+ }
+ }
+ if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Position)) {
+ // width: integer, percent
+ nsCSSValue* width = aData->ValueForWidth();
+ if (width->GetUnit() == eCSSUnit_Null) {
+ const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
+ if (value && value->Type() == nsAttrValue::eInteger) {
+ width->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
+ } else if (value && value->Type() == nsAttrValue::ePercent) {
+ width->SetPercentValue(value->GetPercentValue());
+ }
+ }
+
+ nsCSSValue* height = aData->ValueForHeight();
+ if (height->GetUnit() == eCSSUnit_Null) {
+ // size: integer
+ if (noshade) {
+ // noshade case: size is set using the border
+ height->SetAutoValue();
+ } else {
+ // normal case
+ // the height includes the top and bottom borders that are initially 1px.
+ // for size=1, html.css has a special case rule that makes this work by
+ // removing all but the top border.
+ const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::size);
+ if (value && value->Type() == nsAttrValue::eInteger) {
+ height->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
+ } // else use default value from html.css
+ }
+ }
+ }
+ if ((aData->mSIDs & NS_STYLE_INHERIT_BIT(Border)) && noshade) { // if not noshade, border styles are dealt with by html.css
+ // size: integer
+ // if a size is set, use half of it per side, otherwise, use 1px per side
+ float sizePerSide;
+ bool allSides = true;
+ const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::size);
+ if (value && value->Type() == nsAttrValue::eInteger) {
+ sizePerSide = (float)value->GetIntegerValue() / 2.0f;
+ if (sizePerSide < 1.0f) {
+ // XXX When the pixel bug is fixed, all the special casing for
+ // subpixel borders should be removed.
+ // In the meantime, this makes http://www.microsoft.com/ look right.
+ sizePerSide = 1.0f;
+ allSides = false;
+ }
+ } else {
+ sizePerSide = 1.0f; // default to a 2px high line
+ }
+ nsCSSValue* borderTopWidth = aData->ValueForBorderTopWidth();
+ if (borderTopWidth->GetUnit() == eCSSUnit_Null) {
+ borderTopWidth->SetFloatValue(sizePerSide, eCSSUnit_Pixel);
+ }
+ if (allSides) {
+ nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidth();
+ if (borderRightWidth->GetUnit() == eCSSUnit_Null) {
+ borderRightWidth->SetFloatValue(sizePerSide, eCSSUnit_Pixel);
+ }
+ nsCSSValue* borderBottomWidth = aData->ValueForBorderBottomWidth();
+ if (borderBottomWidth->GetUnit() == eCSSUnit_Null) {
+ borderBottomWidth->SetFloatValue(sizePerSide, eCSSUnit_Pixel);
+ }
+ nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidth();
+ if (borderLeftWidth->GetUnit() == eCSSUnit_Null) {
+ borderLeftWidth->SetFloatValue(sizePerSide, eCSSUnit_Pixel);
+ }
+ }
+
+ nsCSSValue* borderTopStyle = aData->ValueForBorderTopStyle();
+ if (borderTopStyle->GetUnit() == eCSSUnit_Null) {
+ borderTopStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID,
+ eCSSUnit_Enumerated);
+ }
+ if (allSides) {
+ nsCSSValue* borderRightStyle = aData->ValueForBorderRightStyle();
+ if (borderRightStyle->GetUnit() == eCSSUnit_Null) {
+ borderRightStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID,
+ eCSSUnit_Enumerated);
+ }
+ nsCSSValue* borderBottomStyle = aData->ValueForBorderBottomStyle();
+ if (borderBottomStyle->GetUnit() == eCSSUnit_Null) {
+ borderBottomStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID,
+ eCSSUnit_Enumerated);
+ }
+ nsCSSValue* borderLeftStyle = aData->ValueForBorderLeftStyle();
+ if (borderLeftStyle->GetUnit() == eCSSUnit_Null) {
+ borderLeftStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID,
+ eCSSUnit_Enumerated);
+ }
+
+ // If it would be noticeable, set the border radius to
+ // 10000px on all corners; this triggers the clamping to make
+ // circular ends. This assumes the <hr> isn't larger than
+ // that in *both* dimensions.
+ for (const nsCSSPropertyID* props =
+ nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_radius);
+ *props != eCSSProperty_UNKNOWN; ++props) {
+ nsCSSValue* dimen = aData->ValueFor(*props);
+ if (dimen->GetUnit() == eCSSUnit_Null) {
+ dimen->SetFloatValue(10000.0f, eCSSUnit_Pixel);
+ }
+ }
+ }
+ }
+ if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Color)) {
+ // color: a color
+ // (we got the color attribute earlier)
+ nsCSSValue* colorValue = aData->ValueForColor();
+ if (colorIsSet &&
+ colorValue->GetUnit() == eCSSUnit_Null &&
+ aData->mPresContext->UseDocumentColors()) {
+ colorValue->SetColorValue(color);
+ }
+ }
+
+ nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
+}
+
+NS_IMETHODIMP_(bool)
+HTMLHRElement::IsAttributeMapped(const nsIAtom* aAttribute) const
+{
+ static const MappedAttributeEntry attributes[] = {
+ { &nsGkAtoms::align },
+ { &nsGkAtoms::width },
+ { &nsGkAtoms::size },
+ { &nsGkAtoms::color },
+ { &nsGkAtoms::noshade },
+ { nullptr },
+ };
+
+ static const MappedAttributeEntry* const map[] = {
+ attributes,
+ sCommonAttributeMap,
+ };
+
+ return FindAttributeDependence(aAttribute, map);
+}
+
+
+nsMapRuleToAttributesFunc
+HTMLHRElement::GetAttributeMappingFunction() const
+{
+ return &MapAttributesIntoRule;
+}
+
+JSObject*
+HTMLHRElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+ return HTMLHRElementBinding::Wrap(aCx, this, aGivenProto);
+}
+
+} // namespace dom
+} // namespace mozilla