pseudo element patch part 2

David Hyatt hyatt at apple.com
Thu Oct 23 16:33:30 CEST 2003


Here's the rest of it.  first-letter/line inheritance are much better 
now with this patch.

-------------- next part --------------
Index: khtml/rendering/render_block.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_block.cpp,v
retrieving revision 1.69
diff -u -p -r1.69 khtml/rendering/render_block.cpp
--- khtml/rendering/render_block.cpp	2003/10/21 22:14:37	1.69
+++ khtml/rendering/render_block.cpp	2003/10/23 21:15:57
@@ -101,69 +101,6 @@ void RenderBlock::addChildToFlow(RenderO
     
     bool madeBoxesNonInline = FALSE;
 
-    RenderStyle* pseudoStyle=0;
-    if ((!firstChild() || firstChild() == beforeChild) &&
-         (newChild->isInline() || (newChild->isText() && !newChild->isBR())) &&
-         (pseudoStyle=getPseudoStyle(RenderStyle::FIRST_LETTER, style(true))))
-    {
-        // Drill into inlines looking for our first text child.
-        RenderObject* textChild = newChild;
-        while (textChild && !(textChild->isText() && !textChild->isBR()))
-            textChild = textChild->firstChild();
-        
-        if (textChild) {
-            RenderObject* firstLetterContainer = textChild->parent();
-            if (!firstLetterContainer)
-                firstLetterContainer = this;
-            
-            RenderText* textObj = static_cast<RenderText*>(textChild);
-        //kdDebug( 6040 ) << "first letter" << endl;
-
-            // Force inline display (except for floating first-letters)
-            pseudoStyle->setDisplay( pseudoStyle->isFloating() ? BLOCK : INLINE);
-            pseudoStyle->setPosition( STATIC ); // CSS2 says first-letter can't be positioned.
-            
-            RenderObject* firstLetter = RenderFlow::createAnonymousFlow(document(), pseudoStyle); // anonymous box
-            firstLetterContainer->addChild(firstLetter, firstLetterContainer->firstChild());
-
-            // The original string is going to be either a generated content string or a DOM node's
-            // string.  We want the original string before it got transformed in case first-letter has
-            // no text-transform or a different text-transform applied to it.
-            DOMStringImpl* oldText = textObj->originalString();
-
-            if (oldText->l >= 1) {
-                unsigned int length = 0;
-                while ( length < oldText->l &&
-                        ( (oldText->s+length)->isSpace() || (oldText->s+length)->isPunct() ) )
-                    length++;
-                length++;
-                //kdDebug( 6040 ) << "letter= '" << DOMString(oldText->substring(0,length)).string() << "'" << endl;
-                
-                RenderTextFragment* remainingText = 
-                    new (renderArena()) RenderTextFragment(textObj->node(), oldText, length, oldText->l-length);
-                remainingText->setStyle(textObj->style());
-                if (remainingText->element())
-                    remainingText->element()->setRenderer(remainingText);
-                if (textObj->parent()) {
-                    RenderObject* nextObj = textObj->nextSibling();
-                    firstLetterContainer->removeChild(textObj);
-                    firstLetterContainer->addChild(remainingText, nextObj);
-                }
-                else {
-		    newChild->detach();
-                    newChild = remainingText;
-		}
-                
-                RenderTextFragment* letter = 
-                    new (renderArena()) RenderTextFragment(remainingText->node(), oldText, 0, length);
-                RenderStyle* newStyle = new RenderStyle();
-                newStyle->inheritFrom(pseudoStyle);
-                letter->setStyle(newStyle);
-                firstLetter->addChild(letter);
-            }
-        }
-    }
-
     // If the requested beforeChild is not one of our children, then this is most likely because
     // there is an anonymous block box within this object that contains the beforeChild. So
     // just insert the child into the anonymous block box instead of here.
@@ -428,7 +365,7 @@ void RenderBlock::layoutBlock(bool relay
         setNeedsLayout(false);
         return;
     }
-
+    
 #ifdef INCREMENTAL_REPAINTING
     QRect oldBounds, oldFullBounds;
     bool checkForRepaint = checkForRepaintDuringLayout();
@@ -2493,6 +2430,102 @@ InlineFlowBox* RenderBlock::getFirstLine
     }
 
     return 0;    
