[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

hyatt hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:04:29 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit d1a5a09d0b3884d26dd1ab0d4f04ac55365e7546
Author: hyatt <hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Oct 23 22:23:25 2003 +0000

    	This patch fixes the pseudo-elements ::first-line and ::first-letter to inherit styles properly.  More
    	specifically it does the following:
    
    	(1) Implements caching of pseudo-styles once computed off the style() which originated the pseudo-style.
    	The old code did this, and this was a regression from my previous patch.
    
    	(2) Fixes first-letter checking so that it happens at layout time rather than during render object
    	construction time, since that makes first-letter more dynamic and causes it to be discovered in cases
    	where it was being missed before.  This fixes the front page of meyerweb.com.
    
    	(3) Make first-letter inherit from first-line like it's supposed to, and also make first-line styles
    	cross blocks and inherit properly from enclosing containers.
    
    	(4) Make first-letter changes cause a detach/attach to fire just as when the display changes.  I generalized
    	the notion of needing to detach on a style change by making it a new kind of hint in dom_nodeimpl's style
    	diff function.
    
    	(5) Fixed isBlockFlow to return true for inline-blocks.
    
            Reviewed by john
    
            * khtml/rendering/render_block.cpp:
            (khtml::RenderBlock::addChildToFlow):
            (khtml::RenderBlock::layoutBlock):
            (khtml::RenderBlock::getFirstLineBox):
            (khtml::RenderBlock::firstLineBlock):
            (khtml::RenderBlock::updateFirstLetter):
            * khtml/rendering/render_block.h:
            (khtml::RenderBlock::isBlockFlow):
            * khtml/rendering/render_line.cpp:
            (InlineFlowBox::paintBackgroundAndBorder):
            * khtml/rendering/render_list.cpp:
            (RenderListItem::setStyle):
            * khtml/rendering/render_object.cpp:
            (RenderObject::RenderObject):
            (RenderObject::firstLineBlock):
            (RenderObject::updateFirstLetter):
            (RenderObject::dump):
            (RenderObject::setStyle):
            (RenderObject::recalcMinMaxWidths):
            (RenderObject::style):
            (RenderObject::getPseudoStyle):
            * khtml/rendering/render_object.h:
            (khtml::RenderObject::overhangingContents):
            * khtml/rendering/render_style.cpp:
            (pseudoBit):
            * khtml/rendering/render_style.h:
            (khtml::RenderStyle::):
            * khtml/rendering/render_table.cpp:
            (RenderTable::firstLineBlock):
            (RenderTable::updateFirstLetter):
            * khtml/rendering/render_table.h:
            * khtml/rendering/render_text.cpp:
            (RenderText::paintObject):
            (RenderText::htmlFont):
            * khtml/xml/dom_elementimpl.cpp:
            (ElementImpl::recalcStyle):
            * khtml/xml/dom_nodeimpl.cpp:
            (NodeImpl::diff):
            * khtml/xml/dom_nodeimpl.h:
            (DOM::NodeImpl::):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@5249 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index 96da027..1a7411d 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,67 @@
+2003-10-23  David Hyatt  <hyatt at apple.com>
+
+	This patch fixes the pseudo-elements ::first-line and ::first-letter to inherit styles properly.  More
+	specifically it does the following:
+
+	(1) Implements caching of pseudo-styles once computed off the style() which originated the pseudo-style.
+	The old code did this, and this was a regression from my previous patch.
+
+	(2) Fixes first-letter checking so that it happens at layout time rather than during render object
+	construction time, since that makes first-letter more dynamic and causes it to be discovered in cases
+	where it was being missed before.  This fixes the front page of meyerweb.com.
+
+	(3) Make first-letter inherit from first-line like it's supposed to, and also make first-line styles
+	cross blocks and inherit properly from enclosing containers.
+
+	(4) Make first-letter changes cause a detach/attach to fire just as when the display changes.  I generalized
+	the notion of needing to detach on a style change by making it a new kind of hint in dom_nodeimpl's style
+	diff function.
+
+	(5) Fixed isBlockFlow to return true for inline-blocks.
+	
+        Reviewed by john
+
+        * khtml/rendering/render_block.cpp:
+        (khtml::RenderBlock::addChildToFlow):
+        (khtml::RenderBlock::layoutBlock):
+        (khtml::RenderBlock::getFirstLineBox):
+        (khtml::RenderBlock::firstLineBlock):
+        (khtml::RenderBlock::updateFirstLetter):
+        * khtml/rendering/render_block.h:
+        (khtml::RenderBlock::isBlockFlow):
+        * khtml/rendering/render_line.cpp:
+        (InlineFlowBox::paintBackgroundAndBorder):
+        * khtml/rendering/render_list.cpp:
+        (RenderListItem::setStyle):
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::RenderObject):
+        (RenderObject::firstLineBlock):
+        (RenderObject::updateFirstLetter):
+        (RenderObject::dump):
+        (RenderObject::setStyle):
+        (RenderObject::recalcMinMaxWidths):
+        (RenderObject::style):
+        (RenderObject::getPseudoStyle):
+        * khtml/rendering/render_object.h:
+        (khtml::RenderObject::overhangingContents):
+        * khtml/rendering/render_style.cpp:
+        (pseudoBit):
+        * khtml/rendering/render_style.h:
+        (khtml::RenderStyle::):
+        * khtml/rendering/render_table.cpp:
+        (RenderTable::firstLineBlock):
+        (RenderTable::updateFirstLetter):
+        * khtml/rendering/render_table.h:
+        * khtml/rendering/render_text.cpp:
+        (RenderText::paintObject):
+        (RenderText::htmlFont):
+        * khtml/xml/dom_elementimpl.cpp:
+        (ElementImpl::recalcStyle):
+        * khtml/xml/dom_nodeimpl.cpp:
+        (NodeImpl::diff):
+        * khtml/xml/dom_nodeimpl.h:
+        (DOM::NodeImpl::):
+
 2003-10-23  Ken Kocienda  <kocienda at apple.com>
 
         Reviewed by David
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 96da027..1a7411d 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,67 @@
+2003-10-23  David Hyatt  <hyatt at apple.com>
+
+	This patch fixes the pseudo-elements ::first-line and ::first-letter to inherit styles properly.  More
+	specifically it does the following:
+
+	(1) Implements caching of pseudo-styles once computed off the style() which originated the pseudo-style.
+	The old code did this, and this was a regression from my previous patch.
+
+	(2) Fixes first-letter checking so that it happens at layout time rather than during render object
+	construction time, since that makes first-letter more dynamic and causes it to be discovered in cases
+	where it was being missed before.  This fixes the front page of meyerweb.com.
+
+	(3) Make first-letter inherit from first-line like it's supposed to, and also make first-line styles
+	cross blocks and inherit properly from enclosing containers.
+
+	(4) Make first-letter changes cause a detach/attach to fire just as when the display changes.  I generalized
+	the notion of needing to detach on a style change by making it a new kind of hint in dom_nodeimpl's style
+	diff function.
+
+	(5) Fixed isBlockFlow to return true for inline-blocks.
+	
+        Reviewed by john
+
+        * khtml/rendering/render_block.cpp:
+        (khtml::RenderBlock::addChildToFlow):
+        (khtml::RenderBlock::layoutBlock):
+        (khtml::RenderBlock::getFirstLineBox):
+        (khtml::RenderBlock::firstLineBlock):
+        (khtml::RenderBlock::updateFirstLetter):
+        * khtml/rendering/render_block.h:
+        (khtml::RenderBlock::isBlockFlow):
+        * khtml/rendering/render_line.cpp:
+        (InlineFlowBox::paintBackgroundAndBorder):
+        * khtml/rendering/render_list.cpp:
+        (RenderListItem::setStyle):
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::RenderObject):
+        (RenderObject::firstLineBlock):
+        (RenderObject::updateFirstLetter):
+        (RenderObject::dump):
+        (RenderObject::setStyle):
+        (RenderObject::recalcMinMaxWidths):
+        (RenderObject::style):
+        (RenderObject::getPseudoStyle):
+        * khtml/rendering/render_object.h:
+        (khtml::RenderObject::overhangingContents):
+        * khtml/rendering/render_style.cpp:
+        (pseudoBit):
+        * khtml/rendering/render_style.h:
+        (khtml::RenderStyle::):
+        * khtml/rendering/render_table.cpp:
+        (RenderTable::firstLineBlock):
+        (RenderTable::updateFirstLetter):
+        * khtml/rendering/render_table.h:
+        * khtml/rendering/render_text.cpp:
+        (RenderText::paintObject):
+        (RenderText::htmlFont):
+        * khtml/xml/dom_elementimpl.cpp:
+        (ElementImpl::recalcStyle):
+        * khtml/xml/dom_nodeimpl.cpp:
+        (NodeImpl::diff):
+        * khtml/xml/dom_nodeimpl.h:
+        (DOM::NodeImpl::):
+
 2003-10-23  Ken Kocienda  <kocienda at apple.com>
 
         Reviewed by David
