HTMLTableElement* HTMLTablePartElement::findParentTable() const
{
    ContainerNode* parent = parentNode();
    while (parent && !is<HTMLTableElement>(*parent))
        parent = parent->parentNode();
    return downcast<HTMLTableElement>(parent);
}
Пример #2
0
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);
}
Пример #3
0
HTMLFormElement* HTMLElement::findFormAncestor() const
{
    for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
        if (isHTMLFormElement(ancestor))
            return toHTMLFormElement(ancestor);
    }
    return 0;
}
Пример #4
0
HTMLFormElement* HTMLElement::findFormAncestor() const
{
    for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
        if (ancestor->hasTagName(formTag))
            return static_cast<HTMLFormElement*>(ancestor);
    }
    return 0;
}
Пример #5
0
HTMLDataListElement* HTMLOptionElement::ownerDataListElement() const
{
    for (ContainerNode* parent = parentNode(); parent ; parent = parent->parentNode()) {
        if (is<HTMLDataListElement>(*parent))
            return downcast<HTMLDataListElement>(parent);
    }
    return nullptr;
}
Пример #6
0
HTMLDataListElement* HTMLOptionElement::ownerDataListElement() const
{
    for (ContainerNode* parent = parentNode(); parent ; parent = parent->parentNode()) {
        if (parent->hasTagName(datalistTag))
            return static_cast<HTMLDataListElement*>(parent);
    }
    return 0;
}
Пример #7
0
void HTMLOptGroupElement::recalcSelectOptions()
{
    ContainerNode* select = parentNode();
    while (select && !select->hasTagName(selectTag))
        select = select->parentNode();
    if (select)
        toHTMLSelectElement(select)->setRecalcListItems();
}
Пример #8
0
// 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);
}
Пример #9
0
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;
}
Пример #10
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;
}
Пример #11
0
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);
}
Пример #12
0
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);
}
Пример #14
0
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());
    }
}
Пример #16
0
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;
}
Пример #17
0
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();
}
Пример #18
0
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;
}
Пример #19
0
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();
}
Пример #21
0
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);
}
Пример #22
0
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;
}
Пример #25
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;
}
Пример #26
0
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;
}
Пример #27
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);
}
Пример #28
0
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();
    }
}
Пример #29
0
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;
}
Пример #30
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;
    }
}