Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/html/HTMLTableCellElement.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/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"
13
#include "celldata.h"
14
#include "mozilla/dom/HTMLTableCellElementBinding.h"
15
16
NS_IMPL_NS_NEW_HTML_ELEMENT(TableCell)
17
18
namespace mozilla {
19
namespace dom {
20
21
HTMLTableCellElement::~HTMLTableCellElement()
22
0
{
23
0
}
24
25
JSObject*
26
HTMLTableCellElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
27
0
{
28
0
  return HTMLTableCellElement_Binding::Wrap(aCx, this, aGivenProto);
29
0
}
30
31
NS_IMPL_ELEMENT_CLONE(HTMLTableCellElement)
32
33
34
// protected method
35
HTMLTableRowElement*
36
HTMLTableCellElement::GetRow() const
37
0
{
38
0
  return HTMLTableRowElement::FromNodeOrNull(GetParent());
39
0
}
40
41
// protected method
42
HTMLTableElement*
43
HTMLTableCellElement::GetTable() const
44
0
{
45
0
  nsIContent *parent = GetParent();
46
0
  if (!parent) {
47
0
    return nullptr;
48
0
  }
49
0
50
0
  // parent should be a row.
51
0
  nsIContent* section = parent->GetParent();
52
0
  if (!section) {
53
0
    return nullptr;
54
0
  }
55
0
56
0
  if (section->IsHTMLElement(nsGkAtoms::table)) {
57
0
    // XHTML, without a row group.
58
0
    return static_cast<HTMLTableElement*>(section);
59
0
  }
60
0
61
0
  // We have a row group.
62
0
  nsIContent* result = section->GetParent();
63
0
  if (result && result->IsHTMLElement(nsGkAtoms::table)) {
64
0
    return static_cast<HTMLTableElement*>(result);
65
0
  }
66
0
67
0
  return nullptr;
68
0
}
69
70
int32_t
71
HTMLTableCellElement::CellIndex() const
72
0
{
73
0
  HTMLTableRowElement* row = GetRow();
74
0
  if (!row) {
75
0
    return -1;
76
0
  }
77
0
78
0
  nsIHTMLCollection* cells = row->Cells();
79
0
  if (!cells) {
80
0
    return -1;
81
0
  }
82
0
83
0
  uint32_t numCells = cells->Length();
84
0
  for (uint32_t i = 0; i < numCells; i++) {
85
0
    if (cells->Item(i) == this) {
86
0
      return i;
87
0
    }
88
0
  }
89
0
90
0
  return -1;
91
0
}
92
93
94
nsMappedAttributes*
95
HTMLTableCellElement::GetMappedAttributesInheritedFromTable() const
96
0
{
97
0
  if (HTMLTableElement* table = GetTable()) {
98
0
    return table->GetAttributesMappedForCell();
99
0
  }
100
0
101
0
  return nullptr;
102
0
}
103
104
void
105
HTMLTableCellElement::GetAlign(DOMString& aValue)
106
0
{
107
0
  if (!GetAttr(kNameSpaceID_None, nsGkAtoms::align, aValue)) {
108
0
    // There's no align attribute, ask the row for the alignment.
109
0
    HTMLTableRowElement* row = GetRow();
110
0
    if (row) {
111
0
      row->GetAlign(aValue);
112
0
    }
113
0
  }
114
0
}
115
116
static const nsAttrValue::EnumTable kCellScopeTable[] = {
117
  { "row",      NS_STYLE_CELL_SCOPE_ROW },
118
  { "col",      NS_STYLE_CELL_SCOPE_COL },
119
  { "rowgroup", NS_STYLE_CELL_SCOPE_ROWGROUP },
120
  { "colgroup", NS_STYLE_CELL_SCOPE_COLGROUP },
121
  { nullptr,    0 }
122
};
123
124
void
125
HTMLTableCellElement::GetScope(DOMString& aScope)
126
0
{
127
0
  GetEnumAttr(nsGkAtoms::scope, nullptr, aScope);
128
0
}
129
130
bool
131
HTMLTableCellElement::ParseAttribute(int32_t aNamespaceID,
132
                                     nsAtom* aAttribute,
133
                                     const nsAString& aValue,
134
                                     nsIPrincipal* aMaybeScriptedPrincipal,
135
                                     nsAttrValue& aResult)
136
0
{
137
0
  if (aNamespaceID == kNameSpaceID_None) {
138
0
    /* ignore these attributes, stored simply as strings
139
0
       abbr, axis, ch, headers
140
0
    */
141
0
    if (aAttribute == nsGkAtoms::charoff) {
142
0
      /* attributes that resolve to integers with a min of 0 */
143
0
      return aResult.ParseIntWithBounds(aValue, 0);
144
0
    }
145
0
    if (aAttribute == nsGkAtoms::colspan) {
146
0
      aResult.ParseClampedNonNegativeInt(aValue, 1, 1, MAX_COLSPAN);
147
0
      return true;
148
0
    }
149
0
    if (aAttribute == nsGkAtoms::rowspan) {
150
0
      aResult.ParseClampedNonNegativeInt(aValue, 1, 0, MAX_ROWSPAN);
151
0
      // quirks mode does not honor the special html 4 value of 0
152
0
      if (aResult.GetIntegerValue() == 0 && InNavQuirksMode(OwnerDoc())) {
153
0
        aResult.SetTo(1, &aValue);
154
0
      }
155
0
      return true;
156
0
    }
157
0
    if (aAttribute == nsGkAtoms::height) {
158
0
      return aResult.ParseSpecialIntValue(aValue);
159
0
    }
160
0
    if (aAttribute == nsGkAtoms::width) {
161
0
      return aResult.ParseSpecialIntValue(aValue);
162
0
    }
163
0
    if (aAttribute == nsGkAtoms::align) {
164
0
      return ParseTableCellHAlignValue(aValue, aResult);
165
0
    }
166
0
    if (aAttribute == nsGkAtoms::bgcolor) {
167
0
      return aResult.ParseColor(aValue);
168
0
    }
169
0
    if (aAttribute == nsGkAtoms::scope) {
170
0
      return aResult.ParseEnumValue(aValue, kCellScopeTable, false);
171
0
    }
172
0
    if (aAttribute == nsGkAtoms::valign) {
173
0
      return ParseTableVAlignValue(aValue, aResult);
174
0
    }
175
0
  }
176
0
177
0
  return nsGenericHTMLElement::ParseBackgroundAttribute(aNamespaceID,
178
0
                                                        aAttribute, aValue,
179
0
                                                        aResult) ||
180
0
         nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
181
0
                                              aMaybeScriptedPrincipal, aResult);
182
0
}
183
184
void
185
HTMLTableCellElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
186
                                            MappedDeclarations& aDecls)