+}
+
+RenderBlock* RenderBlock::firstLineBlock() const
+{
+    const RenderObject* firstLineBlock = this;
+    bool hasPseudo = false;
+    while (true) {
+        hasPseudo = firstLineBlock->style()->hasPseudoStyle(RenderStyle::FIRST_LINE);
+        if (hasPseudo)
+            break;
+        RenderObject* parentBlock = firstLineBlock->parent();
+        if (!parentBlock || parentBlock->firstChild() != firstLineBlock || !parentBlock->isBlockFlow())
+            break;
+        firstLineBlock = parentBlock;
+    } 
+    
+    if (!hasPseudo)
+        return 0;
+    
+    return (RenderBlock*)(firstLineBlock);
+}
+
+void RenderBlock::updateFirstLetter()
+{
+    // FIXME: We need to destroy the first-letter object if it is no longer the first child.  Need to find
+    // an efficient way to check for that situation though before implementing anything.
+    RenderObject* firstLetterBlock = this;
+    bool hasPseudoStyle = false;
+    while (true) {
+        hasPseudoStyle = firstLetterBlock->style()->hasPseudoStyle(RenderStyle::FIRST_LETTER);
+        if (hasPseudoStyle)
+            break;
+        RenderObject* parentBlock = firstLetterBlock->parent();
+        if (!parentBlock || parentBlock->firstChild() != firstLetterBlock || !parentBlock->isBlockFlow())
+            break;
+        firstLetterBlock = parentBlock;
+    } 
+
+    if (!hasPseudoStyle)
+        return;
+    
+    // Drill into inlines looking for our first text child.
+    RenderObject* textChild = firstLetterBlock->firstChild();
+    while (textChild && textChild->needsLayout() && !textChild->isReplaced() && !textChild->isText())
+        textChild = textChild->firstChild();
+    
+    if (textChild && textChild->isText() && !textChild->isBR() && 
+        textChild->parent()->style()->styleType() != RenderStyle::FIRST_LETTER) {
+        RenderObject* firstLetterContainer = textChild->parent();
+        if (!firstLetterContainer)
+            firstLetterContainer = this;
+        
+        RenderText* textObj = static_cast<RenderText*>(textChild);
+        
+        // Create our pseudo style now that we have our firstLetterContainer determined.
+        RenderStyle* pseudoStyle = firstLetterBlock->getPseudoStyle(RenderStyle::FIRST_LETTER,
+                                                                    firstLetterContainer->style(true));
+        
+        // Force inline display (except for floating first-letters)
+        pseudoStyle->setDisplay( pseudoStyle->isFloating() ? BLOCK : INLINE);
+        pseudoStyle->setPosition( STATIC ); // CSS2 says first-letter can't be positioned.
+        
+        RenderObject* firstLetter = RenderFlow::createAnonymousFlow(document(), pseudoStyle); // anonymous box
+        firstLetterContainer->addChild(firstLetter, firstLetterContainer->firstChild());
+        
+        // The original string is going to be either a generated content string or a DOM node's
+        // string.  We want the original string before it got transformed in case first-letter has
+        // no text-transform or a different text-transform applied to it.
+        DOMStringImpl* oldText = textObj->originalString();
+        
+        if (oldText->l >= 1) {
+            unsigned int length = 0;
+            while ( length < oldText->l &&
+                    ( (oldText->s+length)->isSpace() || (oldText->s+length)->isPunct() ) )
+                length++;
+            length++;
+            //kdDebug( 6040 ) << "letter= '" << DOMString(oldText->substring(0,length)).string() << "'" << endl;
+            
+            RenderTextFragment* remainingText = 
+                new (renderArena()) RenderTextFragment(textObj->node(), oldText, length, oldText->l-length);
+            remainingText->setStyle(textObj->style());
+            if (remainingText->element())
+                remainingText->element()->setRenderer(remainingText);
+            
+            RenderObject* nextObj = textObj->nextSibling();
+            firstLetterContainer->removeChild(textObj);
+            firstLetterContainer->addChild(remainingText, nextObj);
+            
+            RenderTextFragment* letter = 
+                new (renderArena()) RenderTextFragment(remainingText->node(), oldText, 0, length);
+            RenderStyle* newStyle = new RenderStyle();
+            newStyle->inheritFrom(pseudoStyle);
+            letter->setStyle(newStyle);
+            firstLetter->addChild(letter);
+        }
+    }
 }
 
 const char *RenderBlock::renderName() const