diff --git a/WebCore/khtml/rendering/render_block.cpp b/WebCore/khtml/rendering/render_block.cpp
index 70c1988..cfd6be0 100644
--- a/WebCore/khtml/rendering/render_block.cpp
+++ b/WebCore/khtml/rendering/render_block.cpp
@@ -101,69 +101,6 @@ void RenderBlock::addChildToFlow(RenderObject* newChild, RenderObject* beforeChi
     
     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 relayoutChildren)
         setNeedsLayout(false);
         return;
     }
-
+    
 #ifdef INCREMENTAL_REPAINTING
     QRect oldBounds, oldFullBounds;
     bool checkForRepaint = checkForRepaintDuringLayout();
@@ -2495,6 +2432,104 @@ InlineFlowBox* RenderBlock::getFirstLineBox()
     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 (firstLineBlock->isReplaced() || !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 (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock || 
+            !parentBlock->isBlockFlow())
+            break;
+        firstLetterBlock = parentBlock;
+    } 
+
+    if (!hasPseudoStyle)
+        return;
+    
+    // Drill into inlines looking for our first text child.
+    RenderObject* currChild = firstLetterBlock->firstChild();
+    while (currChild && currChild->needsLayout() && !currChild->isReplaced() && !currChild->isText())
+        currChild = currChild->firstChild();
+    
+    if (currChild && currChild->isText() && !currChild->isBR() && 
+        currChild->parent()->style()->styleType() != RenderStyle::FIRST_LETTER) {
+        RenderObject* firstLetterContainer = currChild->parent();
+        if (!firstLetterContainer)
+            firstLetterContainer = this;
+        
+        RenderText* textObj = static_cast<RenderText*>(currChild);
+        
+        // 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
 {
     if (isBody())
diff --git a/WebCore/khtml/rendering/render_block.h b/WebCore/khtml/rendering/render_block.h
index ef31ffb..3628045 100644
--- a/WebCore/khtml/rendering/render_block.h
+++ b/WebCore/khtml/rendering/render_block.h
@@ -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 {
diff --git a/WebCore/khtml/rendering/render_line.cpp b/WebCore/khtml/rendering/render_line.cpp
index 8cab347..35b70af 100644
--- a/WebCore/khtml/rendering/render_line.cpp
+++ b/WebCore/khtml/rendering/render_line.cpp
@@ -499,7 +499,8 @@ void InlineFlowBox::paintBackgroundAndBorder(QPainter *p, int _x, int _y,
     // 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();
diff --git a/WebCore/khtml/rendering/render_list.cpp b/WebCore/khtml/rendering/render_list.cpp
index 0bfe74c..cd5302d 100644
--- a/WebCore/khtml/rendering/render_list.cpp
+++ b/WebCore/khtml/rendering/render_list.cpp
@@ -138,7 +138,9 @@ void RenderListItem::setStyle(RenderStyle *_style)
         (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);
diff --git a/WebCore/khtml/rendering/render_object.cpp b/WebCore/khtml/rendering/render_object.cpp
index 2858235..d0f82da 100644
--- a/WebCore/khtml/rendering/render_object.cpp
+++ b/WebCore/khtml/rendering/render_object.cpp
@@ -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 *stream, QString ind) const
     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 *style)
 
     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(bool,bool isRootLineBox)
 
 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::getPseudoStyle(RenderStyle::PseudoId pseudo, RenderSt
     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,
diff --git a/WebCore/khtml/rendering/render_object.h b/WebCore/khtml/rendering/render_object.h
index 5ca4a57..e48effc 100644
--- a/WebCore/khtml/rendering/render_object.h
+++ b/WebCore/khtml/rendering/render_object.h
@@ -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);
diff --git a/WebCore/khtml/rendering/render_style.cpp b/WebCore/khtml/rendering/render_style.cpp
index 67039a7..f8fcb99 100644
--- a/WebCore/khtml/rendering/render_style.cpp
+++ b/WebCore/khtml/rendering/render_style.cpp
@@ -333,7 +333,7 @@ bool RenderStyle::isStyleAvailable() const
 }
 
 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::PseudoId 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;
     }
