[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 06:51:09 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit b30af4c3f7e7e773481bbec2927a5063ab5b4869
Author: hyatt <hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Oct 18 20:20:47 2002 +0000

    	The collapsing margin rewrite. Also fixes a bug where
    	we stay in quirks mode for strict HTML4 dtds when we
    	shouldn't.
    
            * khtml/html/html_documentimpl.cpp:
            (HTMLDocumentImpl::determineParseMode):
            * khtml/rendering/render_flow.cpp:
            (RenderFlow::layout):
            (RenderFlow::layoutBlockChildren):
            * khtml/rendering/render_flow.h:
            * khtml/rendering/render_object.h:
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@2369 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2002-12-03 b/WebCore/ChangeLog-2002-12-03
index 2082d1d..e60a3a2 100644
--- a/WebCore/ChangeLog-2002-12-03
+++ b/WebCore/ChangeLog-2002-12-03
@@ -1,3 +1,17 @@
+2002-10-18  David Hyatt  <hyatt at apple.com>
+
+	The collapsing margin rewrite. Also fixes a bug where
+	we stay in quirks mode for strict HTML4 dtds when we
+	shouldn't.
+	
+        * khtml/html/html_documentimpl.cpp:
+        (HTMLDocumentImpl::determineParseMode):
+        * khtml/rendering/render_flow.cpp:
+        (RenderFlow::layout):
+        (RenderFlow::layoutBlockChildren):
+        * khtml/rendering/render_flow.h:
+        * khtml/rendering/render_object.h:
+
 2002-10-18  Darin Adler  <darin at apple.com>
 
         * Makefile.am: Move dependency so clean happens before build.
diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index 2082d1d..e60a3a2 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,17 @@
+2002-10-18  David Hyatt  <hyatt at apple.com>
+
+	The collapsing margin rewrite. Also fixes a bug where
+	we stay in quirks mode for strict HTML4 dtds when we
+	shouldn't.
+	
+        * khtml/html/html_documentimpl.cpp:
+        (HTMLDocumentImpl::determineParseMode):
+        * khtml/rendering/render_flow.cpp:
+        (RenderFlow::layout):
+        (RenderFlow::layoutBlockChildren):
+        * khtml/rendering/render_flow.h:
+        * khtml/rendering/render_object.h:
+
 2002-10-18  Darin Adler  <darin at apple.com>
 
         * Makefile.am: Move dependency so clean happens before build.
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 2082d1d..e60a3a2 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,17 @@
+2002-10-18  David Hyatt  <hyatt at apple.com>
+
+	The collapsing margin rewrite. Also fixes a bug where
+	we stay in quirks mode for strict HTML4 dtds when we
+	shouldn't.
+	
+        * khtml/html/html_documentimpl.cpp:
+        (HTMLDocumentImpl::determineParseMode):
+        * khtml/rendering/render_flow.cpp:
+        (RenderFlow::layout):
+        (RenderFlow::layoutBlockChildren):
+        * khtml/rendering/render_flow.h:
+        * khtml/rendering/render_object.h:
+
 2002-10-18  Darin Adler  <darin at apple.com>
 
         * Makefile.am: Move dependency so clean happens before build.
diff --git a/WebCore/khtml/html/html_documentimpl.cpp b/WebCore/khtml/html/html_documentimpl.cpp
index 06b0c4f..ca93a1f 100644
--- a/WebCore/khtml/html/html_documentimpl.cpp
+++ b/WebCore/khtml/html/html_documentimpl.cpp
@@ -384,10 +384,10 @@ void HTMLDocumentImpl::determineParseMode( const QString &str )
             }
         }
 
-        if( systemId == publicId )
+        // e.g.,<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> should be strict.
+        // Just because it's HTML4 doesn't mean it should be treated as Compat. -dwh
+        if( systemId == publicId || systemId == Unknown )
             pMode = publicId;
-        else if ( systemId == Unknown )
-            pMode = hMode == Html4 ? Compat : publicId;
         else if ( publicId == Transitional && systemId == Strict ) {
             pMode = hMode == Html3 ? Compat : Strict;
         } else
diff --git a/WebCore/khtml/rendering/render_flow.cpp b/WebCore/khtml/rendering/render_flow.cpp
index 3ac0196..e448730 100644
--- a/WebCore/khtml/rendering/render_flow.cpp
+++ b/WebCore/khtml/rendering/render_flow.cpp
@@ -35,22 +35,11 @@
 #include "rendering/render_table.h"
 #include "rendering/render_root.h"
 #include "xml/dom_nodeimpl.h"
