The position of an outside bullet should not be affected by floats inside the principal block (this fixes most cases). b=427370 r+sr=dbaron a1.9=beltzner
authormats.palmgren@bredband.net
Sun, 13 Apr 2008 10:43:12 -0700
changeset 14271 4491200dc79368a477a40508f7e0112f328ece69
parent 14270 9339b426122153bf483d48d069c7cd94ac009fb9
child 14272 4e8a9c5f4039b54d0065582c2a7efe12ec417e34
push idunknown
push userunknown
push dateunknown
bugs427370
milestone1.9pre
The position of an outside bullet should not be affected by floats inside the principal block (this fixes most cases). b=427370 r+sr=dbaron a1.9=beltzner
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockReflowState.cpp
layout/generic/nsBlockReflowState.h
layout/reftests/bugs/427370-1-ref.html
layout/reftests/bugs/427370-1.html
layout/reftests/bugs/reftest.list
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -6587,45 +6587,28 @@ nsBlockFrame::ReflowBullet(nsBlockReflow
   // XXXwaterson Should this look just like the logic in
   // nsBlockReflowContext::ReflowBlock and nsLineLayout::ReflowFrame?
   nsHTMLReflowState reflowState(aState.mPresContext, rs,
                                 mBullet, availSize);
   nsReflowStatus  status;
   mBullet->WillReflow(aState.mPresContext);
   mBullet->Reflow(aState.mPresContext, aMetrics, reflowState, status);
 
-  // Place the bullet now.  We want to place the bullet relative to the
-  // border-box of the associated box (using the right/left margin of
-  // the bullet frame as separation).  However, if a line box would be
-  // displaced by floats, we want to displace it by the same amount.
-  // That is, we act as though the edge of the floats is the
-  // content-edge of the block, and place the bullet at a position
-  // offset from there by the block's padding, the block's border, and
-  // the bullet frame's margin.
-  // FIXME (bug 25888): need to check the entire region that the first
-  // line overlaps, not just the top pixel.
-  nscoord x;
-  aState.GetAvailableSpace(aLineTop, PR_FALSE);
-  if (rs.mStyleVisibility->mDirection == NS_STYLE_DIRECTION_LTR) {
-    // Note: mAvailSpaceRect.x is relative to the content box and never
-    // less than zero.  Converting to frame coordinates and subtracting
-    // the padding and border cancel each other out, and the PR_MAX()
-    // with 0 (or with the left border+padding) is even implied in the
-    // right place.
-    x = aState.mAvailSpaceRect.x
-        - reflowState.mComputedMargin.right - aMetrics.width;
-  } else {
-    // The XMost() of the available space and the computed width both
-    // give us offsets from the left content edge.  Then we add the left
-    // border/padding to get into frame coordinates, and the right
-    // border/padding and the bullet's margin to offset the position.
-    x = PR_MIN(rs.ComputedWidth(), aState.mAvailSpaceRect.XMost())
-        + rs.mComputedBorderPadding.LeftRight()
-        + reflowState.mComputedMargin.left;
-  }
+  // Place the bullet now, separate it from mOutsideBulletX by its margin.
+  // If the mAvailSpaceRect position is outside the mOutsideBulletX
+  // position it means the line didn't care about the float edge and we
+  // use that position instead (there cannot be any floats at the start
+  // of the line this case since that would violate CSS 2.1 float rules).
+  // XXX we need to take floats inside the principal block that clears
+  // outside floats into account also (bug 428810).
+  nscoord x = rs.mStyleVisibility->mDirection == NS_STYLE_DIRECTION_LTR ?
+    PR_MIN(aState.mOutsideBulletX, aState.mAvailSpaceRect.x)
+      - reflowState.mComputedMargin.right - aMetrics.width :
+    PR_MAX(aState.mOutsideBulletX, aState.mAvailSpaceRect.XMost())
+      + reflowState.mComputedMargin.left;
 
   // FIXME: come up with rules for when mAvailSpaceRect is valid so we
   // don't need to do this.
   aState.GetAvailableSpace();
 
   // Approximate the bullets position; vertical alignment will provide
   // the final vertical location.
   const nsMargin& bp = aState.BorderPadding();
--- a/layout/generic/nsBlockReflowState.cpp
+++ b/layout/generic/nsBlockReflowState.cpp
@@ -136,16 +136,26 @@ nsBlockReflowState::nsBlockReflowState(c
   mY = borderPadding.top;
   mBand.Init(mSpaceManager, mContentArea);
 
   mPrevChild = nsnull;
   mCurrentLine = aFrame->end_lines();
 
   mMinLineHeight = nsHTMLReflowState::CalcLineHeight(aReflowState.rendContext,
                                                      aReflowState.frame);
+
+  // Calculate mOutsideBulletX
+  GetAvailableSpace();
+  // FIXME (bug 25888): need to check the entire region that the first
+  // line overlaps, not just the top pixel.
+  mOutsideBulletX =
+    mReflowState.mStyleVisibility->mDirection == NS_STYLE_DIRECTION_LTR ?
+      mAvailSpaceRect.x :
+      PR_MIN(mReflowState.ComputedWidth(), mAvailSpaceRect.XMost()) +
+        mReflowState.mComputedBorderPadding.LeftRight();
 }
 
 void
 nsBlockReflowState::SetupOverflowPlaceholdersProperty()
 {
   if (mReflowState.availableHeight != NS_UNCONSTRAINEDSIZE ||
       !mOverflowPlaceholders.IsEmpty()) {
     mBlock->SetProperty(nsGkAtoms::overflowPlaceholdersProperty,
--- a/layout/generic/nsBlockReflowState.h
+++ b/layout/generic/nsBlockReflowState.h
@@ -180,16 +180,23 @@ public:
   // padding. This, therefore, represents the inner "content area" (in
   // spacemanager coordinates) where child frames will be placed,
   // including child blocks and floats.
   nscoord mSpaceManagerX, mSpaceManagerY;
 
   // XXX get rid of this
   nsReflowStatus mReflowStatus;
 
+  // The x-position we should place an outside bullet relative to.
+  // This is the border-box edge of the principal box.  However, if a line box
+  // would be displaced by floats, we want to displace it by the same amount.
+  // That is, we act as though the edge of the floats is the content-edge of
+  // the block, displaced by the block's padding and border.
+  nscoord mOutsideBulletX;
+
   nscoord mBottomEdge;
 
   // The content area to reflow child frames within. The x/y
   // coordinates are known to be mBorderPadding.left and
   // mBorderPadding.top. The width/height may be NS_UNCONSTRAINEDSIZE
   // if the container reflowing this frame has given the frame an
   // unconstrained area.
   nsSize mContentArea;
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/427370-1-ref.html
@@ -0,0 +1,152 @@
+<!DOCTYPE HTML>
+<html><head>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+    <title>Testcase for bug 427370</title>
+    <style type="text/css">
+
+        html,body {
+            color:black; background-color: white; font-size:16px; padding:0; margin:0;
+        }
+        body {
+            margin:10px;
+        }
+        ol,li{margin:0!important;padding:0!important}
+        ol { margin-top:1em!important; }
+        .rtl li {margin-right:40px!important;}
+        .ltr li {margin-left:40px!important;}
+
+        DEBUG_li {
+                outline:1px dashed red;
+                border:3px dashed blue;
+        }
+        .inside li {
+                list-style-position:inside;
+        }
+
+        .rtl label { 
+                float:right;
+        }
+        .ltr label { 
+                float:left;
+        }
+
+        label {
+                width:100px;
+                height:1em;
+                background:pink;
+        }
+
+        .rtl { 
+                direction:rtl;
+        }
+        .ltr { 
+                direction:ltr;
+        }
+
+    </style>
+</head>
+<body>
+<div style="position:absolute;top:0;left: 50px;bottom:0;width:1px;background:lime;opacity:0.5"></div>
+<div style="position:absolute;top:0;right:50px;bottom:0;width:1px;background:lime;opacity:0.5"></div>
+
+<div class="ltr">
+                <ol>
+                        <li><div style="overflow:hidden;">
+                                <label></label>
+                                Outside
+                        </div></li>
+                        <li><div style="overflow:hidden;">
+                                <div></div><div>C</div>
+                        </div></li>
+</ol>
+</div>
+
+<div class="rtl">
+<ol>
+                        <li><div style="overflow:hidden;">
+                                <label></label>
+                                Outside
+                        </div></li>
+                        <li><div style="overflow:hidden;">
+                                <div></div><div>C</div>
+                        </div></li>
+</ol>
+</div>
+
+<br style="clear:both;">
+
+<div style="float:left; width:100px; height:5em; border:1px solid black"></div>
+<div class="ltr">
+                <ol>
+                        <li><div style="overflow:hidden;">
+                                <label></label>
+                                Outside
+                        </div></li>
+                        <li><div style="overflow:hidden;">
+                                <div></div><div>C</div>
+                        </div></li>
+</ol>
+</div>
+
+<br style="clear:both;">
+
+<div style="float:right; width:100px; height:5em; border:1px solid black"></div>
+<div class="rtl">
+<ol>
+                        <li><div style="overflow:hidden;">
+                                <label></label>
+                                Outside
+                        </div></li>
+                        <li><div style="overflow:hidden;">
+                                <div></div><div>C</div>
+                        </div></li>
+</ol>
+</div>
+
+
+<br style="clear:both;">
+
+<div class="ltr">
+                <ol>
+                        <li><div><div style="overflow:hidden;">
+                                <label></label>
+                                Outside
+                        </div></div></li>
+</ol>
+</div>
+
+<div class="rtl">
+<ol>
+                        <li><div><div style="overflow:hidden;">
+                                <label></label>
+                                Outside
+                        </div></div></li>
+</ol>
+</div>
+
+<br style="clear:both;">
+
+<div style="float:left; width:100px; height:5em; border:1px solid black"></div>
+<div class="ltr">
+                <ol>
+                        <li><div><div style="overflow:hidden;">
+                                <label></label>
+                                Outside
+                        </div></div></li>
+</ol>
+</div>
+
+<br style="clear:both;">
+
+<div style="float:right; width:100px; height:5em; border:1px solid black"></div>
+<div class="rtl">
+<ol>
+                        <li><div><div style="overflow:hidden;">
+                                <label></label>
+                                Outside
+                        </div></div></li>
+</ol>
+</div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/427370-1.html
@@ -0,0 +1,152 @@
+<!DOCTYPE HTML>
+<html><head>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+    <title>Testcase for bug 427370</title>
+    <style type="text/css">
+
+        html,body {
+            color:black; background-color: white; font-size:16px; padding:0; margin:0;
+        }
+        body {
+            margin:10px;
+        }
+        ol,li{margin:0!important;padding:0!important}
+        ol { margin-top:1em!important; }
+        .rtl li {margin-right:40px!important;}
+        .ltr li {margin-left:40px!important;}
+
+        DEBUG_li {
+                outline:1px dashed red;
+                border:3px dashed blue;
+        }
+        .inside li {
+                list-style-position:inside;
+        }
+
+        .rtl label { 
+                float:right;
+        }
+        .ltr label { 
+                float:left;
+        }
+
+        label {
+                width:100px;
+                height:1em;
+                background:pink;
+        }
+
+        .rtl { 
+                direction:rtl;
+        }
+        .ltr { 
+                direction:ltr;
+        }
+
+    </style>
+</head>
+<body>
+<div style="position:absolute;top:0;left: 50px;bottom:0;width:1px;background:lime;opacity:0.5"></div>
+<div style="position:absolute;top:0;right:50px;bottom:0;width:1px;background:lime;opacity:0.5"></div>
+
+<div class="ltr">
+                <ol>
+                        <li>
+                                <label></label>
+                                Outside
+                        </li>
+                        <li>
+                                <div></div><div>C</div>
+                        </li>
+</ol>
+</div>
+
+<div class="rtl">
+<ol>
+                        <li>
+                                <label></label>
+                                Outside
+                        </li>
+                        <li>
+                                <div></div><div>C</div>
+                        </li>
+</ol>
+</div>
+
+<br style="clear:both;">
+
+<div style="float:left; width:100px; height:5em; border:1px solid black"></div>
+<div class="ltr">
+                <ol>
+                        <li>
+                                <label></label>
+                                Outside
+                        </li>
+                        <li>
+                                <div></div><div>C</div>
+                        </li>
+</ol>
+</div>
+
+<br style="clear:both;">
+
+<div style="float:right; width:100px; height:5em; border:1px solid black"></div>
+<div class="rtl">
+<ol>
+                        <li>
+                                <label></label>
+                                Outside
+                        </li>
+                        <li>
+                                <div></div><div>C</div>
+                        </li>
+</ol>
+</div>
+
+
+<br style="clear:both;">
+
+<div class="ltr">
+                <ol>
+                        <li><div>
+                                <label></label>
+                                Outside
+                        </div></li>
+</ol>
+</div>
+
+<div class="rtl">
+<ol>
+                        <li><div>
+                                <label></label>
+                                Outside
+                        </div></li>
+</ol>
+</div>
+
+<br style="clear:both;">
+
+<div style="float:left; width:100px; height:5em; border:1px solid black"></div>
+<div class="ltr">
+                <ol>
+                        <li><div>
+                                <label></label>
+                                Outside
+                        </div></li>
+</ol>
+</div>
+
+<br style="clear:both;">
+
+<div style="float:right; width:100px; height:5em; border:1px solid black"></div>
+<div class="rtl">
+<ol>
+                        <li><div>
+                                <label></label>
+                                Outside
+                        </div></li>
+</ol>
+</div>
+
+</body>
+</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -793,8 +793,9 @@ fails-if(MOZ_WIDGET_TOOLKIT=="gtk2") == 
 == 424236-10.html 424236-10-ref.html
 == 424434-1.html 424434-1-ref.html
 == 424631-1.html 424631-1-ref.html
 == 424710-1.html 424710-1-ref.html
 == 425972-1.html 425972-1-ref.html
 == 425972-2.html 425972-2-ref.html
 != 425972-1.html 425972-2.html
 != 427017-1.xhtml about:blank    # crash test (needs reftest-print)
+== 427370-1.html 427370-1-ref.html