187
0
{
188
0
  // width: value
189
0
  if (!aDecls.PropertyIsSet(eCSSProperty_width)) {
190
0
    const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
191
0
    if (value && value->Type() == nsAttrValue::eInteger) {
192
0
      if (value->GetIntegerValue() > 0)
193
0
        aDecls.SetPixelValue(eCSSProperty_width, (float)value->GetIntegerValue());
194
0
      // else 0 implies auto for compatibility.
195
0
    }
196
0
    else if (value && value->Type() == nsAttrValue::ePercent) {
197
0
      if (value->GetPercentValue() > 0.0f)
198
0
        aDecls.SetPercentValue(eCSSProperty_width, value->GetPercentValue());
199
0
      // else 0 implies auto for compatibility
200
0
    }
201
0
  }
202
0
  // height: value
203
0
  if (!aDecls.PropertyIsSet(eCSSProperty_height)) {
204
0
    const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::height);
205
0
    if (value && value->Type() == nsAttrValue::eInteger) {
206
0
      if (value->GetIntegerValue() > 0)
207
0
        aDecls.SetPixelValue(eCSSProperty_height, (float)value->GetIntegerValue());
208
0
      // else 0 implies auto for compatibility.
209
0
    }
210
0
    else if (value && value->Type() == nsAttrValue::ePercent) {
211
0
      if (value->GetPercentValue() > 0.0f)
212
0
        aDecls.SetPercentValue(eCSSProperty_height, value->GetPercentValue());
213
0
      // else 0 implies auto for compatibility
214
0
    }
215
0
  }
216
0
  if (!aDecls.PropertyIsSet(eCSSProperty_white_space)) {
217
0
    // nowrap: enum
218
0
    if (aAttributes->GetAttr(nsGkAtoms::nowrap)) {
219
0
      // See if our width is not a nonzero integer width.
220
0
      const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
221
0
      nsCompatibility mode = aDecls.Document()->GetCompatibilityMode();
222
0
      if (!value || value->Type() != nsAttrValue::eInteger ||
223
0
          value->GetIntegerValue() == 0 ||
224
0
          eCompatibility_NavQuirks != mode) {
225
0
        aDecls.SetKeywordValue(eCSSProperty_white_space, StyleWhiteSpace::Nowrap);
226
0
      }
227
0
    }
228
0
  }
229
0
230
0
  nsGenericHTMLElement::MapDivAlignAttributeInto(aAttributes, aDecls);
231
0
  nsGenericHTMLElement::MapVAlignAttributeInto(aAttributes, aDecls);
232
0
  nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aDecls);
233
0
  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
234
0
}
235
236
NS_IMETHODIMP_(bool)
237
HTMLTableCellElement::IsAttributeMapped(const nsAtom* aAttribute) const
238
0
{
239
0
  static const MappedAttributeEntry attributes[] = {
240
0
    { &nsGkAtoms::align },
241
0
    { &nsGkAtoms::valign },
242
0
    { &nsGkAtoms::nowrap },
243
#if 0
244
    // XXXldb If these are implemented, they might need to move to
245
    // GetAttributeChangeHint (depending on how, and preferably not).
246
    { &nsGkAtoms::abbr },
247
    { &nsGkAtoms::axis },
248
    { &nsGkAtoms::headers },
249
    { &nsGkAtoms::scope },
250
#endif
251
    { &nsGkAtoms::width },
252
0
    { &nsGkAtoms::height },
253
0
    { nullptr }
254
0
  };
255
0
256
0
  static const MappedAttributeEntry* const map[] = {
257
0
    attributes,
258
0
    sCommonAttributeMap,
259
0
    sBackgroundAttributeMap,
260
0
  };
261
0
262
0
  return FindAttributeDependence(aAttribute, map);
263
0
}
264
265
nsMapRuleToAttributesFunc
266
HTMLTableCellElement::GetAttributeMappingFunction() const
267
0
{
268
0
  return &MapAttributesIntoRule;
269
0
}
270
271
} // namespace dom
272
} // namespace mozilla