示例#1
0
bool HTMLOptGroupElement::isFocusable() const
{
    // Optgroup elements do not have a renderer so we check the renderStyle instead.
    return supportsFocus() && renderStyle() && renderStyle()->display() != NONE;
}
void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
    ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
    if (!changedByParser)
        checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta);
}
void Element::finishParsingChildren()
{
    ContainerNode::finishParsingChildren();
    m_parsingChildrenFinished = true;
    checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0);
}
void Element::recalcStyle(StyleChange change)
{
    RenderStyle* currentStyle = renderStyle();
    bool hasParentStyle = parentNode() ? parentNode()->renderStyle() : false;
    bool hasPositionalRules = changed() && currentStyle && currentStyle->childrenAffectedByPositionalRules();
    bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByDirectAdjacentRules();

#if ENABLE(SVG)
    if (!hasParentStyle && isShadowNode() && isSVGElement())
        hasParentStyle = true;
#endif

    if ((change > NoChange || changed())) {
        if (hasRareData())
            rareData()->resetComputedStyle();
    }
    if (hasParentStyle && (change >= Inherit || changed())) {
        RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(this);
        StyleChange ch = diff(currentStyle, newStyle.get());
        if (ch == Detach || !currentStyle) {
            if (attached())
                detach();
            attach(); // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along.
            // attach recalulates the style for all children. No need to do it twice.
            setChanged(NoStyleChange);
            setHasChangedChild(false);
            return;
        }

        if (currentStyle) {
            // Preserve "affected by" bits that were propagated to us from descendants in the case where we didn't do a full
            // style change (e.g., only inline style changed).
            if (currentStyle->affectedByHoverRules())
                newStyle->setAffectedByHoverRules(true);
            if (currentStyle->affectedByActiveRules())
                newStyle->setAffectedByActiveRules(true);
            if (currentStyle->affectedByDragRules())
                newStyle->setAffectedByDragRules(true);
            if (currentStyle->childrenAffectedByForwardPositionalRules())
                newStyle->setChildrenAffectedByForwardPositionalRules();
            if (currentStyle->childrenAffectedByBackwardPositionalRules())
                newStyle->setChildrenAffectedByBackwardPositionalRules();
            if (currentStyle->childrenAffectedByFirstChildRules())
                newStyle->setChildrenAffectedByFirstChildRules();
            if (currentStyle->childrenAffectedByLastChildRules())
                newStyle->setChildrenAffectedByLastChildRules();
            if (currentStyle->childrenAffectedByDirectAdjacentRules())
                newStyle->setChildrenAffectedByDirectAdjacentRules();
        }

        if (ch != NoChange) {
            setRenderStyle(newStyle);
        } else if (changed() && (styleChangeType() != AnimationStyleChange) && (document()->usesSiblingRules() || document()->usesDescendantRules())) {
            // Although no change occurred, we use the new style so that the cousin style sharing code won't get
            // fooled into believing this style is the same.  This is only necessary if the document actually uses
            // sibling/descendant rules, since otherwise it isn't possible for ancestor styles to affect sharing of
            // descendants.
            if (renderer())
                renderer()->setStyleInternal(newStyle.get());
            else
                setRenderStyle(newStyle);
        } else if (styleChangeType() == AnimationStyleChange)
             setRenderStyle(newStyle);

        if (change != Force) {
            if ((document()->usesDescendantRules() || hasPositionalRules) && styleChangeType() >= FullStyleChange)
                change = Force;
            else
                change = ch;
        }
    }

    // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar.
    // For now we will just worry about the common case, since it's a lot trickier to get the second case right
    // without doing way too much re-resolution.
    bool forceCheckOfNextElementSibling = false;
    for (Node *n = firstChild(); n; n = n->nextSibling()) {
        bool childRulesChanged = n->changed() && n->styleChangeType() == FullStyleChange;
        if (forceCheckOfNextElementSibling && n->isElementNode())
            n->setChanged();
        if (change >= Inherit || n->isTextNode() || n->hasChangedChild() || n->changed())
            n->recalcStyle(change);
        if (n->isElementNode())
            forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
    }

    setChanged(NoStyleChange);
    setHasChangedChild(false);
}