diff options
Diffstat (limited to 'dom/html/HTMLTableCellElement.cpp')
-rw-r--r-- | dom/html/HTMLTableCellElement.cpp | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/dom/html/HTMLTableCellElement.cpp b/dom/html/HTMLTableCellElement.cpp new file mode 100644 index 0000000000..c260323a8b --- /dev/null +++ b/dom/html/HTMLTableCellElement.cpp @@ -0,0 +1,219 @@ +/* -*- 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/HTMLTableCellElement.h" +#include "mozilla/dom/Document.h" +#include "mozilla/dom/HTMLTableElement.h" +#include "mozilla/dom/HTMLTableRowElement.h" +#include "mozilla/MappedDeclarationsBuilder.h" +#include "nsAttrValueInlines.h" +#include "celldata.h" +#include "mozilla/dom/HTMLTableCellElementBinding.h" + +namespace { +enum class StyleCellScope : uint8_t { Row, Col, Rowgroup, Colgroup }; +} // namespace + +NS_IMPL_NS_NEW_HTML_ELEMENT(TableCell) + +namespace mozilla::dom { + +HTMLTableCellElement::~HTMLTableCellElement() = default; + +JSObject* HTMLTableCellElement::WrapNode(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) { + return HTMLTableCellElement_Binding::Wrap(aCx, this, aGivenProto); +} + +NS_IMPL_ELEMENT_CLONE(HTMLTableCellElement) + +// protected method +HTMLTableRowElement* HTMLTableCellElement::GetRow() const { + return HTMLTableRowElement::FromNodeOrNull(GetParent()); +} + +// protected method +HTMLTableElement* HTMLTableCellElement::GetTable() const { + nsIContent* parent = GetParent(); + if (!parent) { + return nullptr; + } + + // parent should be a row. + nsIContent* section = parent->GetParent(); + if (!section) { + return nullptr; + } + + if (section->IsHTMLElement(nsGkAtoms::table)) { + // XHTML, without a row group. + return static_cast<HTMLTableElement*>(section); + } + + // We have a row group. + nsIContent* result = section->GetParent(); + if (result && result->IsHTMLElement(nsGkAtoms::table)) { + return static_cast<HTMLTableElement*>(result); + } + + return nullptr; +} + +int32_t HTMLTableCellElement::CellIndex() const { + HTMLTableRowElement* row = GetRow(); + if (!row) { + return -1; + } + + nsIHTMLCollection* cells = row->Cells(); + if (!cells) { + return -1; + } + + uint32_t numCells = cells->Length(); + for (uint32_t i = 0; i < numCells; i++) { + if (cells->Item(i) == this) { + return i; + } + } + + return -1; +} + +StyleLockedDeclarationBlock* +HTMLTableCellElement::GetMappedAttributesInheritedFromTable() const { + if (HTMLTableElement* table = GetTable()) { + return table->GetAttributesMappedForCell(); + } + return nullptr; +} + +void HTMLTableCellElement::GetAlign(DOMString& aValue) { + if (!GetAttr(nsGkAtoms::align, aValue)) { + // There's no align attribute, ask the row for the alignment. + HTMLTableRowElement* row = GetRow(); + if (row) { + row->GetAlign(aValue); + } + } +} + +static const nsAttrValue::EnumTable kCellScopeTable[] = { + {"row", StyleCellScope::Row}, + {"col", StyleCellScope::Col}, + {"rowgroup", StyleCellScope::Rowgroup}, + {"colgroup", StyleCellScope::Colgroup}, + {nullptr, 0}}; + +void HTMLTableCellElement::GetScope(DOMString& aScope) { + GetEnumAttr(nsGkAtoms::scope, nullptr, aScope); +} + +bool HTMLTableCellElement::ParseAttribute(int32_t aNamespaceID, + nsAtom* aAttribute, + const nsAString& aValue, + nsIPrincipal* aMaybeScriptedPrincipal, + nsAttrValue& aResult) { + if (aNamespaceID == kNameSpaceID_None) { + /* ignore these attributes, stored simply as strings + abbr, axis, ch, headers + */ + if (aAttribute == nsGkAtoms::colspan) { + aResult.ParseClampedNonNegativeInt(aValue, 1, 1, MAX_COLSPAN); + return true; + } + if (aAttribute == nsGkAtoms::rowspan) { + aResult.ParseClampedNonNegativeInt(aValue, 1, 0, MAX_ROWSPAN); + // quirks mode does not honor the special html 4 value of 0 + if (aResult.GetIntegerValue() == 0 && InNavQuirksMode(OwnerDoc())) { + aResult.SetTo(1, &aValue); + } + return true; + } + if (aAttribute == nsGkAtoms::height) { + return aResult.ParseNonzeroHTMLDimension(aValue); + } + if (aAttribute == nsGkAtoms::width) { + return aResult.ParseNonzeroHTMLDimension(aValue); + } + if (aAttribute == nsGkAtoms::align) { + return ParseTableCellHAlignValue(aValue, aResult); + } + if (aAttribute == nsGkAtoms::bgcolor) { + return aResult.ParseColor(aValue); + } + if (aAttribute == nsGkAtoms::scope) { + return aResult.ParseEnumValue(aValue, kCellScopeTable, false); + } + if (aAttribute == nsGkAtoms::valign) { + return ParseTableVAlignValue(aValue, aResult); + } + } + + return nsGenericHTMLElement::ParseBackgroundAttribute( + aNamespaceID, aAttribute, aValue, aResult) || + nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue, + aMaybeScriptedPrincipal, aResult); +} + +void HTMLTableCellElement::MapAttributesIntoRule( + MappedDeclarationsBuilder& aBuilder) { + MapImageSizeAttributesInto(aBuilder); + + if (!aBuilder.PropertyIsSet(eCSSProperty_text_wrap_mode)) { + // nowrap: enum + if (aBuilder.GetAttr(nsGkAtoms::nowrap)) { + // See if our width is not a nonzero integer width. + const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::width); + nsCompatibility mode = aBuilder.Document().GetCompatibilityMode(); + if (!value || value->Type() != nsAttrValue::eInteger || + value->GetIntegerValue() == 0 || eCompatibility_NavQuirks != mode) { + aBuilder.SetKeywordValue(eCSSProperty_text_wrap_mode, + StyleTextWrapMode::Nowrap); + } + } + } + + nsGenericHTMLElement::MapDivAlignAttributeInto(aBuilder); + nsGenericHTMLElement::MapVAlignAttributeInto(aBuilder); + nsGenericHTMLElement::MapBackgroundAttributesInto(aBuilder); + nsGenericHTMLElement::MapCommonAttributesInto(aBuilder); +} + +NS_IMETHODIMP_(bool) +HTMLTableCellElement::IsAttributeMapped(const nsAtom* aAttribute) const { + static const MappedAttributeEntry attributes[] = { + {nsGkAtoms::align}, + {nsGkAtoms::valign}, + {nsGkAtoms::nowrap}, +#if 0 + // XXXldb If these are implemented, they might need to move to + // GetAttributeChangeHint (depending on how, and preferably not). + { nsGkAtoms::abbr }, + { nsGkAtoms::axis }, + { nsGkAtoms::headers }, + { nsGkAtoms::scope }, +#endif + {nsGkAtoms::width}, + {nsGkAtoms::height}, + {nullptr} + }; + + static const MappedAttributeEntry* const map[] = { + attributes, + sCommonAttributeMap, + sBackgroundAttributeMap, + }; + + return FindAttributeDependence(aAttribute, map); +} + +nsMapRuleToAttributesFunc HTMLTableCellElement::GetAttributeMappingFunction() + const { + return &MapAttributesIntoRule; +} + +} // namespace mozilla::dom |