HTMLTableElement* HTMLTablePartElement::findParentTable() const { ContainerNode* parent = parentNode(); while (parent && !is<HTMLTableElement>(*parent)) parent = parent->parentNode(); return downcast<HTMLTableElement>(parent); }
void SelectorDataList::findTraverseRootsAndExecute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const { // We need to return the matches in document order. To use id lookup while there is possiblity of multiple matches // we would need to sort the results. For now, just traverse the document in that case. ASSERT(m_selectors.size() == 1); bool isRightmostSelector = true; bool startFromParent = false; Element* singleMatchingElement = 0; for (const CSSSelector* selector = &m_selectors[0].selector; selector; selector = selector->tagHistory()) { if (selector->m_match == CSSSelector::Id && (rootNode.document().getNumberOfElementsWithId(selector->value(), singleMatchingElement) <= 1)) { ContainerNode* adjustedNode = &rootNode; if (singleMatchingElement && (isTreeScopeRoot(rootNode) || singleMatchingElement->isDescendantOf(&rootNode))) adjustedNode = singleMatchingElement; else if (!singleMatchingElement || isRightmostSelector) adjustedNode = 0; if (isRightmostSelector) { executeForTraverseRoot<SelectorQueryTrait>(m_selectors[0], adjustedNode, MatchesTraverseRoots, rootNode, output); return; } if (startFromParent && adjustedNode) adjustedNode = adjustedNode->parentNode(); executeForTraverseRoot<SelectorQueryTrait>(m_selectors[0], adjustedNode, DoesNotMatchTraverseRoots, rootNode, output); return; } // If we have both CSSSelector::Id and CSSSelector::Class at the same time, we should use Id // to find traverse root. if (!SelectorQueryTrait::shouldOnlyMatchFirstElement && !startFromParent && selector->m_match == CSSSelector::Class) { if (isRightmostSelector) { ClassElementList<AllElements> traverseRoots(rootNode, selector->value()); executeForTraverseRoots<SelectorQueryTrait>(m_selectors[0], traverseRoots, MatchesTraverseRoots, rootNode, output); return; } // Since there exists some ancestor element which has the class name, we need to see all children of rootNode. if (ancestorHasClassName(rootNode, selector->value())) { executeForTraverseRoot<SelectorQueryTrait>(m_selectors[0], &rootNode, DoesNotMatchTraverseRoots, rootNode, output); return; } ClassElementList<OnlyRoots> traverseRoots(rootNode, selector->value()); executeForTraverseRoots<SelectorQueryTrait>(m_selectors[0], traverseRoots, DoesNotMatchTraverseRoots, rootNode, output); return; } if (selector->relation() == CSSSelector::SubSelector) continue; isRightmostSelector = false; if (selector->relation() == CSSSelector::DirectAdjacent || selector->relation() == CSSSelector::IndirectAdjacent) startFromParent = true; else startFromParent = false; } executeForTraverseRoot<SelectorQueryTrait>(m_selectors[0], &rootNode, DoesNotMatchTraverseRoots, rootNode, output); }
HTMLFormElement* HTMLElement::findFormAncestor() const { for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) { if (isHTMLFormElement(ancestor)) return toHTMLFormElement(ancestor); } return 0; }
HTMLFormElement* HTMLElement::findFormAncestor() const { for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) { if (ancestor->hasTagName(formTag)) return static_cast<HTMLFormElement*>(ancestor); } return 0; }
HTMLDataListElement* HTMLOptionElement::ownerDataListElement() const { for (ContainerNode* parent = parentNode(); parent ; parent = parent->parentNode()) { if (is<HTMLDataListElement>(*parent)) return downcast<HTMLDataListElement>(parent); } return nullptr; }
HTMLDataListElement* HTMLOptionElement::ownerDataListElement() const { for (ContainerNode* parent = parentNode(); parent ; parent = parent->parentNode()) { if (parent->hasTagName(datalistTag)) return static_cast<HTMLDataListElement*>(parent); } return 0; }
void HTMLOptGroupElement::recalcSelectOptions() { ContainerNode* select = parentNode(); while (select && !select->hasTagName(selectTag)) select = select->parentNode(); if (select) toHTMLSelectElement(select)->setRecalcListItems(); }
// used by table cells to share style decls created by the enclosing table. void HTMLTableCellElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>& results) { ContainerNode* p = parentNode(); while (p && !p->hasTagName(tableTag)) p = p->parentNode(); if (!p) return; static_cast<HTMLTableElement*>(p)->addSharedCellDecls(results); }
SVGElement* SVGLocatable::nearestViewportElement(const SVGElement* element) { ASSERT(element); for (ContainerNode* n = element->parentNode(); n; n = n->parentNode()) { if (isViewportElement(n)) return static_cast<SVGElement*>(n); } return 0; }
SVGElement* SVGLocatable::farthestViewportElement(const SVGElement* element) { ASSERT(element); SVGElement* farthest = 0; for (ContainerNode* n = element->parentNode(); n; n = n->parentNode()) { if (isViewportElement(n)) farthest = static_cast<SVGElement*>(n); } return farthest; }
HTMLSelectElement* HTMLOptionElement::ownerSelectElement() const { ContainerNode* select = parentNode(); while (select && !(select->hasTagName(selectTag) || select->hasTagName(keygenTag))) select = select->parentNode(); if (!select) return 0; return static_cast<HTMLSelectElement*>(select); }
HTMLSelectElement* HTMLOptionElement::ownerSelectElement() const { ContainerNode* select = parentNode(); while (select && !is<HTMLSelectElement>(*select)) select = select->parentNode(); if (!select) return nullptr; return downcast<HTMLSelectElement>(select); }
static inline WMLSelectElement* ownerSelectElement(Element* element) { ContainerNode* select = element->parentNode(); while (select && !select->hasTagName(selectTag)) select = select->parentNode(); if (!select) return 0; return static_cast<WMLSelectElement*>(select); }
HTMLSelectElement* HTMLOptionElement::ownerSelectElement() const { ContainerNode* select = parentNode(); while (select && !select->hasTagName(selectTag)) select = select->parentNode(); if (!select) return 0; return toHTMLSelectElement(select); }
void HTMLEmbedElement::attributeChanged(Attribute* attr, bool preserveDecls) { HTMLPlugInImageElement::attributeChanged(attr, preserveDecls); if ((attr->name() == widthAttr || attr->name() == heightAttr) && !attr->isEmpty()) { ContainerNode* n = parentNode(); while (n && !n->hasTagName(objectTag)) n = n->parentNode(); if (n) static_cast<HTMLObjectElement*>(n)->setAttribute(attr->name(), attr->value()); } }
void HTMLFormControlElement::updateAncestorDisabledState() const { HTMLFieldSetElement* fieldSetAncestor = 0; ContainerNode* legendAncestor = 0; for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) { if (!legendAncestor && ancestor->hasTagName(legendTag)) legendAncestor = ancestor; if (ancestor->hasTagName(fieldsetTag)) { fieldSetAncestor = toHTMLFieldSetElement(ancestor); break; } } m_ancestorDisabledState = (fieldSetAncestor && fieldSetAncestor->isDisabledFormControl() && !(legendAncestor && legendAncestor == fieldSetAncestor->legend())) ? AncestorDisabledStateDisabled : AncestorDisabledStateEnabled; }
bool HTMLFormControlElement::recalcWillValidate() const { if (m_dataListAncestorState == Unknown) { for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) { if (ancestor->hasTagName(datalistTag)) { m_dataListAncestorState = InsideDataList; break; } } if (m_dataListAncestorState == Unknown) m_dataListAncestorState = NotInsideDataList; } return m_dataListAncestorState == NotInsideDataList && !isDisabledOrReadOnly(); }
void HTMLFormControlElement::updateFieldSetAndLegendAncestor() const { m_fieldSetAncestor = 0; m_legendAncestor = 0; for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) { if (!m_legendAncestor && ancestor->hasTagName(legendTag)) m_legendAncestor = static_cast<HTMLLegendElement*>(ancestor); if (ancestor->hasTagName(fieldsetTag)) { m_fieldSetAncestor = static_cast<HTMLFieldSetElement*>(ancestor); break; } } m_fieldSetAncestorValid = true; }
int HTMLTableRowElement::rowIndex() const { ContainerNode* table = parentNode(); if (!table) return -1; table = table->parentNode(); if (!table || !table->hasTagName(tableTag)) return -1; // To match Firefox, the row indices work like this: // Rows from the first <thead> are numbered before all <tbody> rows. // Rows from the first <tfoot> are numbered after all <tbody> rows. // Rows from other <thead> and <tfoot> elements don't get row indices at all. int rIndex = 0; if (HTMLTableSectionElement* head = static_cast<HTMLTableElement*>(table)->tHead()) { for (Node *row = head->firstChild(); row; row = row->nextSibling()) { if (row == this) return rIndex; if (row->hasTagName(trTag)) ++rIndex; } } for (Node *node = table->firstChild(); node; node = node->nextSibling()) { if (node->hasTagName(tbodyTag)) { HTMLTableSectionElement* section = static_cast<HTMLTableSectionElement*>(node); for (Node* row = section->firstChild(); row; row = row->nextSibling()) { if (row == this) return rIndex; if (row->hasTagName(trTag)) ++rIndex; } } } if (HTMLTableSectionElement* foot = static_cast<HTMLTableElement*>(table)->tFoot()) { for (Node *row = foot->firstChild(); row; row = row->nextSibling()) { if (row == this) return rIndex; if (row->hasTagName(trTag)) ++rIndex; } } // We get here for rows that are in <thead> or <tfoot> sections other than the main header and footer. return -1; }
void SVGFontFaceFormatElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); if (!parentNode() || !parentNode()->hasTagName(font_face_uriTag)) return; ContainerNode* ancestor = parentNode()->parentNode(); if (!ancestor || !ancestor->hasTagName(font_face_srcTag)) return; ancestor = ancestor->parentNode(); if (ancestor && ancestor->hasTagName(font_faceTag)) static_cast<SVGFontFaceElement*>(ancestor)->rebuildFontFace(); }
void HTMLImageElement::insertedIntoTree(bool deep) { if (!m_form) { // m_form can be non-null if it was set in constructor. for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) { if (ancestor->hasTagName(formTag)) { m_form = static_cast<HTMLFormElement*>(ancestor); m_form->registerImgElement(this); break; } } } HTMLElement::insertedIntoTree(deep); }
void SVGFontFaceFormatElement::childrenChanged(const ChildChange& change) { SVGElement::childrenChanged(change); if (!parentNode() || !parentNode()->hasTagName(font_face_uriTag)) return; ContainerNode* ancestor = parentNode()->parentNode(); if (!ancestor || !ancestor->hasTagName(font_face_srcTag)) return; ancestor = ancestor->parentNode(); if (ancestor && ancestor->hasTagName(font_faceTag)) toSVGFontFaceElement(ancestor)->rebuildFontFace(); }
void SVGFontFaceFormatElement::childrenChanged(const ChildrenChange& change) { SVGElement::childrenChanged(change); if (!isSVGFontFaceUriElement(parentNode())) return; ContainerNode* ancestor = parentNode()->parentNode(); if (!isSVGFontFaceSrcElement(ancestor)) return; ancestor = ancestor->parentNode(); if (isSVGFontFaceElement(ancestor)) toSVGFontFaceElement(ancestor)->rebuildFontFace(); }
HTMLElement* enclosingList(Node* node) { if (!node) return 0; Node* root = highestEditableRoot(firstPositionInOrBeforeNode(node)); for (ContainerNode* n = node->parentNode(); n; n = n->parentNode()) { if (n->hasTagName(ulTag) || n->hasTagName(olTag)) return toHTMLElement(n); if (n == root) return 0; } return 0; }
int HTMLTableRowElement::rowIndex() const { ContainerNode* table = parentNode(); if (!table) return -1; table = table->parentNode(); if (!isHTMLTableElement(table)) return -1; // To match Firefox, the row indices work like this: // Rows from the first <thead> are numbered before all <tbody> rows. // Rows from the first <tfoot> are numbered after all <tbody> rows. // Rows from other <thead> and <tfoot> elements don't get row indices at all. int rIndex = 0; if (HTMLTableSectionElement* head = toHTMLTableElement(table)->tHead()) { for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*head); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) { if (row == this) return rIndex; ++rIndex; } } for (Element* child = ElementTraversal::firstWithin(*table); child; child = ElementTraversal::nextSibling(*child)) { if (child->hasTagName(tbodyTag)) { HTMLTableSectionElement* section = toHTMLTableSectionElement(child); for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*section); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) { if (row == this) return rIndex; ++rIndex; } } } if (HTMLTableSectionElement* foot = toHTMLTableElement(table)->tFoot()) { for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*foot); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) { if (row == this) return rIndex; ++rIndex; } } // We get here for rows that are in <thead> or <tfoot> sections other than the main header and footer. return -1; }
static Node* ancestorToRetainStructureAndAppearanceForBlock(Node* commonAncestorBlock) { if (!commonAncestorBlock) return 0; if (commonAncestorBlock->hasTagName(tbodyTag) || commonAncestorBlock->hasTagName(trTag)) { ContainerNode* table = commonAncestorBlock->parentNode(); while (table && !table->hasTagName(tableTag)) table = table->parentNode(); return table; } if (isNonTableCellHTMLBlockElement(commonAncestorBlock)) return commonAncestorBlock; return 0; }
Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode* insertionPoint) { if (!m_form) { // m_form can be non-null if it was set in constructor. for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) { if (ancestor->hasTagName(formTag)) { m_form = static_cast<HTMLFormElement*>(ancestor); m_form->registerImgElement(this); break; } } } // If we have been inserted from a renderer-less document, // our loader may have not fetched the image, so do it now. if (insertionPoint->inDocument() && !m_imageLoader.image()) m_imageLoader.updateFromElement(); return HTMLElement::insertedInto(insertionPoint); }
void HTMLFrameSetElement::willAttachRenderers() { // Inherit default settings from parent frameset // FIXME: This is not dynamic. for (ContainerNode* node = parentNode(); node; node = node->parentNode()) { if (!node->hasTagName(framesetTag)) continue; HTMLFrameSetElement* frameset = static_cast<HTMLFrameSetElement*>(node); if (!m_frameborderSet) m_frameborder = frameset->hasFrameBorder(); if (m_frameborder) { if (!m_borderSet) m_border = frameset->border(); if (!m_borderColorSet) m_borderColorSet = frameset->hasBorderColor(); } if (!m_noresize) m_noresize = frameset->noResize(); } }
HTMLFormControlElement* HTMLLegendElement::associatedControl() { // Check if there's a fieldset belonging to this legend. ContainerNode* fieldset = parentNode(); while (fieldset && !fieldset->hasTagName(fieldsetTag)) fieldset = fieldset->parentNode(); if (!fieldset) return 0; // Find first form element inside the fieldset that is not a legend element. // FIXME: Should we consider tabindex? Node* node = fieldset; while ((node = node->traverseNextNode(fieldset))) { if (node->isElementNode()) { Element* element = static_cast<Element*>(node); if (!element->hasLocalName(legendTag) && element->isFormControlElement()) return static_cast<HTMLFormControlElement*>(element); } } return 0; }
void SVGStyledElement::updateRelativeLengthsInformation(bool hasRelativeLengths, SVGStyledElement* element) { // If we're not yet in a document, this function will be called again from insertedIntoDocument(). Do nothing now. if (!inDocument()) return; // An element wants to notify us that its own relative lengths state changed. // Register it in the relative length map, and register us in the parent relative length map. // Register the parent in the grandparents map, etc. Repeat procedure until the root of the SVG tree. if (hasRelativeLengths) m_elementsWithRelativeLengths.add(element); else { if (!m_elementsWithRelativeLengths.contains(element)) { // We were never registered. Do nothing. return; } m_elementsWithRelativeLengths.remove(element); } // Find first styled parent node, and notify it that we've changed our relative length state. ContainerNode* node = parentNode(); while (node) { if (!node->isSVGElement()) break; SVGElement* element = static_cast<SVGElement*>(node); if (!element->isStyled()) { node = node->parentNode(); continue; } // Register us in the parent element map. static_cast<SVGStyledElement*>(element)->updateRelativeLengthsInformation(hasRelativeLengths, this); break; } }