void ElementImpl::recalcStyle( StyleChange change )
{
    // ### should go away and be done in renderobject
    RenderStyle* _style = m_render ? m_render->style() : 0;
    bool hasParentRenderer = parent() ? parent()->renderer() : false;
    
#if 0
    const char* debug;
    switch(change) {
    case NoChange: debug = "NoChange";
        break;
    case NoInherit: debug= "NoInherit";
        break;
    case Inherit: debug = "Inherit";
        break;
    case Force: debug = "Force";
        break;
    }
    qDebug("recalcStyle(%d: %s)[%p: %s]", change, debug, this, tagName().string().latin1());
#endif
    if ( hasParentRenderer && (change >= Inherit || changed()) ) {
        RenderStyle *newStyle = getDocument()->styleSelector()->styleForElement(this);
        newStyle->ref();
        StyleChange ch = diff( _style, newStyle );
        if (ch == Detach) {
            if (attached()) detach();
            // ### Suboptimal. Style gets calculated again.
            attach();
            // attach recalulates the style for all children. No need to do it twice.
            setChanged( false );
            setHasChangedChild( false );
            newStyle->deref(getDocument()->renderArena());
            return;
        }
        else if (ch != NoChange) {
            if( m_render && newStyle ) {
                //qDebug("--> setting style on render element bgcolor=%s", newStyle->backgroundColor().name().latin1());
                m_render->setStyle(newStyle);
            }
        }
        else if (changed() && m_render && newStyle && (getDocument()->usesSiblingRules() || getDocument()->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.
            m_render->setStyleInternal(newStyle);
        }

        newStyle->deref(getDocument()->renderArena());

        if ( change != Force) {
            if (getDocument()->usesDescendantRules())
                change = Force;
            else
                change = ch;
        }
    }

    NodeImpl *n;
    for (n = _first; n; n = n->nextSibling()) {
	//qDebug("    (%p) calling recalcStyle on child %s/%p, change=%d", this, n, n->isElementNode() ? ((ElementImpl *)n)->tagName().string().latin1() : n->isTextNode() ? "text" : "unknown", change );
        if ( change >= Inherit || n->isTextNode() ||
             n->hasChangedChild() || n->changed() )
            n->recalcStyle( change );
    }

    setChanged( false );
    setHasChangedChild( false );
}
예제 #2
0
void ElementImpl::recalcStyle(StyleChange change)
{
    // ### should go away and be done in renderobject
    RenderStyle *_style = m_render ? m_render->style() : 0;
    bool hasParentRenderer = parent() ? parent()->attached() : false;

#if 0
    const char* debug;
    switch(change) {
    case NoChange: debug = "NoChange";
        break;
    case NoInherit: debug= "NoInherit";
        break;
    case Inherit: debug = "Inherit";
        break;
    case Force: debug = "Force";
        break;
    }
    qDebug("recalcStyle(%d: %s, changed: %d)[%p: %s]", change, debug, changed(), this, tagName().string().latin1());
#endif
    if(hasParentRenderer && (change >= Inherit || changed()))
    {
        RenderStyle *newStyle = getDocument()->styleSelector()->styleForElement(this);
        newStyle->ref();
        StyleChange ch = diff(_style, newStyle);
        if(ch == Detach)
        {
            if(attached())
                detach();
            // ### Suboptimal. Style gets calculated again.
            attach();
            // attach recalulates the style for all children. No need to do it twice.
            setChanged(false);
            setHasChangedChild(false);
            newStyle->deref();
            return;
        }
        else if(ch != NoChange)
        {
            if(m_render && newStyle)
            {
                m_render->setStyle(newStyle);
            }
        }
        newStyle->deref();

        if(change != Force)
            change = ch;
    }
    // If a changed attribute has ancestor dependencies, restyle all children
    if(changedAscendentAttribute())
    {
        change = Force;
        setChangedAscendentAttribute(false);
    }

    NodeImpl *n;
    for(n = _first; n; n = n->nextSibling())
    {
        if(change >= Inherit || n->isTextNode() || n->hasChangedChild() || n->changed())
        {
            // qDebug("    (%p) calling recalcStyle on child %p/%s, change=%d", this, n, n->isElementNode() ? ((ElementImpl
            // *)n)->tagName().string().latin1() : n->isTextNode() ? "text" : "unknown", change );
            n->recalcStyle(change);
        }
    }

    setChanged(false);
    setHasChangedChild(false);
}