Index: khtml/rendering/render_block.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_block.h,v
retrieving revision 1.26
diff -u -p -r1.26 khtml/rendering/render_block.h
--- khtml/rendering/render_block.h	2003/10/07 04:43:23	1.26
+++ khtml/rendering/render_block.h	2003/10/23 21:15:57
@@ -44,7 +44,7 @@ public:
     virtual short baselinePosition(bool b, bool isRootLineBox=false) const;
     
     virtual bool isRenderBlock() const { return true; }
-    virtual bool isBlockFlow() const { return !isInline() && !isTable(); }
+    virtual bool isBlockFlow() const { return (!isInline() || isReplaced()) && !isTable(); }
     virtual bool isInlineFlow() const { return isInline() && !isReplaced(); }
     virtual bool isInlineBlockOrInlineTable() const { return isInline() && isReplaced(); }
     
@@ -179,6 +179,11 @@ public:
     // overrides RenderObject
     virtual bool requiresLayer();
     
+    // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
+    // children.
+    virtual RenderBlock* firstLineBlock() const;
+    virtual void updateFirstLetter();
+    
 #ifndef NDEBUG
     virtual void printTree(int indent=0) const;
     virtual void dump(QTextStream *stream, QString ind = "") const;
@@ -186,7 +191,7 @@ public:
     
 protected:
     void newLine();
