From 66e4b800823b1dc59c9f1bc5d1ea9c4dd8cee8e6 Mon Sep 17 00:00:00 2001 From: "alexsavulov%netscape.com" Date: Fri, 8 Mar 2002 20:25:54 +0000 Subject: [PATCH] fix for bug 122200 - floaters regression and fix for bug 99461 - floating tables will be constrained in the same line if they can fit quirks mode only sr= attinasi, r= kin, a= asa git-svn-id: svn://10.0.0.236/trunk@116174 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/generic/nsBlockFrame.cpp | 32 +++++++- mozilla/layout/generic/nsBlockReflowState.cpp | 80 +++++++++++++++++-- mozilla/layout/html/base/src/nsBlockFrame.cpp | 32 +++++++- .../html/base/src/nsBlockReflowState.cpp | 80 +++++++++++++++++-- 4 files changed, 206 insertions(+), 18 deletions(-) diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index 733dc4c71d5..68f5f14cdd8 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -5103,9 +5103,35 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, // Compute the available width. By default, assume the width of the // containing block. - nscoord availWidth = aState.GetFlag(BRS_UNCONSTRAINEDWIDTH) - ? NS_UNCONSTRAINEDSIZE - : aState.mContentArea.width; + nscoord availWidth; + if(aState.GetFlag(BRS_UNCONSTRAINEDWIDTH)){ + availWidth = NS_UNCONSTRAINEDSIZE; + }else{ + const nsStyleDisplay* floaterDisplay; + floater->GetStyleData(eStyleStruct_Display, + (const nsStyleStruct*&)floaterDisplay); + nsCompatibility mode; + aState.mPresContext->GetCompatibilityMode(&mode); + + if (NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay || + eCompatibility_NavQuirks != mode ) { + availWidth = aState.mContentArea.width; + }else{ + // give tables only the available space + // if they can shrink we may not be constrained to place + // them in the next line + availWidth = aState.mAvailSpaceRect.width; + // round down to twips per pixel so that we fit + // needed when prev. floater has procentage width + // (maybe is a table flaw that makes table chose to round up + // but i don't want to change that, too risky) + nscoord twp; + float p2t; + aState.mPresContext->GetScaledPixelsToTwips(&p2t); + twp = NSIntPixelsToTwips(1,p2t); + availWidth -= availWidth % twp; + } + } // If the floater's width is automatic, we can't let the floater's // width shrink below its maxElementSize. diff --git a/mozilla/layout/generic/nsBlockReflowState.cpp b/mozilla/layout/generic/nsBlockReflowState.cpp index 36369ec34bb..ab7df2803ac 100644 --- a/mozilla/layout/generic/nsBlockReflowState.cpp +++ b/mozilla/layout/generic/nsBlockReflowState.cpp @@ -47,6 +47,10 @@ #include "nsLayoutAtoms.h" #include "nsIFrame.h" +#include "nsINameSpaceManager.h" +#include "nsHTMLAtoms.h" + + #ifdef DEBUG #include "nsBlockDebugFlags.h" #endif @@ -887,12 +891,70 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, "invalid float type"); // Can the floater fit here? - while (! CanPlaceFloater(region, floaterDisplay->mFloats)) { - // Nope. Advance to the next band. - mY += mAvailSpaceRect.height; - GetAvailableSpace(); - } + PRBool keepFloaterOnSameLine = PR_FALSE; + nsCompatibility mode; + mPresContext->GetCompatibilityMode(&mode); + while (! CanPlaceFloater(region, floaterDisplay->mFloats)) { + // Nope. try to advance to the next band. + if (NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay || + eCompatibility_NavQuirks != mode ) { + + mY += mAvailSpaceRect.height; + GetAvailableSpace(); + } else { + // IE handles floater tables in a very special way + + // see if the previous floater is also a table and has "align" + nsFloaterCache* fc = mCurrentLineFloaters.Head(); + nsIFrame* prevFrame = nsnull; + while (fc) { + if (fc->mPlaceholder->GetOutOfFlowFrame() == floater) { + break; + } + prevFrame = fc->mPlaceholder->GetOutOfFlowFrame(); + fc = fc->Next(); + } + + //get the frame type + nsIAtom* atom; + prevFrame->GetFrameType(&atom); + if(nsLayoutAtoms::tableOuterFrame == atom) { + //see if it has "align=" + // IE makes a difference between align and he float property + nsCOMPtr content; + prevFrame->GetContent(getter_AddRefs(content)); + if (content) { + nsAutoString value; + if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttr(kNameSpaceID_None, nsHTMLAtoms::align, value)) { + // we're interested only if previous frame is align=left + // IE messes things up when "right" (overlapping frames) + if (value.EqualsIgnoreCase("left")) { + keepFloaterOnSameLine = PR_TRUE; + // don't advance to next line (IE quirkie behaviour) + // it breaks rule CSS2/9.5.1/1, but what the hell + // since we cannot evangelize the world + break; + } + } + } + } + + // the table does not fit anymore in this line so advance to next band + mY += mAvailSpaceRect.height; + GetAvailableSpace(); + // reflow the floater again now since we have more space + mBlock->ReflowFloater(*this, aFloaterCache->mPlaceholder, aFloaterCache->mCombinedArea, + aFloaterCache->mMargins, aFloaterCache->mOffsets); + // Get the floaters bounding box and margin information + floater->GetRect(region); + // Adjust the floater size by its margin. That's the area that will + // impact the space manager. + region.width += aFloaterCache->mMargins.left + aFloaterCache->mMargins.right; + region.height += aFloaterCache->mMargins.top + aFloaterCache->mMargins.bottom; + + } + } // Assign an x and y coordinate to the floater. Note that the x,y // coordinates are computed relative to the translation in the // spacemanager which means that the impacted region will be @@ -906,7 +968,13 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, else { isLeftFloater = PR_FALSE; if (NS_UNCONSTRAINEDSIZE != mAvailSpaceRect.XMost()) - region.x = mAvailSpaceRect.XMost() - region.width; + if(!keepFloaterOnSameLine) { + region.x = mAvailSpaceRect.XMost() - region.width; + } else { + // this is the IE quirk (see few lines above) + // the table is keept in the same line: don't let it overlap the previous floater + region.x = mAvailSpaceRect.x; + } else { okToAddRectRegion = PR_FALSE; region.x = mAvailSpaceRect.x; diff --git a/mozilla/layout/html/base/src/nsBlockFrame.cpp b/mozilla/layout/html/base/src/nsBlockFrame.cpp index 733dc4c71d5..68f5f14cdd8 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.cpp +++ b/mozilla/layout/html/base/src/nsBlockFrame.cpp @@ -5103,9 +5103,35 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, // Compute the available width. By default, assume the width of the // containing block. - nscoord availWidth = aState.GetFlag(BRS_UNCONSTRAINEDWIDTH) - ? NS_UNCONSTRAINEDSIZE - : aState.mContentArea.width; + nscoord availWidth; + if(aState.GetFlag(BRS_UNCONSTRAINEDWIDTH)){ + availWidth = NS_UNCONSTRAINEDSIZE; + }else{ + const nsStyleDisplay* floaterDisplay; + floater->GetStyleData(eStyleStruct_Display, + (const nsStyleStruct*&)floaterDisplay); + nsCompatibility mode; + aState.mPresContext->GetCompatibilityMode(&mode); + + if (NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay || + eCompatibility_NavQuirks != mode ) { + availWidth = aState.mContentArea.width; + }else{ + // give tables only the available space + // if they can shrink we may not be constrained to place + // them in the next line + availWidth = aState.mAvailSpaceRect.width; + // round down to twips per pixel so that we fit + // needed when prev. floater has procentage width + // (maybe is a table flaw that makes table chose to round up + // but i don't want to change that, too risky) + nscoord twp; + float p2t; + aState.mPresContext->GetScaledPixelsToTwips(&p2t); + twp = NSIntPixelsToTwips(1,p2t); + availWidth -= availWidth % twp; + } + } // If the floater's width is automatic, we can't let the floater's // width shrink below its maxElementSize. diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.cpp b/mozilla/layout/html/base/src/nsBlockReflowState.cpp index 36369ec34bb..ab7df2803ac 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.cpp +++ b/mozilla/layout/html/base/src/nsBlockReflowState.cpp @@ -47,6 +47,10 @@ #include "nsLayoutAtoms.h" #include "nsIFrame.h" +#include "nsINameSpaceManager.h" +#include "nsHTMLAtoms.h" + + #ifdef DEBUG #include "nsBlockDebugFlags.h" #endif @@ -887,12 +891,70 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, "invalid float type"); // Can the floater fit here? - while (! CanPlaceFloater(region, floaterDisplay->mFloats)) { - // Nope. Advance to the next band. - mY += mAvailSpaceRect.height; - GetAvailableSpace(); - } + PRBool keepFloaterOnSameLine = PR_FALSE; + nsCompatibility mode; + mPresContext->GetCompatibilityMode(&mode); + while (! CanPlaceFloater(region, floaterDisplay->mFloats)) { + // Nope. try to advance to the next band. + if (NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay || + eCompatibility_NavQuirks != mode ) { + + mY += mAvailSpaceRect.height; + GetAvailableSpace(); + } else { + // IE handles floater tables in a very special way + + // see if the previous floater is also a table and has "align" + nsFloaterCache* fc = mCurrentLineFloaters.Head(); + nsIFrame* prevFrame = nsnull; + while (fc) { + if (fc->mPlaceholder->GetOutOfFlowFrame() == floater) { + break; + } + prevFrame = fc->mPlaceholder->GetOutOfFlowFrame(); + fc = fc->Next(); + } + + //get the frame type + nsIAtom* atom; + prevFrame->GetFrameType(&atom); + if(nsLayoutAtoms::tableOuterFrame == atom) { + //see if it has "align=" + // IE makes a difference between align and he float property + nsCOMPtr content; + prevFrame->GetContent(getter_AddRefs(content)); + if (content) { + nsAutoString value; + if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttr(kNameSpaceID_None, nsHTMLAtoms::align, value)) { + // we're interested only if previous frame is align=left + // IE messes things up when "right" (overlapping frames) + if (value.EqualsIgnoreCase("left")) { + keepFloaterOnSameLine = PR_TRUE; + // don't advance to next line (IE quirkie behaviour) + // it breaks rule CSS2/9.5.1/1, but what the hell + // since we cannot evangelize the world + break; + } + } + } + } + + // the table does not fit anymore in this line so advance to next band + mY += mAvailSpaceRect.height; + GetAvailableSpace(); + // reflow the floater again now since we have more space + mBlock->ReflowFloater(*this, aFloaterCache->mPlaceholder, aFloaterCache->mCombinedArea, + aFloaterCache->mMargins, aFloaterCache->mOffsets); + // Get the floaters bounding box and margin information + floater->GetRect(region); + // Adjust the floater size by its margin. That's the area that will + // impact the space manager. + region.width += aFloaterCache->mMargins.left + aFloaterCache->mMargins.right; + region.height += aFloaterCache->mMargins.top + aFloaterCache->mMargins.bottom; + + } + } // Assign an x and y coordinate to the floater. Note that the x,y // coordinates are computed relative to the translation in the // spacemanager which means that the impacted region will be @@ -906,7 +968,13 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache, else { isLeftFloater = PR_FALSE; if (NS_UNCONSTRAINEDSIZE != mAvailSpaceRect.XMost()) - region.x = mAvailSpaceRect.XMost() - region.width; + if(!keepFloaterOnSameLine) { + region.x = mAvailSpaceRect.XMost() - region.width; + } else { + // this is the IE quirk (see few lines above) + // the table is keept in the same line: don't let it overlap the previous floater + region.x = mAvailSpaceRect.x; + } else { okToAddRectRegion = PR_FALSE; region.x = mAvailSpaceRect.x;