# HG changeset patch # User Boris Zbarsky # Date 1285047226 14400 # Node ID 6c5a0576473a60efcf8c94a4caa5c3d3c50000a4 # Parent 98e964205d79eb6527a5bfe2dc8f12e6dacc1e76 Bug 129941. Don't create scrollframes for blockframes (except inline blocks) while printing, and make such blockframes clip their contents instead. r=dbaron diff -r 98e964205d79 -r 6c5a0576473a layout/base/nsCSSFrameConstructor.cpp --- a/layout/base/nsCSSFrameConstructor.cpp Sun Sep 12 22:06:02 2010 -0400 +++ b/layout/base/nsCSSFrameConstructor.cpp Tue Sep 21 01:33:46 2010 -0400 @@ -4390,14 +4390,24 @@ PropagateScrollToViewport() == aContent; } + NS_ASSERTION(!propagatedScrollToViewport || + !mPresShell->GetPresContext()->IsPaginated(), + "Shouldn't propagate scroll in paginated contexts"); + // If the frame is a block-level frame and is scrollable, then wrap it - // in a scroll frame. + // in a scroll frame. Except we don't want to do that for paginated contexts + // for frames that are block-outside. + // The condition on skipping scrollframe construction in the + // paginated case needs to match code in ConstructNonScrollableBlock + // and in nsFrame::ApplyPaginatedOverflowClipping. // XXX Ignore tables for the time being // XXXbz it would be nice to combine this with the other block // case... Think about how do do this? if (aDisplay->IsBlockInside() && aDisplay->IsScrollableOverflow() && - !propagatedScrollToViewport) { + !propagatedScrollToViewport && + (!mPresShell->GetPresContext()->IsPaginated() || + !aDisplay->IsBlockOutside())) { static const FrameConstructionData sScrollableBlockData = FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructScrollableBlock); return &sScrollableBlockData; @@ -4525,7 +4535,17 @@ if (aDisplay->IsAbsolutelyPositioned() || aDisplay->IsFloating() || - NS_STYLE_DISPLAY_INLINE_BLOCK == aDisplay->mDisplay) { + NS_STYLE_DISPLAY_INLINE_BLOCK == aDisplay->mDisplay || + // This check just needs to be the same as the check for using + // scrollable blocks in FindDisplayData; we want a block + // formatting context root in paginated contexts for every block + // that would be scrollable in a non-paginated context. Note + // that IsPaginated() implies that no propagation to viewport + // has taken place, so we don't need to check for propagation + // here. + (mPresShell->GetPresContext()->IsPaginated() && + aDisplay->IsBlockInside() && + aDisplay->IsScrollableOverflow())) { *aNewFrame = NS_NewBlockFormattingContext(mPresShell, styleContext); } else { *aNewFrame = NS_NewBlockFrame(mPresShell, styleContext); diff -r 98e964205d79 -r 6c5a0576473a layout/generic/nsFrame.cpp --- a/layout/generic/nsFrame.cpp Sun Sep 12 22:06:02 2010 -0400 +++ b/layout/generic/nsFrame.cpp Tue Sep 21 01:33:46 2010 -0400 @@ -1057,8 +1057,8 @@ * Returns PR_TRUE if aFrame is overflow:hidden and we should interpret * that as -moz-hidden-unscrollable. */ -static PRBool ApplyOverflowHiddenClipping(nsIFrame* aFrame, - const nsStyleDisplay* aDisp) +static inline PRBool ApplyOverflowHiddenClipping(nsIFrame* aFrame, + const nsStyleDisplay* aDisp) { if (aDisp->mOverflowX != NS_STYLE_OVERFLOW_HIDDEN) return PR_FALSE; @@ -1075,6 +1075,21 @@ type == nsGkAtoms::bcTableCellFrame; } +static inline PRBool ApplyPaginatedOverflowClipping(nsIFrame* aFrame, + const nsStyleDisplay* aDisp) +{ + // These conditions on aDisp need to match the conditions for which in + // non-paginated contexts we'd create a scrollframe for a block but in a + // paginated context we don't. See nsCSSFrameConstructor::FindDisplayData + // for the relevant conditions. + return + aFrame->PresContext()->IsPaginated() && + aDisp->IsBlockInside() && + aDisp->IsScrollableOverflow() && + aDisp->IsBlockOutside() && + aFrame->GetType() == nsGkAtoms::blockFrame; +} + static PRBool ApplyOverflowClipping(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, const nsStyleDisplay* aDisp, nsRect* aRect) { @@ -1084,8 +1099,10 @@ // changed -moz-hidden-unscrollable to apply to any kind of frame. // Only -moz-hidden-unscrollable is handled here (and 'hidden' for table - // frames). Other overflow clipping is applied by nsHTML/XULScrollFrame. - if (!ApplyOverflowHiddenClipping(aFrame, aDisp)) { + // frames, and any non-visible value for blocks in a paginated context). + // Other overflow clipping is applied by nsHTML/XULScrollFrame. + if (!ApplyOverflowHiddenClipping(aFrame, aDisp) && + !ApplyPaginatedOverflowClipping(aFrame, aDisp)) { PRBool clip = aDisp->mOverflowX == NS_STYLE_OVERFLOW_CLIP; if (!clip) return PR_FALSE; diff -r 98e964205d79 -r 6c5a0576473a layout/reftests/printing/129941-1-ref.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layout/reftests/printing/129941-1-ref.html Tue Sep 21 01:33:46 2010 -0400 @@ -0,0 +1,8 @@ + + + +
+
+
+ + diff -r 98e964205d79 -r 6c5a0576473a layout/reftests/printing/129941-1a.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layout/reftests/printing/129941-1a.html Tue Sep 21 01:33:46 2010 -0400 @@ -0,0 +1,8 @@ + + + +
+
+
+ + diff -r 98e964205d79 -r 6c5a0576473a layout/reftests/printing/129941-1b.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layout/reftests/printing/129941-1b.html Tue Sep 21 01:33:46 2010 -0400 @@ -0,0 +1,8 @@ + + + +
+
+
+ + diff -r 98e964205d79 -r 6c5a0576473a layout/reftests/printing/reftest.list --- a/layout/reftests/printing/reftest.list Sun Sep 12 22:06:02 2010 -0400 +++ b/layout/reftests/printing/reftest.list Tue Sep 21 01:33:46 2010 -0400 @@ -7,3 +7,5 @@ == 403669-1.html 403669-1-ref.html == 381497-n.html 381497-f.html == test-async-print.html 272830-1-ref.html +== 129941-1a.html 129941-1-ref.html +== 129941-1b.html 129941-1-ref.html