+#include "xml/dom_docimpl.h"
 #include "khtmlview.h"
 using namespace DOM;
 using namespace khtml;
 
-#define TABLECELLMARGIN -0x4000
-
-static inline int collapseMargins(int a, int b)
-{
-    if ( a == TABLECELLMARGIN || b == TABLECELLMARGIN ) return TABLECELLMARGIN;
-    if(a >= 0 && b >= 0) return (a > b ? a : b );
-    if(a > 0 && b < 0) return a + b;
-    if(a < 0 && b > 0) return b + a;
-    return ( a > b ? b : a);
-}
-
-
 RenderFlow::RenderFlow(DOM::NodeImpl* node)
     : RenderBox(node)
 {
@@ -231,22 +220,36 @@ void RenderFlow::layout()
     m_height = 0;
     m_clearStatus = CNONE;
 
-    // COLLAPSING MARGIN CODE
-    // Start out by setting our margin values to our current margin.
-    if (m_marginTop > 0)
-        m_maxTopPosMargin = m_marginTop;
-    else
-        m_maxTopNegMargin = m_marginTop;
-    if (m_marginBottom > 0)
-        m_maxBottomPosMargin = m_marginBottom;
-    else
-        m_maxBottomNegMargin = m_marginBottom;
+    // We use four values, maxTopPos, maxPosNeg, maxBottomPos, and maxBottomNeg, to track
+    // our current maximal positive and negative margins.  These values are used when we
+    // are collapsed with adjacent blocks, so for example, if you have block A and B
+    // collapsing together, then you'd take the maximal positive margin from both A and B
+    // and subtract it from the maximal negative margin from both A and B to get the
+    // true collapsed margin.  This algorithm is recursive, so when we finish layout()
+    // our block knows its current maximal positive/negative values.
+    //
+    // Start out by setting our margin values to our current margins.  Table cells have
+    // no margins, so we don't fill in the values for table cells.
+    if (!isTableCell()) {
+        if (m_marginTop >= 0)
+            m_maxTopPosMargin = m_marginTop;
+        else
+            m_maxTopNegMargin = -m_marginTop;
+        if (m_marginBottom >= 0)
+            m_maxBottomPosMargin = m_marginBottom;
+        else
+            m_maxBottomNegMargin = -m_marginBottom;
+    }
+    
+    // A quirk that has become an unfortunate standard.  Positioned elements, floating elements
+    // and table cells don't ever collapse their margins with either themselves or their
+    // children.
     bool canCollapseOwnMargins = !isPositioned() && !isFloating() && !isTableCell();
                                        
 //    kdDebug( 6040 ) << "childrenInline()=" << childrenInline() << endl;
     if(childrenInline()) {
         // ### make bidi resumeable so that we can get rid of this ugly hack
-         if (!m_blockBidi)
+        if (!m_blockBidi)
             layoutInlineChildren();
     }
     else
@@ -254,7 +257,7 @@ void RenderFlow::layout()
 
     int oldHeight = m_height;
     calcHeight();
-    if ( oldHeight != m_height )
+    if (oldHeight != m_height)
         relayoutChildren = true;
 
     if ( isTableCell() && lastChild() && lastChild()->hasOverhangingFloats() ) {
@@ -270,28 +273,19 @@ void RenderFlow::layout()
 
     //kdDebug() << renderName() << " layout width=" << m_width << " height=" << m_height << endl;
 
-    // COLLAPSING MARGIN CODE
     if (canCollapseOwnMargins && m_height == 0) {
-        // We are an empty block with no border and padding and a computed height
-        // of 0.  The CSS spec states that empty blocks collapse their margins
+        // We are a block with no border and padding and a computed height
+        // of 0.  The CSS spec states that zero-height blocks collapse their margins
         // together.
-        // When blocks are empty, we just use the top margin values and set the
+        // When blocks are self-collapsing, we just use the top margin values and set the
         // bottom margin max values to 0.  This way we don't factor in the values
         // twice when we collapse with our previous vertically adjacent and 
         // following vertically adjacent blocks.
-        m_maxBottomPosMargin = m_maxBottomNegMargin = 0;
-        if (m_marginTop >= 0 && m_marginBottom >= 0)
-            m_maxTopPosMargin = m_marginTop > m_marginBottom ? m_marginTop : m_marginBottom;
-        else if (m_marginTop >= 0) {
-            m_maxTopPosMargin = m_marginTop;
-            m_maxTopNegMargin = m_marginBottom;
-        }
-        else if (m_marginBottom >= 0) {
-            m_maxTopPosMargin = m_marginBottom;
-            m_maxTopNegMargin = m_marginTop;
-        }
-        else
-            m_maxTopNegMargin = m_marginTop > m_marginBottom ? -m_marginBottom : -m_marginTop;
+        if (m_maxBottomPosMargin > m_maxTopPosMargin)
+            m_maxTopPosMargin = m_maxBottomPosMargin;
+        if (m_maxBottomNegMargin > m_maxTopNegMargin)
+            m_maxTopNegMargin = m_maxBottomNegMargin;
+        m_maxBottomNegMargin = m_maxBottomPosMargin = 0;
     }
 
     setLayouted();
@@ -340,6 +334,8 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
         toAdd += paddingBottom();
     }
 
+    int minHeight = m_height + toAdd;
+    
     if( style()->direction() == RTL ) {
         xPos = marginLeft() + m_width - paddingRight() - borderRight();
     }
@@ -347,21 +343,28 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
     RenderObject *child = firstChild();
     RenderFlow *prevFlow = 0;
 
-    // COLLAPSING MARGIN CODE
-    //bool canCollapseWithChildren = !isPositioned() && !isFloating() && !isTableCell() &&
-    //                               (m_height == 0);
-   
-    int prevMargin = 0;
-    if(isTableCell() ) {
-        prevMargin = TABLECELLMARGIN;
-    } else if ( m_height == 0 ) {
-        // the elements and childs margin collapse if there is no border and padding.
-        prevMargin = marginTop();
-        if ( parent() )
-            prevMargin = collapseMargins( prevMargin, parent()->marginTop() );
-        if ( prevMargin != TABLECELLMARGIN )
-            m_height = -prevMargin;
-    }
+    // Whether or not we can collapse our own margins with our children.  We don't do this
+    // if we had any border/padding (obviously), if we're the root or HTML elements, or if
+    // we're positioned, floating, or a table cell.
+    bool canCollapseWithChildren = !isRoot() && !isHtml() && !isPositioned() && 
+      !isFloating() && !isTableCell() && (m_height == 0);
+      
+    // Sometimes an element will be shoved down away from a previous sibling, e.g., when
+    // clearing to pass beyond a float.  In this case, you don't need to collapse.  This
+    // boolean is updated with each iteration through our child list to reflect whether
+    // that particular child should be collapsed with its previous sibling (or with the top
+    // of the block).
+    bool shouldCollapseChild = true;
+    
+    // This flag tracks whether the child should collapse with the top margins of the block.
+    // It can remain set through multiple iterations as long as we keep encountering 
+    // self-collapsing blocks.
+    bool topMarginContributor = true;
+    
+    // These flags track the previous maximal positive and negative margins.
+    int prevPosMargin = maxTopMargin(true);
+    int prevNegMargin = maxTopMargin(false);
+        
     //kdDebug() << "RenderFlow::layoutBlockChildren " << prevMargin << endl;
 
     // take care in case we inherited floats
@@ -373,16 +376,15 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
 
     while( child != 0 )
     {
-
         // make sure we relayout children if we need it.
         if ( relayoutChildren || floatBottom() > m_y ||
              (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())))
-                child->setLayouted(false);
-	if ( child->style()->flowAroundFloats() && !child->isFloating() &&
-	     style()->width().isFixed() && child->minWidth() > lineWidth( m_height ) ) {
-	    m_height = QMAX( m_height, floatBottom() );
-	    prevMargin = 0;
-	}
+            child->setLayouted(false);
+        if ( child->style()->flowAroundFloats() && !child->isFloating() &&
+                style()->width().isFixed() && child->minWidth() > lineWidth( m_height ) ) {
+            m_height = QMAX( m_height, floatBottom() );
+            shouldCollapseChild = false;
+        }
 	
 //         kdDebug( 6040 ) << "   " << child->renderName() << " loop " << child << ", " << child->isInline() << ", " << child->layouted() << endl;
 //         kdDebug( 6040 ) << t.elapsed() << endl;
@@ -399,30 +401,17 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
             if ( !child->layouted() )
                 child->layout();
         } else if ( child->isFloating() ) {
-	    // margins of floats and other objects do not collapse. The hack below assures this.
-	    if ( prevMargin != TABLECELLMARGIN )
-		m_height += prevMargin;
-	    insertSpecialObject( child );
-	    positionNewFloats();
-	    //kdDebug() << "RenderFlow::layoutBlockChildren inserting float at "<< m_height <<" prevMargin="<<prevMargin << endl;
-	    if ( prevMargin != TABLECELLMARGIN )
-		m_height -= prevMargin;
-	    child = child->nextSibling();
-	    continue;
-	}
+            insertSpecialObject( child );
+            positionNewFloats();
+            //kdDebug() << "RenderFlow::layoutBlockChildren inserting float at "<< m_height <<" prevMargin="<<prevMargin << endl;
+            child = child->nextSibling();
+            continue;
+        }
 
         child->calcVerticalMargins();
 
