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/HTMLTableCellElement.h"
8 #include "mozilla/dom/HTMLTableElement.h"
9 #include "mozilla/dom/HTMLTableRowElement.h"
10 #include "mozilla/MappedDeclarations.h"
11 #include "nsMappedAttributes.h"
12 #include "nsAttrValueInlines.h"
14 #include "mozilla/dom/HTMLTableCellElementBinding.h"
16 NS_IMPL_NS_NEW_HTML_ELEMENT(TableCell
)
21 HTMLTableCellElement::~HTMLTableCellElement() = default;
23 JSObject
* HTMLTableCellElement::WrapNode(JSContext
* aCx
,
24 JS::Handle
<JSObject
*> aGivenProto
) {
25 return HTMLTableCellElement_Binding::Wrap(aCx
, this, aGivenProto
);
28 NS_IMPL_ELEMENT_CLONE(HTMLTableCellElement
)
31 HTMLTableRowElement
* HTMLTableCellElement::GetRow() const {
32 return HTMLTableRowElement::FromNodeOrNull(GetParent());
36 HTMLTableElement
* HTMLTableCellElement::GetTable() const {
37 nsIContent
* parent
= GetParent();
42 // parent should be a row.
43 nsIContent
* section
= parent
->GetParent();
48 if (section
->IsHTMLElement(nsGkAtoms::table
)) {
49 // XHTML, without a row group.
50 return static_cast<HTMLTableElement
*>(section
);
53 // We have a row group.
54 nsIContent
* result
= section
->GetParent();
55 if (result
&& result
->IsHTMLElement(nsGkAtoms::table
)) {
56 return static_cast<HTMLTableElement
*>(result
);
62 int32_t HTMLTableCellElement::CellIndex() const {
63 HTMLTableRowElement
* row
= GetRow();
68 nsIHTMLCollection
* cells
= row
->Cells();
73 uint32_t numCells
= cells
->Length();
74 for (uint32_t i
= 0; i
< numCells
; i
++) {
75 if (cells
->Item(i
) == this) {
84 HTMLTableCellElement::GetMappedAttributesInheritedFromTable() const {
85 if (HTMLTableElement
* table
= GetTable()) {
86 return table
->GetAttributesMappedForCell();
92 void HTMLTableCellElement::GetAlign(DOMString
& aValue
) {
93 if (!GetAttr(kNameSpaceID_None
, nsGkAtoms::align
, aValue
)) {
94 // There's no align attribute, ask the row for the alignment.
95 HTMLTableRowElement
* row
= GetRow();
97 row
->GetAlign(aValue
);
102 static const nsAttrValue::EnumTable kCellScopeTable
[] = {
103 {"row", NS_STYLE_CELL_SCOPE_ROW
},
104 {"col", NS_STYLE_CELL_SCOPE_COL
},
105 {"rowgroup", NS_STYLE_CELL_SCOPE_ROWGROUP
},
106 {"colgroup", NS_STYLE_CELL_SCOPE_COLGROUP
},
109 void HTMLTableCellElement::GetScope(DOMString
& aScope
) {
110 GetEnumAttr(nsGkAtoms::scope
, nullptr, aScope
);
113 bool HTMLTableCellElement::ParseAttribute(int32_t aNamespaceID
,
115 const nsAString
& aValue
,
116 nsIPrincipal
* aMaybeScriptedPrincipal
,
117 nsAttrValue
& aResult
) {
118 if (aNamespaceID
== kNameSpaceID_None
) {
119 /* ignore these attributes, stored simply as strings
120 abbr, axis, ch, headers
122 if (aAttribute
== nsGkAtoms::colspan
) {
123 aResult
.ParseClampedNonNegativeInt(aValue
, 1, 1, MAX_COLSPAN
);
126 if (aAttribute
== nsGkAtoms::rowspan
) {
127 aResult
.ParseClampedNonNegativeInt(aValue
, 1, 0, MAX_ROWSPAN
);
128 // quirks mode does not honor the special html 4 value of 0
129 if (aResult
.GetIntegerValue() == 0 && InNavQuirksMode(OwnerDoc())) {
130 aResult
.SetTo(1, &aValue
);
134 if (aAttribute
== nsGkAtoms::height
) {
135 return aResult
.ParseNonzeroHTMLDimension(aValue
);
137 if (aAttribute
== nsGkAtoms::width
) {
138 return aResult
.ParseNonzeroHTMLDimension(aValue
);
140 if (aAttribute
== nsGkAtoms::align
) {
141 return ParseTableCellHAlignValue(aValue
, aResult
);
143 if (aAttribute
== nsGkAtoms::bgcolor
) {
144 return aResult
.ParseColor(aValue
);
146 if (aAttribute
== nsGkAtoms::scope
) {
147 return aResult
.ParseEnumValue(aValue
, kCellScopeTable
, false);
149 if (aAttribute
== nsGkAtoms::valign
) {
150 return ParseTableVAlignValue(aValue
, aResult
);
154 return nsGenericHTMLElement::ParseBackgroundAttribute(
155 aNamespaceID
, aAttribute
, aValue
, aResult
) ||
156 nsGenericHTMLElement::ParseAttribute(aNamespaceID
, aAttribute
, aValue
,
157 aMaybeScriptedPrincipal
, aResult
);
160 void HTMLTableCellElement::MapAttributesIntoRule(
161 const nsMappedAttributes
* aAttributes
, MappedDeclarations
& aDecls
) {
162 MapImageSizeAttributesInto(aAttributes
, aDecls
);
164 if (!aDecls
.PropertyIsSet(eCSSProperty_white_space
)) {
166 if (aAttributes
->GetAttr(nsGkAtoms::nowrap
)) {
167 // See if our width is not a nonzero integer width.
168 const nsAttrValue
* value
= aAttributes
->GetAttr(nsGkAtoms::width
);
169 nsCompatibility mode
= aDecls
.Document()->GetCompatibilityMode();
170 if (!value
|| value
->Type() != nsAttrValue::eInteger
||
171 value
->GetIntegerValue() == 0 || eCompatibility_NavQuirks
!= mode
) {
172 aDecls
.SetKeywordValue(eCSSProperty_white_space
,
173 StyleWhiteSpace::Nowrap
);
178 nsGenericHTMLElement::MapDivAlignAttributeInto(aAttributes
, aDecls
);
179 nsGenericHTMLElement::MapVAlignAttributeInto(aAttributes
, aDecls
);
180 nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes
, aDecls
);
181 nsGenericHTMLElement::MapCommonAttributesInto(aAttributes
, aDecls
);
185 HTMLTableCellElement::IsAttributeMapped(const nsAtom
* aAttribute
) const {
186 static const MappedAttributeEntry attributes
[] = {
191 // XXXldb If these are implemented, they might need to move to
192 // GetAttributeChangeHint (depending on how, and preferably not).
195 { nsGkAtoms::headers
},
196 { nsGkAtoms::scope
},
203 static const MappedAttributeEntry
* const map
[] = {
206 sBackgroundAttributeMap
,
209 return FindAttributeDependence(aAttribute
, map
);
212 nsMapRuleToAttributesFunc
HTMLTableCellElement::GetAttributeMappingFunction()
214 return &MapAttributesIntoRule
;
218 } // namespace mozilla