Bug 129941. Don't create scrollframes for blockframes (except inline blocks) while printing, and make such blockframes clip their contents instead. r=dbaron

This commit is contained in:
Boris Zbarsky
2010-10-06 21:01:24 -04:00
parent 8a399a3e22
commit 2545e55aaf
6 changed files with 74 additions and 7 deletions

View File

@@ -4354,14 +4354,24 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay* aDisplay,
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;
@@ -4489,7 +4499,18 @@ nsCSSFrameConstructor::ConstructNonScrollableBlock(nsFrameConstructorState& aSta
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 and the check for clipping in
// nsFrame::ApplyPaginatedOverflowClipping; 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() &&
aDisplay->IsBlockOutside())) {
*aNewFrame = NS_NewBlockFormattingContext(mPresShell, styleContext);
} else {
*aNewFrame = NS_NewBlockFrame(mPresShell, styleContext);

View File

@@ -1197,7 +1197,7 @@ static PRBool ApplyAbsPosClipping(nsDisplayListBuilder* aBuilder,
* Returns PR_TRUE if aFrame is overflow:hidden and we should interpret
* that as -moz-hidden-unscrollable.
*/
static PRBool ApplyOverflowHiddenClipping(nsIFrame* aFrame,
static inline PRBool ApplyOverflowHiddenClipping(nsIFrame* aFrame,
const nsStyleDisplay* aDisp)
{
if (aDisp->mOverflowX != NS_STYLE_OVERFLOW_HIDDEN)
@@ -1215,6 +1215,24 @@ static PRBool ApplyOverflowHiddenClipping(nsIFrame* aFrame,
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. These conditions must also match those in
// nsCSSFrameConstructor::ConstructNonScrollableBlock for creating block
// formatting context roots for forced-to-be-no-longer scrollable blocks in
// paginated contexts.
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) {
@@ -1224,8 +1242,10 @@ static PRBool ApplyOverflowClipping(nsDisplayListBuilder* aBuilder,
// 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;

View File

@@ -0,0 +1,8 @@
<!DOCTYPE html>
<html class="reftest-print" style="margin: 0; padding: 0">
<body style="margin: 0; padding: 0">
<div style="height: 1.25in; border: 0.25in solid green"></div>
<div style="height: 1.25in; border: 0.25in solid green"></div>
<div style="height: 1.25in; border: 0.25in solid green; border-bottom: none"></div>
</body>
</html>

View File

@@ -0,0 +1,8 @@
<!DOCTYPE html>
<html class="reftest-print" style="margin: 0; padding: 0;">
<body style="overflow: scroll; height: 5in; margin: 0; padding: 0;">
<div style="height: 1.25in; border: 0.25in solid green"></div>
<div style="height: 1.25in; border: 0.25in solid green"></div>
<div style="height: 1.25in; border: 0.25in solid green"></div>
</body>
</html>

View File

@@ -0,0 +1,8 @@
<!DOCTYPE html>
<html class="reftest-print" style="margin: 0; padding: 0;">
<body style="overflow: -moz-hidden-unscrollable; height: 5in; margin: 0; padding: 0;">
<div style="height: 1.25in; border: 0.25in solid green"></div>
<div style="height: 1.25in; border: 0.25in solid green"></div>
<div style="height: 1.25in; border: 0.25in solid green"></div>
</body>
</html>

View File

@@ -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