-        if(checkClear(child)) prevMargin = 0; // ### should only be 0
-        // if oldHeight+prevMargin < newHeight
-
-        int margin = child->marginTop();
-        //kdDebug(0) << "margin = " << margin << " prevMargin = " << prevMargin << endl;
-        margin = collapseMargins(margin, prevMargin);
-
-	if ( margin != TABLECELLMARGIN )
-	    m_height += margin;
-
+        if(checkClear(child)) shouldCollapseChild = false; // ### should only be 0
+        
         //kdDebug(0) << "margin = " << margin << " yPos = " << m_height << endl;
 
         if(prevFlow)
@@ -434,14 +423,67 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
         }
 
         child->setPos(child->xPos(), m_height);
-	if ( !child->layouted() )
-	    child->layout();
-
+        if ( !child->layouted() )
+            child->layout();
+
+        // Now determine the correct ypos based off examination of collapsing margin
+        // values.
+        if (shouldCollapseChild) {
+            // Get our max pos and neg top margins.
+            int posTop = child->maxTopMargin(true);
+            int negTop = child->maxTopMargin(false);
+            
+            if (canCollapseWithChildren && topMarginContributor) {
+                // This child is collapsing with the top of the
+                // block.  If it has larger margin values, then we need to update
+                // our own maximal values.
+                if (posTop > m_maxTopPosMargin)
+                    m_maxTopPosMargin = posTop;
+                if (negTop > m_maxTopNegMargin)
+                    m_maxTopNegMargin = negTop;
+            }
+            
+            int ypos = m_height;
+            if (child->isSelfCollapsingBlock()) {
+                // This child has no height.  Update our previous pos and neg
+                // values and just keep going.
+                if (posTop > prevPosMargin)
+                    prevPosMargin = posTop;
+                if (negTop > prevNegMargin)
+                    prevNegMargin = negTop;
+                    
+                if (!topMarginContributor)
+                    // We need to make sure that the position of the self-collapsing block
+                    // is correct, since it could have overflowing content
+                    // that needs to be positioned correctly (e.g., a block that
+                    // had a specified height of 0 but that actually had subcontent).
+                    ypos = m_height + prevPosMargin - prevNegMargin;
+            }
+            else {
+                if (!topMarginContributor || 
+                     (!canCollapseWithChildren && 
+                      (element()->getDocument()->parseMode() == DocumentImpl::Strict ||
+                        !isTableCell()))) {
+                    // We're collapsing with a previous sibling's margins and not
+                    // with the top of the block.
+                    int absPos = prevPosMargin > posTop ? prevPosMargin : posTop;
+                    int absNeg = prevNegMargin > negTop ? prevNegMargin : negTop;
+                    int collapsedMargin = absPos - absNeg;
+                    m_height += collapsedMargin;
+                    ypos = m_height;
+                }
+                topMarginContributor = false;
+                prevPosMargin = child->maxBottomMargin(true);
+                prevNegMargin = child->maxBottomMargin(false);
+            }
+            child->setPos(child->xPos(), ypos);
+        }
+        
         int chPos = xPos + child->marginLeft();
 
         if(style()->direction() == LTR) {
             // html blocks flow around floats
-            if ( ( style()->htmlHacks() || child->isTable() ) && child->style()->flowAroundFloats() ) {
+            if ( ( style()->htmlHacks() || child->isTable() ) && child->style()->flowAroundFloats() ) 			{
                 int leftOff = leftOffset(m_height);
                 if (leftOff != xPos) {
                     // The object is shifting right. The object might be centered, so we need to 
@@ -456,8 +498,8 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
                         cw = static_cast<RenderFlow *>(cb)->lineWidth( child->yPos() );
                     else
                         cw = cb->contentWidth();
-                    static_cast<RenderBox*>(child)->calcHorizontalMargins(child->style()->marginLeft(), 				                                          child->style()->marginRight(), 
-                                                                          cw);
+                    static_cast<RenderBox*>(child)->calcHorizontalMargins															( child->style()->marginLeft(), 				                                          								  child->style()->marginRight(), 
+                                  cw);
                     chPos = leftOff + child->marginLeft();
                 }
             }
@@ -466,27 +508,54 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
             if ( ( style()->htmlHacks() || child->isTable() ) && child->style()->flowAroundFloats() )
                 chPos -= leftOffset(m_height);
         }
+        
         child->setPos(chPos, child->yPos());
 
         m_height += child->height();
 
-        prevMargin = child->marginBottom();
-
         if (child->isFlow())
             prevFlow = static_cast<RenderFlow*>(child);
 
-	if ( child->hasOverhangingFloats() ) {
-	    // need to add the float to our special objects
-	    addOverHangingFloats( static_cast<RenderFlow *>(child), -child->xPos(), -child->yPos(), true );
-	}
+        if ( child->hasOverhangingFloats() ) {
+            // need to add the float to our special objects
+            addOverHangingFloats( static_cast<RenderFlow *>(child), -child->xPos(), -child->yPos(), true );
+        }
 
         child = child->nextSibling();
     }
 