-    
+
 protected:
     struct FloatingObject {
         enum Type {
Index: khtml/rendering/render_line.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_line.cpp,v
retrieving revision 1.11
diff -u -p -r1.11 khtml/rendering/render_line.cpp
--- khtml/rendering/render_line.cpp	2003/09/25 16:51:10	1.11
+++ khtml/rendering/render_line.cpp	2003/10/23 21:15:57
@@ -499,7 +499,8 @@ void InlineFlowBox::paintBackgroundAndBo
     // You can use p::first-line to specify a background. If so, the root line boxes for
     // a line may actually have to paint a background.
     RenderStyle* styleToUse = object()->style(m_firstLine);
-    if (object()->hasFirstLine() || (parent() && object()->shouldPaintBackgroundOrBorder())) {
+    if ((!parent() && m_firstLine && styleToUse != object()->style()) || 
+        (parent() && object()->shouldPaintBackgroundOrBorder())) {
         CachedImage* bg = styleToUse->backgroundImage();
         bool hasBackgroundImage = bg && (bg->pixmap_size() == bg->valid_rect().size()) &&
                                   !bg->isTransparent() && !bg->isErrorImage();
Index: khtml/rendering/render_list.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_list.cpp,v
retrieving revision 1.48
diff -u -p -r1.48 khtml/rendering/render_list.cpp
--- khtml/rendering/render_list.cpp	2003/10/09 22:20:53	1.48
+++ khtml/rendering/render_list.cpp	2003/10/23 21:15:57
@@ -138,7 +138,9 @@ void RenderListItem::setStyle(RenderStyl
         (style()->listStyleImage() && !style()->listStyleImage()->isErrorImage())) {
         RenderStyle *newStyle = new RenderStyle();
         newStyle->ref();
-        newStyle->inheritFrom(style());
+        // The marker always inherits from the list item, regardless of where it might end
+        // up (e.g., in some deeply nested line box).  See CSS3 spec.
+        newStyle->inheritFrom(style()); 
         if (!m_marker) {
             m_marker = new (renderArena()) RenderListMarker(document());
             m_marker->setStyle(newStyle);
Index: khtml/rendering/render_object.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_object.cpp,v
retrieving revision 1.106
diff -u -p -r1.106 khtml/rendering/render_object.cpp
--- khtml/rendering/render_object.cpp	2003/10/21 22:14:37	1.106
+++ khtml/rendering/render_object.cpp	2003/10/23 21:15:57
@@ -146,7 +146,6 @@ m_inline( true ),
 
 m_replaced( false ),
 m_mouseInside( false ),
-m_hasFirstLine( false ),
 m_isSelectionBorder( false )
 {
 }
@@ -327,6 +326,14 @@ bool RenderObject::requiresLayer()
     return isRoot() || isPositioned() || isRelPositioned() || style()->opacity() < 1.0f;
 }
 
+RenderBlock* RenderObject::firstLineBlock() const
+{
+    return 0;
+}
+
+void RenderObject::updateFirstLetter()
+{}
+
 int RenderObject::offsetLeft() const
 {
     int x = xPos();
@@ -1071,7 +1078,6 @@ void RenderObject::dump(QTextStream *str
     if (needsLayout()) { *stream << " needsLayout"; }
     if (minMaxKnown()) { *stream << " minMaxKnown"; }
     if (overhangingContents()) { *stream << " overhangingContents"; }
-    if (hasFirstLine()) { *stream << " hasFirstLine"; }
     *stream << endl;
 
     RenderObject *child = firstChild();
@@ -1210,8 +1216,7 @@ void RenderObject::setStyle(RenderStyle 
 
     setShouldPaintBackgroundOrBorder(m_style->backgroundColor().isValid() || 
                                      m_style->hasBorder() || nb );
-    m_hasFirstLine = getPseudoStyle(RenderStyle::FIRST_LINE);
-
+    
     if (affectsParentBlock)
         handleDynamicFloatPositionChange();
             
@@ -1687,6 +1692,9 @@ void RenderObject::recalcMinMaxWidths()
     kdDebug( 6040 ) << renderName() << " recalcMinMaxWidths() this=" << this <<endl;
 #endif
 
+    if (m_recalcMinMax)
+        updateFirstLetter();
+    
     RenderObject *child = firstChild();
     while( child ) {
         // gcc sucks. if anybody knows a trick to get rid of the
@@ -1749,10 +1757,22 @@ InlineBox* RenderObject::createInlineBox
 
 RenderStyle* RenderObject::style(bool firstLine) const {
     RenderStyle *s = m_style;
-    if (firstLine && hasFirstLine()) {
-        RenderStyle *pseudoStyle  = getPseudoStyle(RenderStyle::FIRST_LINE);
-        if (pseudoStyle)
-            s = pseudoStyle;
+    if (firstLine) {
+        const RenderObject* obj = isText() ? parent() : this;
+        if (obj->isBlockFlow()) {
+            RenderBlock* firstLineBlock = obj->firstLineBlock();
+            if (firstLineBlock)
+                s = firstLineBlock->getPseudoStyle(RenderStyle::FIRST_LINE, style());
+        }
+        else if (!obj->isAnonymous() && obj->isInlineFlow()) {
+            RenderStyle* parentStyle = obj->parent()->style(true);
+            if (parentStyle != obj->parent()->style()) {
+                // A first-line style is in effect. We need to cache a first-line style
+                // for ourselves.
+                style()->setHasPseudoStyle(RenderStyle::FIRST_LINE_INHERITED);
+                s = obj->getPseudoStyle(RenderStyle::FIRST_LINE_INHERITED, parentStyle);
+            }
+        }
     }
     return s;
 }
@@ -1762,15 +1782,26 @@ RenderStyle* RenderObject::getPseudoStyl
     if (!style()->hasPseudoStyle(pseudo))
         return 0;
     
+    if (!parentStyle)
+        parentStyle = style();
+
+    RenderStyle* result = style()->getPseudoStyle(pseudo);
+    if (result) return result;
+    
     DOM::NodeImpl* node = element();
     if (isText())
         node = element()->parentNode();
     if (!node) return 0;
     
-    if (!parentStyle)
-        parentStyle = style();
-    
-    return document()->styleSelector()->pseudoStyleForElement(pseudo, static_cast<DOM::ElementImpl*>(node), parentStyle);
+    if (pseudo == RenderStyle::FIRST_LINE_INHERITED)
+        result = document()->styleSelector()->styleForElement(static_cast<DOM::ElementImpl*>(node), 
+                                                              parentStyle);
+    else
+        result = document()->styleSelector()->pseudoStyleForElement(pseudo, static_cast<DOM::ElementImpl*>(node), 
+                                                                    parentStyle);
+    if (result)
+        style()->addPseudoStyle(result);
+    return result;
 }
 
 void RenderObject::getTextDecorationColors(int decorations, QColor& underline, QColor& overline,
Index: khtml/rendering/render_object.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_object.h,v
retrieving revision 1.87
diff -u -p -r1.87 khtml/rendering/render_object.h
--- khtml/rendering/render_object.h	2003/10/21 22:14:37	1.87
+++ khtml/rendering/render_object.h	2003/10/23 21:15:57
@@ -140,6 +140,11 @@ public:
     virtual int getBaselineOfFirstLineBox() { return -1; } // Tables and blocks implement this.
     virtual InlineFlowBox* getFirstLineBox() { return 0; } // Tables and blocks implement this.
 
+    // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
+    // children.
+    virtual RenderBlock* firstLineBlock() const;
+    virtual void updateFirstLetter();
+    
     // Called when an object that was floating or positioned becomes a normal flow object
     // again.  We have to make sure the render tree updates as needed to accommodate the new
     // normal flow object.
@@ -249,7 +254,6 @@ public:
     bool normalChildNeedsLayout() const { return m_normalChildNeedsLayout; }
     bool minMaxKnown() const{ return m_minMaxKnown; }
     bool overhangingContents() const { return m_overhangingContents; }
-    bool hasFirstLine() const { return m_hasFirstLine; }
     bool isSelectionBorder() const { return m_isSelectionBorder; }
     bool recalcMinMax() const { return m_recalcMinMax; }
 
@@ -709,7 +713,6 @@ private:
     bool m_inline                    : 1;
     bool m_replaced                  : 1;
     bool m_mouseInside               : 1;
-    bool m_hasFirstLine              : 1;
     bool m_isSelectionBorder         : 1;
 
     void arenaDelete(RenderArena *arena, void *objectBase);
Index: khtml/rendering/render_style.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_style.cpp,v
retrieving revision 1.30
diff -u -p -r1.30 khtml/rendering/render_style.cpp
--- khtml/rendering/render_style.cpp	2003/10/21 22:14:37	1.30
+++ khtml/rendering/render_style.cpp	2003/10/23 21:15:57
@@ -333,7 +333,7 @@ bool RenderStyle::isStyleAvailable() con
 }
 
 enum EPseudoBit { NO_BIT = 0x0, BEFORE_BIT = 0x1, AFTER_BIT = 0x2, FIRST_LINE_BIT = 0x4,
-                  FIRST_LETTER_BIT = 0x8, SELECTION_BIT = 0x10 };
+                  FIRST_LETTER_BIT = 0x8, SELECTION_BIT = 0x10, FIRST_LINE_INHERITED_BIT = 0x20 };
 
 static int pseudoBit(RenderStyle::PseudoId pseudo)
 {
@@ -348,6 +348,8 @@ static int pseudoBit(RenderStyle::Pseudo
             return FIRST_LETTER_BIT;
         case RenderStyle::SELECTION:
             return SELECTION_BIT;
+        case RenderStyle::FIRST_LINE_INHERITED:
+            return FIRST_LINE_INHERITED_BIT;
         default:
             return NO_BIT;
     }
Index: khtml/rendering/render_style.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_style.h,v
retrieving revision 1.33
diff -u -p -r1.33 khtml/rendering/render_style.h
--- khtml/rendering/render_style.h	2003/10/21 22:14:37	1.33
+++ khtml/rendering/render_style.h	2003/10/23 21:15:57
@@ -618,7 +618,7 @@ public:
     static void cleanup();
 
     // static pseudo styles. Dynamic ones are produced on the fly.
-    enum PseudoId { NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION };
+    enum PseudoId { NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION, FIRST_LINE_INHERITED };
 
 protected:
 
@@ -708,7 +708,7 @@ protected:
         PseudoId _styleType : 3;
         bool _affectedByHover : 1;
         bool _affectedByActive : 1;
-        int _pseudoBits : 5;
+        int _pseudoBits : 6;
         EUnicodeBidi _unicodeBidi : 2;
     } noninherited_flags;
 
Index: khtml/rendering/render_table.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_table.cpp,v
retrieving revision 1.80
diff -u -p -r1.80 khtml/rendering/render_table.cpp
--- khtml/rendering/render_table.cpp	2003/10/20 06:57:29	1.80
+++ khtml/rendering/render_table.cpp	2003/10/23 21:15:57
@@ -817,6 +817,14 @@ RenderTableCell* RenderTable::cellRight(
     return (result == (RenderTableCell*)-1) ? 0 : result;
 }
 
+RenderBlock* RenderTable::firstLineBlock() const
+{
+    return 0;
+}
+
+void RenderTable::updateFirstLetter()
+{}
+
 #ifndef NDEBUG
 void RenderTable::dump(QTextStream *stream, QString ind) const
 {
Index: khtml/rendering/render_table.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_table.h,v
retrieving revision 1.29
diff -u -p -r1.29 khtml/rendering/render_table.h
--- khtml/rendering/render_table.h	2003/10/17 22:32:14	1.29
+++ khtml/rendering/render_table.h	2003/10/23 21:15:57
@@ -110,6 +110,9 @@ public:
     virtual void calcMinMaxWidth();
     virtual void close();
 
+    virtual RenderBlock* firstLineBlock() const;
+    virtual void updateFirstLetter();
+    
     virtual void setCellWidths( );
 
     virtual void calcWidth();
Index: khtml/rendering/render_text.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_text.cpp,v
retrieving revision 1.89
diff -u -p -r1.89 khtml/rendering/render_text.cpp
--- khtml/rendering/render_text.cpp	2003/10/23 00:10:53	1.89
+++ khtml/rendering/render_text.cpp	2003/10/23 21:15:57
@@ -577,7 +577,8 @@ void RenderText::paintObject(QPainter *p
                              int tx, int ty, PaintAction paintAction)
 {
     int ow = style()->outlineWidth();
-    RenderStyle* pseudoStyle = hasFirstLine() ? getPseudoStyle(RenderStyle::FIRST_LINE) : 0;
+    RenderStyle* pseudoStyle = style(true);
+    if (pseudoStyle == style()) pseudoStyle = 0;
     int d = style()->textDecorationsInEffect();
     InlineTextBox f(0, y-ty);
     int si = m_lines.findFirstMatching(&f);
@@ -1335,15 +1336,7 @@ const QFontMetrics &RenderText::metrics(
 
 const Font *RenderText::htmlFont(bool firstLine) const
 {
-    const Font *f = 0;
-    if( firstLine && hasFirstLine() ) {
-        RenderStyle* pseudoStyle = getPseudoStyle(RenderStyle::FIRST_LINE);
-	if ( pseudoStyle )
-	    f = &pseudoStyle->htmlFont();
-    } else {
-	f = &style()->htmlFont();
-    }
-    return f;
+    return &style(firstLine)->htmlFont();
 }
 
 void RenderText::paintTextOutline(QPainter *p, int tx, int ty, const QRect &lastline, const QRect &thisline, const QRect &nextline)
Index: khtml/xml/dom_elementimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_elementimpl.cpp,v
retrieving revision 1.22
diff -u -p -r1.22 khtml/xml/dom_elementimpl.cpp
--- khtml/xml/dom_elementimpl.cpp	2003/10/01 20:22:52	1.22
+++ khtml/xml/dom_elementimpl.cpp	2003/10/23 21:15:57
@@ -357,22 +357,20 @@ void ElementImpl::recalcStyle( StyleChan
     qDebug("recalcStyle(%d: %s)[%p: %s]", change, debug, this, tagName().string().latin1());
 #endif
     if ( hasParentRenderer && (change >= Inherit || changed()) ) {
-        EDisplay oldDisplay = _style ? _style->display() : NONE;
-
         RenderStyle *newStyle = getDocument()->styleSelector()->styleForElement(this);
         newStyle->ref();
         StyleChange ch = diff( _style, newStyle );
-        if ( ch != NoChange ) {
-            if (oldDisplay != newStyle->display()) {
-                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;
-            }
+        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 ) {
                 //qDebug("--> setting style on render element bgcolor=%s", newStyle->backgroundColor().name().latin1());
                 m_render->setStyle(newStyle);
Index: khtml/xml/dom_nodeimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_nodeimpl.cpp,v
retrieving revision 1.41
diff -u -p -r1.41 khtml/xml/dom_nodeimpl.cpp
--- khtml/xml/dom_nodeimpl.cpp	2003/10/20 17:28:10	1.41
+++ khtml/xml/dom_nodeimpl.cpp	2003/10/23 21:15:57
@@ -929,7 +929,13 @@ NodeImpl::StyleChange NodeImpl::diff( kh
     // explicit inheritance of non-inherited properties and so you end up not re-resolving
     // style in cases where you need to.
     StyleChange ch = NoInherit;
-    if ( !s1 || !s2 )
+    EDisplay display1 = s1 ? s1->display() : NONE;
+    bool fl1 = s1 ? s1->hasPseudoStyle(RenderStyle::FIRST_LETTER) : false;
+    EDisplay display2 = s2 ? s2->display() : NONE;
+    bool fl2 = s2 ? s2->hasPseudoStyle(RenderStyle::FIRST_LETTER) : false;
+    if (display1 != display2 || fl1 != fl2)
+        ch = Detach;
+    else if ( !s1 || !s2 )
 	ch = Inherit;
     else if ( *s1 == *s2 )
  	ch = NoChange;
Index: khtml/xml/dom_nodeimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_nodeimpl.h,v
retrieving revision 1.23
diff -u -p -r1.23 khtml/xml/dom_nodeimpl.h
--- khtml/xml/dom_nodeimpl.h	2003/10/20 07:07:54	1.23
+++ khtml/xml/dom_nodeimpl.h	2003/10/23 21:15:57
@@ -213,7 +213,7 @@ public:
     virtual void getCursor(int offset, int &_x, int &_y, int &height);
     virtual QRect getRect() const;
 
-    enum StyleChange { NoChange, NoInherit, Inherit, Force };
+    enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force };
     virtual void recalcStyle( StyleChange = NoChange ) {}
     StyleChange diff( khtml::RenderStyle *s1, khtml::RenderStyle *s2 ) const;
 
-------------- next part --------------


dave


More information about the Khtml-devel mailing list