Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/html/HTMLTableRowElement.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/HTMLTableRowElement.h"
8
#include "mozilla/dom/HTMLTableElement.h"
9
#include "mozilla/MappedDeclarations.h"
10
#include "nsMappedAttributes.h"
11
#include "nsAttrValueInlines.h"
12
#include "mozilla/dom/BindingUtils.h"
13
#include "mozilla/dom/HTMLTableRowElementBinding.h"
14
#include "nsContentList.h"
15
#include "nsContentUtils.h"
16
17
NS_IMPL_NS_NEW_HTML_ELEMENT(TableRow)
18
19
namespace mozilla {
20
namespace dom {
21
22
HTMLTableRowElement::~HTMLTableRowElement()
23
0
{
24
0
}
25
26
JSObject*
27
HTMLTableRowElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
28
0
{
29
0
  return HTMLTableRowElement_Binding::Wrap(aCx, this, aGivenProto);
30
0
}
31
32
NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLTableRowElement)
33
34
0
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLTableRowElement,
35
0
                                                  nsGenericHTMLElement)
36
0
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCells)
37
0
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
38
39
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(HTMLTableRowElement,
40
                                               nsGenericHTMLElement)
41
42
NS_IMPL_ELEMENT_CLONE(HTMLTableRowElement)
43
44
45
// protected method
46
HTMLTableSectionElement*
47
HTMLTableRowElement::GetSection() const
48
0
{
49
0
  nsIContent* parent = GetParent();
50
0
  if (parent &&
51
0
      parent->IsAnyOfHTMLElements(nsGkAtoms::thead,
52
0
                                  nsGkAtoms::tbody,
53
0
                                  nsGkAtoms::tfoot)) {
54
0
    return static_cast<HTMLTableSectionElement*>(parent);
55
0
  }
56
0
  return nullptr;
57
0
}
58
59
// protected method
60
HTMLTableElement*
61
HTMLTableRowElement::GetTable() const
62
0
{
63
0
  nsIContent* parent = GetParent();
64
0
  if (!parent) {
65
0
    return nullptr;
66
0
  }
67
0
68
0
  // We may not be in a section
69
0
  HTMLTableElement* table = HTMLTableElement::FromNode(parent);
70
0
  if (table) {
71
0
    return table;
72
0
  }
73
0
74
0
  return HTMLTableElement::FromNodeOrNull(parent->GetParent());
75
0
}
76
77
int32_t
78
HTMLTableRowElement::RowIndex() const
79
0
{
80
0
  HTMLTableElement* table = GetTable();
81
0
  if (!table) {
82
0
    return -1;
83
0
  }
84
0
85
0
  nsIHTMLCollection* rows = table->Rows();
86
0
87
0
  uint32_t numRows = rows->Length();
88
0
89
0
  for (uint32_t i = 0; i < numRows; i++) {
90
0
    if (rows->GetElementAt(i) == this) {
91
0
      return i;
92
0
    }
93
0
  }
94
0
95
0
  return -1;
96
0
}
97
98
int32_t
99
HTMLTableRowElement::SectionRowIndex() const
100
0
{
101
0
  HTMLTableSectionElement* section = GetSection();
102
0
  if (!section) {
103
0
    return -1;
104
0
  }
105
0
106
0
  nsCOMPtr<nsIHTMLCollection> coll = section->Rows();
107
0
  uint32_t numRows = coll->Length();
108
0
  for (uint32_t i = 0; i < numRows; i++) {
109
0
    if (coll->GetElementAt(i) == this) {
110
0
      return i;
111
0
    }
112
0
  }
113
0
114
0
  return -1;
115
0
}
116
117
static bool
118
IsCell(Element *aElement, int32_t aNamespaceID,
119
       nsAtom* aAtom, void *aData)
120
0
{
121
0
  return aElement->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th);
122
0
}
123
124
nsIHTMLCollection*
125
HTMLTableRowElement::Cells()
126
0
{
127
0
  if (!mCells) {
128
0
    mCells = new nsContentList(this,
129
0
                               IsCell,
130
0
                               nullptr, // destroy func
131
0
                               nullptr, // closure data
132
0
                               false,
133
0
                               nullptr,
134
0
                               kNameSpaceID_XHTML,
135
0
                               false);
136
0
  }
137
0
138
0
  return mCells;
139
0
}
140
141
already_AddRefed<nsGenericHTMLElement>
142
HTMLTableRowElement::InsertCell(int32_t aIndex,
143
                                ErrorResult& aError)
144
0
{
145
0
  if (aIndex < -1) {
146
0
    aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
147
0
    return nullptr;
148
0
  }
149
0
150
0
  // Make sure mCells is initialized.
151
0
  nsIHTMLCollection* cells = Cells();
152
0
153
0
  NS_ASSERTION(mCells, "How did that happen?");
154
0
155
0
  nsCOMPtr<nsINode> nextSibling;
156
0
  // -1 means append, so should use null nextSibling
157
0
  if (aIndex != -1) {
158
0
    nextSibling = cells->Item(aIndex);
159
0
    // Check whether we're inserting past end of list.  We want to avoid doing
160
0
    // this unless we really have to, since this has to walk all our kids.  If
161
0
    // we have a nextSibling, we're clearly not past end of list.
162
0
    if (!nextSibling) {
163
0
      uint32_t cellCount = cells->Length();
164
0
      if (aIndex > int32_t(cellCount)) {
165
0
        aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
166
0
        return nullptr;
167
0
      }
168
0
    }
169
0
  }
170
0
171
0
  // create the cell
172
0
  RefPtr<mozilla::dom::NodeInfo> nodeInfo;
173
0
  nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::td,
174
0
                               getter_AddRefs(nodeInfo));
