tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

HTMLTableRowElement.cpp (7330B)


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