-    if(!isTableCell() && toAdd != 0)
-	m_height += prevMargin;
+    // XXX This check is unconvincing. Needs to be a reliable way to test for auto height. -dwh
+    bool autoHeight = style()->height().isVariable() && style()->height().value == 0;
+    
+    // If any height other than auto is specified in CSS, then we don't collapse our bottom
+    // margins with our children's margins.  To do otherwise would be to risk odd visual
+    // effects when the children overflow out of the parent block and yet still collapse
+    // with it.
+    if (canCollapseWithChildren && !autoHeight)
+        canCollapseWithChildren = false;
+        
+    // If we can't collapse with children then go ahead and add in the bottom margins.
+    if (!canCollapseWithChildren && !topMarginContributor &&
+        (element()->getDocument()->parseMode() == DocumentImpl::Strict ||
+         !isTableCell()))
+        m_height += prevPosMargin - prevNegMargin;
+        
     m_height += toAdd;
-
+    
+    // Negative margins can cause our height to shrink below our minimal height (border/padding).
+    // If this happens, ensure that the computed height is increased to the minimal height.
+    if (m_height < minHeight)
+        m_height = minHeight;
+    
+    if (canCollapseWithChildren && !topMarginContributor) {
+        // Update our max pos/neg bottom margins, since we collapsed our bottom margins
+        // with our children.
+        if (prevPosMargin > m_maxBottomPosMargin)
+            m_maxBottomPosMargin = prevPosMargin;
+        if (prevNegMargin > m_maxBottomNegMargin)
+            m_maxBottomNegMargin = prevNegMargin;
+    }
+    
     setLayouted();
 
     // kdDebug( 6040 ) << "layouted = " << layouted_ << endl;