175
0
176
0
  RefPtr<nsGenericHTMLElement> cell =
177
0
    NS_NewHTMLTableCellElement(nodeInfo.forget());
178
0
  if (!cell) {
179
0
    aError.Throw(NS_ERROR_OUT_OF_MEMORY);
180
0
    return nullptr;
181
0
  }
182
0
183
0
  nsINode::InsertBefore(*cell, nextSibling, aError);
184
0
185
0
  return cell.forget();
186
0
}
187
188
void
189
HTMLTableRowElement::DeleteCell(int32_t aValue, ErrorResult& aError)
190
0
{
191
0
  if (aValue < -1) {
192
0
    aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
193
0
    return;
194
0
  }
195
0
196
0
  nsIHTMLCollection* cells = Cells();
197
0
198
0
  uint32_t refIndex;
199
0
  if (aValue == -1) {
200
0
    refIndex = cells->Length();
201
0
    if (refIndex == 0) {
202
0
      return;
203
0
    }
204
0
205
0
    --refIndex;
206
0
  }
207
0
  else {
208
0
    refIndex = (uint32_t)aValue;
209
0
  }
210
0
211
0
  nsCOMPtr<nsINode> cell = cells->Item(refIndex);
212
0
  if (!cell) {
213
0
    aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
214
0
    return;
215
0
  }
216
0
217
0
  nsINode::RemoveChild(*cell, aError);
218
0
}
219
220
bool
221
HTMLTableRowElement::ParseAttribute(int32_t aNamespaceID,
222
                                    nsAtom* aAttribute,
223
                                    const nsAString& aValue,
224
                                    nsIPrincipal* aMaybeScriptedPrincipal,
225
                                    nsAttrValue& aResult)
226
0
{
227
0
  /*
228
0
   * ignore these attributes, stored simply as strings
229
0
   *
230
0
   * ch
231
0
   */
232
0
233
0
  if (aNamespaceID == kNameSpaceID_None) {
234
0
    if (aAttribute == nsGkAtoms::charoff) {
235
0
      return aResult.ParseIntWithBounds(aValue, 0);
236
0
    }
237
0
    if (aAttribute == nsGkAtoms::height) {
238
0
      return aResult.ParseSpecialIntValue(aValue);
239
0
    }
240
0
    if (aAttribute == nsGkAtoms::width) {
241
0
      return aResult.ParseSpecialIntValue(aValue);
242
0
    }
243
0
    if (aAttribute == nsGkAtoms::align) {
244
0
      return ParseTableCellHAlignValue(aValue, aResult);
245
0
    }
246
0
    if (aAttribute == nsGkAtoms::bgcolor) {
247
0
      return aResult.ParseColor(aValue);
248
0
    }
249
0
    if (aAttribute == nsGkAtoms::valign) {
250
0
      return ParseTableVAlignValue(aValue, aResult);
251
0
    }
252
0
  }
253
0
254
0
  return nsGenericHTMLElement::ParseBackgroundAttribute(aNamespaceID,
255
0
                                                        aAttribute, aValue,
256
0
                                                        aResult) ||
257
0
         nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
258
0
                                              aMaybeScriptedPrincipal, aResult);
259
0
}
260
261
void
262
HTMLTableRowElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
263
                                           MappedDeclarations& aDecls)
264
0
{
265
0
  nsGenericHTMLElement::MapHeightAttributeInto(aAttributes, aDecls);
266
0
  nsGenericHTMLElement::MapDivAlignAttributeInto(aAttributes, aDecls);
267
0
  nsGenericHTMLElement::MapVAlignAttributeInto(aAttributes, aDecls);
268
0
  nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aDecls);
269
0
  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
270
0
}
271
272
NS_IMETHODIMP_(bool)
273
HTMLTableRowElement::IsAttributeMapped(const nsAtom* aAttribute) const
274
0
{
275
0
  static const MappedAttributeEntry attributes[] = {
276
0
    { &nsGkAtoms::align },
277
0
    { &nsGkAtoms::valign },
278
0
    { &nsGkAtoms::height },
279
0
    { nullptr }
280
0
  };
281
0
282
0
  static const MappedAttributeEntry* const map[] = {
283
0
    attributes,
284
0
    sCommonAttributeMap,
285
0
    sBackgroundAttributeMap,
286
0
  };
287
0
288
0
  return FindAttributeDependence(aAttribute, map);
289
0
}
290
291
nsMapRuleToAttributesFunc
292
HTMLTableRowElement::GetAttributeMappingFunction() const
293
0
{
294
0
  return &MapAttributesIntoRule;
295
0
}
296
297
} // namespace dom
298
} // namespace mozilla