diff --git a/WebCore/khtml/rendering/render_style.h b/WebCore/khtml/rendering/render_style.h
index a5235e5..4796fa6 100644
--- a/WebCore/khtml/rendering/render_style.h
+++ b/WebCore/khtml/rendering/render_style.h
@@ -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;
 
diff --git a/WebCore/khtml/rendering/render_table.cpp b/WebCore/khtml/rendering/render_table.cpp
index c01f36e..5bdd753 100644
--- a/WebCore/khtml/rendering/render_table.cpp
+++ b/WebCore/khtml/rendering/render_table.cpp
@@ -817,6 +817,14 @@ RenderTableCell* RenderTable::cellRight(const RenderTableCell* cell) const
     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
 {
diff --git a/WebCore/khtml/rendering/render_table.h b/WebCore/khtml/rendering/render_table.h
index 19203cc..2cc7162 100644
--- a/WebCore/khtml/rendering/render_table.h
+++ b/WebCore/khtml/rendering/render_table.h
@@ -110,6 +110,9 @@ public:
     virtual void calcMinMaxWidth();
     virtual void close();
 
+    virtual RenderBlock* firstLineBlock() const;
+    virtual void updateFirstLetter();
+    
     virtual void setCellWidths( );
 
     virtual void calcWidth();
diff --git a/WebCore/khtml/rendering/render_text.cpp b/WebCore/khtml/rendering/render_text.cpp
index 2f36bb1..d6f4453 100644
--- a/WebCore/khtml/rendering/render_text.cpp
+++ b/WebCore/khtml/rendering/render_text.cpp
@@ -577,7 +577,8 @@ void RenderText::paintObject(QPainter *p, int /*x*/, int y, int /*w*/, int h,
                              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(bool firstLine) const
 
 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)
diff --git a/WebCore/khtml/xml/dom_elementimpl.cpp b/WebCore/khtml/xml/dom_elementimpl.cpp
index 7439467..4b3d444 100644
--- a/WebCore/khtml/xml/dom_elementimpl.cpp
+++ b/WebCore/khtml/xml/dom_elementimpl.cpp
@@ -357,22 +357,20 @@ void ElementImpl::recalcStyle( StyleChange change )
     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);
diff --git a/WebCore/khtml/xml/dom_nodeimpl.cpp b/WebCore/khtml/xml/dom_nodeimpl.cpp
index dbfac2d..b7c589a 100644
--- a/WebCore/khtml/xml/dom_nodeimpl.cpp
+++ b/WebCore/khtml/xml/dom_nodeimpl.cpp
@@ -929,7 +929,13 @@ NodeImpl::StyleChange NodeImpl::diff( khtml::RenderStyle *s1, khtml::RenderStyle
     // 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;
diff --git a/WebCore/khtml/xml/dom_nodeimpl.h b/WebCore/khtml/xml/dom_nodeimpl.h
index 29e22f1..41072d7 100644
--- a/WebCore/khtml/xml/dom_nodeimpl.h
+++ b/WebCore/khtml/xml/dom_nodeimpl.h
@@ -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;
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list