diff --git a/WebCore/khtml/rendering/render_flow.h b/WebCore/khtml/rendering/render_flow.h
index e97fc87..5e58706 100644
--- a/WebCore/khtml/rendering/render_flow.h
+++ b/WebCore/khtml/rendering/render_flow.h
@@ -132,6 +132,8 @@ public:
     void bidiReorderLine(const BidiIterator &start, const BidiIterator &end);
     BidiIterator findNextLineBreak(BidiIterator &start);
 
+    virtual bool isSelfCollapsingBlock() const { return m_height == 0; }
+    
     virtual short maxTopMargin(bool positive) const {
         if (positive)
             return m_maxTopPosMargin;
diff --git a/WebCore/khtml/rendering/render_object.h b/WebCore/khtml/rendering/render_object.h
index a3ed267..8fd023e 100644
--- a/WebCore/khtml/rendering/render_object.h
+++ b/WebCore/khtml/rendering/render_object.h
@@ -367,6 +367,7 @@ public:
     // For a non-collapsing, e.g., a leaf element, this formula will simply return
     // the margin of the element.  Blocks override the maxTopMargin and maxBottomMargin
     // methods.
+    virtual bool isSelfCollapsingBlock() const { return false; }
     virtual short collapsedMarginTop() const 
         { return maxTopMargin(true)-maxTopMargin(false); }
     virtual short collapsedMarginBottom() const 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list