HTMLTableSectionElement.cpp (5608B)
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/HTMLTableSectionElement.h" 8 9 #include "mozilla/MappedDeclarationsBuilder.h" 10 #include "mozilla/dom/BindingUtils.h" 11 #include "mozilla/dom/HTMLTableSectionElementBinding.h" 12 #include "nsAttrValueInlines.h" 13 #include "nsContentUtils.h" 14 15 NS_IMPL_NS_NEW_HTML_ELEMENT(TableSection) 16 17 namespace mozilla::dom { 18 19 // you will see the phrases "rowgroup" and "section" used interchangably 20 21 HTMLTableSectionElement::~HTMLTableSectionElement() = default; 22 23 JSObject* HTMLTableSectionElement::WrapNode(JSContext* aCx, 24 JS::Handle<JSObject*> aGivenProto) { 25 return HTMLTableSectionElement_Binding::Wrap(aCx, this, aGivenProto); 26 } 27 28 NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLTableSectionElement, 29 nsGenericHTMLElement, mRows) 30 31 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(HTMLTableSectionElement, 32 nsGenericHTMLElement) 33 34 NS_IMPL_ELEMENT_CLONE(HTMLTableSectionElement) 35 36 nsIHTMLCollection* HTMLTableSectionElement::Rows() { 37 if (!mRows) { 38 mRows = new nsContentList(this, mNodeInfo->NamespaceID(), nsGkAtoms::tr, 39 nsGkAtoms::tr, false); 40 } 41 42 return mRows; 43 } 44 45 already_AddRefed<nsGenericHTMLElement> HTMLTableSectionElement::InsertRow( 46 int32_t aIndex, ErrorResult& aError) { 47 if (aIndex < -1) { 48 aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); 49 return nullptr; 50 } 51 52 nsIHTMLCollection* rows = Rows(); 53 54 uint32_t rowCount = rows->Length(); 55 if (aIndex > (int32_t)rowCount) { 56 aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); 57 return nullptr; 58 } 59 60 bool doInsert = (aIndex < int32_t(rowCount)) && (aIndex != -1); 61 62 // create the row 63 RefPtr<mozilla::dom::NodeInfo> nodeInfo; 64 nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::tr, 65 getter_AddRefs(nodeInfo)); 66 67 RefPtr<nsGenericHTMLElement> rowContent = 68 NS_NewHTMLTableRowElement(nodeInfo.forget()); 69 if (!rowContent) { 70 aError.Throw(NS_ERROR_OUT_OF_MEMORY); 71 return nullptr; 72 } 73 74 if (doInsert) { 75 nsCOMPtr<nsINode> refNode = rows->Item(aIndex); 76 nsINode::InsertBefore(*rowContent, refNode, aError); 77 } else { 78 nsINode::AppendChild(*rowContent, aError); 79 } 80 return rowContent.forget(); 81 } 82 83 void HTMLTableSectionElement::DeleteRow(int32_t aValue, ErrorResult& aError) { 84 if (aValue < -1) { 85 aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); 86 return; 87 } 88 89 nsIHTMLCollection* rows = Rows(); 90 91 uint32_t refIndex; 92 if (aValue == -1) { 93 refIndex = rows->Length(); 94 if (refIndex == 0) { 95 return; 96 } 97 98 --refIndex; 99 } else { 100 refIndex = (uint32_t)aValue; 101 } 102 103 nsCOMPtr<nsINode> row = rows->Item(refIndex); 104 if (!row) { 105 aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); 106 return; 107 } 108 109 nsINode::RemoveChild(*row, aError); 110 } 111 112 bool HTMLTableSectionElement::ParseAttribute( 113 int32_t aNamespaceID, nsAtom* aAttribute, const nsAString& aValue, 114 nsIPrincipal* aMaybeScriptedPrincipal, nsAttrValue& aResult) { 115 if (aNamespaceID == kNameSpaceID_None) { 116 /* ignore these attributes, stored simply as strings 117 ch 118 */ 119 if (aAttribute == nsGkAtoms::height) { 120 // Per HTML spec there should be nothing special here, but all browsers 121 // implement height mapping to style. See 122 // <https://github.com/whatwg/html/issues/4718>. All browsers allow 0, so 123 // keep doing that. 124 return aResult.ParseHTMLDimension(aValue); 125 } 126 if (aAttribute == nsGkAtoms::align) { 127 return ParseTableCellHAlignValue(aValue, aResult); 128 } 129 if (aAttribute == nsGkAtoms::bgcolor) { 130 return aResult.ParseColor(aValue); 131 } 132 if (aAttribute == nsGkAtoms::valign) { 133 return ParseTableVAlignValue(aValue, aResult); 134 } 135 } 136 137 return nsGenericHTMLElement::ParseBackgroundAttribute( 138 aNamespaceID, aAttribute, aValue, aResult) || 139 nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue, 140 aMaybeScriptedPrincipal, aResult); 141 } 142 143 void HTMLTableSectionElement::MapAttributesIntoRule( 144 MappedDeclarationsBuilder& aBuilder) { 145 // height: value 146 if (!aBuilder.PropertyIsSet(eCSSProperty_height)) { 147 const nsAttrValue* value = aBuilder.GetAttr(nsGkAtoms::height); 148 if (value && value->Type() == nsAttrValue::eInteger) { 149 aBuilder.SetPixelValue(eCSSProperty_height, 150 (float)value->GetIntegerValue()); 151 } 152 } 153 nsGenericHTMLElement::MapTableCellHAlignAttributeInto(aBuilder); 154 nsGenericHTMLElement::MapTableVAlignAttributeInto(aBuilder); 155 nsGenericHTMLElement::MapBackgroundAttributesInto(aBuilder); 156 nsGenericHTMLElement::MapCommonAttributesInto(aBuilder); 157 } 158 159 NS_IMETHODIMP_(bool) 160 HTMLTableSectionElement::IsAttributeMapped(const nsAtom* aAttribute) const { 161 static const MappedAttributeEntry attributes[] = { 162 {nsGkAtoms::align}, {nsGkAtoms::valign}, {nsGkAtoms::height}, {nullptr}}; 163 164 static const MappedAttributeEntry* const map[] = { 165 attributes, 166 sCommonAttributeMap, 167 sBackgroundAttributeMap, 168 }; 169 170 return FindAttributeDependence(aAttribute, map); 171 } 172 173 nsMapRuleToAttributesFunc HTMLTableSectionElement::GetAttributeMappingFunction() 174 const { 175 return &MapAttributesIntoRule; 176 } 177 178 } // namespace mozilla::dom