mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-04 15:51:37 +00:00
Bug 480452. Make {ib} splits behave the same way with regard to margins, borders, and padding as inline frames that just have a line-break happening inside them do. r+sr=dbaron
This commit is contained in:
parent
4ce33a6c6d
commit
56ee16413d
@ -842,6 +842,29 @@ nsBidiPresUtils::IsLeftOrRightMost(nsIFrame* aFrame,
|
||||
(isLTR ? !firstFrameState->mHasContOnNextLines
|
||||
: !firstFrameState->mHasContOnPrevLines);
|
||||
|
||||
if ((aIsLeftMost || aIsRightMost) &&
|
||||
(aFrame->GetStateBits() & NS_FRAME_IS_SPECIAL)) {
|
||||
// For ib splits, don't treat the first part as endmost or the
|
||||
// last part as startmost.
|
||||
if (nsLayoutUtils::FrameIsInFirstPartOfIBSplit(aFrame)) {
|
||||
// We are not endmost
|
||||
if (isLTR) {
|
||||
aIsRightMost = PR_FALSE;
|
||||
} else {
|
||||
aIsLeftMost = PR_FALSE;
|
||||
}
|
||||
} else {
|
||||
NS_ASSERTION(nsLayoutUtils::FrameIsInLastPartOfIBSplit(aFrame),
|
||||
"How did that happen?");
|
||||
// We are not startmost
|
||||
if (isLTR) {
|
||||
aIsLeftMost = PR_FALSE;
|
||||
} else {
|
||||
aIsRightMost = PR_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reduce number of remaining frames of the continuation chain on the line.
|
||||
firstFrameState->mFrameCount--;
|
||||
}
|
||||
@ -964,7 +987,8 @@ nsBidiPresUtils::RepositionInlineFrames(nsIFrame* aFirstChild) const
|
||||
// bidiUtils->ReorderFrames, so this is guaranteed to be after the inlines
|
||||
// have been reflowed, which is required for GetUsedMargin/Border/Padding
|
||||
nsMargin margin = aFirstChild->GetUsedMargin();
|
||||
if (!aFirstChild->GetPrevContinuation())
|
||||
if (!aFirstChild->GetPrevContinuation() &&
|
||||
!nsLayoutUtils::FrameIsInLastPartOfIBSplit(aFirstChild))
|
||||
leftSpace = isLTR ? margin.left : margin.right;
|
||||
|
||||
nscoord left = aFirstChild->GetPosition().x - leftSpace;
|
||||
|
@ -499,9 +499,9 @@ SetFrameIsSpecial(nsIFrame* aFrame, nsIFrame* aSpecialSibling)
|
||||
}
|
||||
|
||||
if (aSpecialSibling) {
|
||||
// We should be the first-in-flow
|
||||
NS_ASSERTION(!aFrame->GetPrevInFlow(),
|
||||
"assigning special sibling to other than first-in-flow!");
|
||||
// We should be the first continuation
|
||||
NS_ASSERTION(!aFrame->GetPrevContinuation(),
|
||||
"assigning special sibling to other than first continuation!");
|
||||
|
||||
// Store the "special sibling" (if we were given one) with the
|
||||
// first frame in the flow.
|
||||
|
@ -1004,6 +1004,26 @@ public:
|
||||
* @param aFrame The nsIFrame object, which uses text fragment data.
|
||||
*/
|
||||
static nsTextFragment* GetTextFragmentForPrinting(const nsIFrame* aFrame);
|
||||
|
||||
/**
|
||||
* Return whether aFrame is an inline frame in the first part of an {ib}
|
||||
* split.
|
||||
*/
|
||||
static PRBool FrameIsInFirstPartOfIBSplit(const nsIFrame* aFrame) {
|
||||
return (aFrame->GetStateBits() & NS_FRAME_IS_SPECIAL) &&
|
||||
!aFrame->GetFirstContinuation()->
|
||||
GetProperty(nsGkAtoms::IBSplitSpecialPrevSibling);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether aFrame is an inline frame in the last part of an {ib}
|
||||
* split.
|
||||
*/
|
||||
static PRBool FrameIsInLastPartOfIBSplit(const nsIFrame* aFrame) {
|
||||
return (aFrame->GetStateBits() & NS_FRAME_IS_SPECIAL) &&
|
||||
!aFrame->GetFirstContinuation()->
|
||||
GetProperty(nsGkAtoms::IBSplitSpecialSibling);
|
||||
}
|
||||
};
|
||||
|
||||
class nsAutoDisableGetUsedXAssertions
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
@ -410,7 +411,10 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
|
||||
nsLineLayout* lineLayout = aReflowState.mLineLayout;
|
||||
PRBool ltr = (NS_STYLE_DIRECTION_LTR == aReflowState.mStyleVisibility->mDirection);
|
||||
nscoord leftEdge = 0;
|
||||
if (nsnull == GetPrevContinuation()) {
|
||||
// Don't offset by our start borderpadding if we have a prev continuation or
|
||||
// if we're in the last part of an {ib} split.
|
||||
if (!GetPrevContinuation() &&
|
||||
!nsLayoutUtils::FrameIsInLastPartOfIBSplit(this)) {
|
||||
leftEdge = ltr ? aReflowState.mComputedBorderPadding.left
|
||||
: aReflowState.mComputedBorderPadding.right;
|
||||
}
|
||||
@ -557,12 +561,28 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
|
||||
// whitespace in an inline element don't affect the line-height.
|
||||
aMetrics.width = lineLayout->EndSpan(this);
|
||||
|
||||
// Compute final width
|
||||
if (nsnull == GetPrevContinuation()) {
|
||||
// Compute final width.
|
||||
|
||||
// Make sure to not include our start border and padding if we have a prev
|
||||
// continuation or if we're in the last part of an {ib} split.
|
||||
if (!GetPrevContinuation() &&
|
||||
!nsLayoutUtils::FrameIsInLastPartOfIBSplit(this)) {
|
||||
aMetrics.width += ltr ? aReflowState.mComputedBorderPadding.left
|
||||
: aReflowState.mComputedBorderPadding.right;
|
||||
}
|
||||
if (NS_FRAME_IS_COMPLETE(aStatus) && (!GetNextContinuation() || GetNextInFlow())) {
|
||||
|
||||
/*
|
||||
* We want to only apply the end border and padding if we're the last
|
||||
* continuation and not in the first part of an {ib} split. To be the last
|
||||
* continuation we have to be complete (so that we won't get a next-in-flow)
|
||||
* and have no non-fluid continuations.
|
||||
*
|
||||
* FIXME the check for non-fluid continuations is not quite correct in the
|
||||
* code (though the comment above describes it correctly); see bug 492469.
|
||||
*/
|
||||
if (NS_FRAME_IS_COMPLETE(aStatus) &&
|
||||
(!GetNextContinuation() || GetNextInFlow()) &&
|
||||
!nsLayoutUtils::FrameIsInFirstPartOfIBSplit(this)) {
|
||||
aMetrics.width += ltr ? aReflowState.mComputedBorderPadding.right
|
||||
: aReflowState.mComputedBorderPadding.left;
|
||||
}
|
||||
@ -791,6 +811,28 @@ nsInlineFrame::GetSkipSides() const
|
||||
// edge border render.
|
||||
}
|
||||
}
|
||||
|
||||
if (GetStateBits() & NS_FRAME_IS_SPECIAL) {
|
||||
// The first part of an {ib} split should always skip the "end" side (as
|
||||
// determined by this frame's direction) and the last part of such a split
|
||||
// should alwas skip the "start" side. But figuring out which part of the
|
||||
// split we are involves getting our first continuation, which might be
|
||||
// expensive. So don't bother if we already have the relevant bits set.
|
||||
PRBool ltr = (NS_STYLE_DIRECTION_LTR == GetStyleVisibility()->mDirection);
|
||||
PRIntn startBit = (1 << (ltr ? NS_SIDE_LEFT : NS_SIDE_RIGHT));
|
||||
PRIntn endBit = (1 << (ltr ? NS_SIDE_RIGHT : NS_SIDE_LEFT));
|
||||
if (((startBit | endBit) & skip) != (startBit | endBit)) {
|
||||
// We're missing one of the skip bits, so check whether we need to set it.
|
||||
if (nsLayoutUtils::FrameIsInFirstPartOfIBSplit(this)) {
|
||||
skip |= endBit;
|
||||
} else {
|
||||
NS_ASSERTION(nsLayoutUtils::FrameIsInLastPartOfIBSplit(this),
|
||||
"How did that happen?");
|
||||
skip |= startBit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return skip;
|
||||
}
|
||||
|
||||
|
@ -1089,8 +1089,13 @@ nsLineLayout::ApplyStartMargin(PerFrameData* pfd,
|
||||
// XXXwaterson probably not the right way to get this; e.g., embeddings, etc.
|
||||
PRBool ltr = (NS_STYLE_DIRECTION_LTR == aReflowState.mStyleVisibility->mDirection);
|
||||
|
||||
// Only apply start-margin on the first-in flow for inline frames
|
||||
if (pfd->mFrame->GetPrevContinuation()) {
|
||||
// Only apply start-margin on the first-in flow for inline frames,
|
||||
// and make sure to not apply it to the last part of an ib split.
|
||||
// Note that the ib special sibling annotations only live on the
|
||||
// first continuation, but we don't want to apply the start margin
|
||||
// for later continuations anyway.
|
||||
if (pfd->mFrame->GetPrevContinuation() ||
|
||||
nsLayoutUtils::FrameIsInLastPartOfIBSplit(pfd->mFrame)) {
|
||||
// Zero this out so that when we compute the max-element-width of
|
||||
// the frame we will properly avoid adding in the starting margin.
|
||||
if (ltr)
|
||||
@ -1156,11 +1161,23 @@ nsLineLayout::CanPlaceFrame(PerFrameData* pfd,
|
||||
// XXXwaterson this is probably not exactly right; e.g., embeddings, etc.
|
||||
PRBool ltr = (NS_STYLE_DIRECTION_LTR == aReflowState.mStyleVisibility->mDirection);
|
||||
|
||||
if ((NS_FRAME_IS_NOT_COMPLETE(aStatus) || (pfd->mFrame->GetNextContinuation() && !pfd->mFrame->GetNextInFlow()))
|
||||
/*
|
||||
* We want to only apply the end margin if we're the last continuation and
|
||||
* not in the first part of an {ib} split. In all other cases we want to
|
||||
* zero it out. That means zeroing it out if any of these conditions hold:
|
||||
* 1) The frame is not complete (in this case it will get a next-in-flow)
|
||||
* 2) The frame is complete but has a non-fluid continuation. Note that if
|
||||
* it has a fluid continuation, that continuation will get destroyed
|
||||
* later, so we don't want to drop the end-margin in that case.
|
||||
* // FIXME: bug 492469
|
||||
* 3) The frame is in the first part of an {ib} split.
|
||||
*
|
||||
* However, none of that applies if this is a letter frame (XXXbz why?)
|
||||
*/
|
||||
if ((NS_FRAME_IS_NOT_COMPLETE(aStatus) ||
|
||||
(pfd->mFrame->GetNextContinuation() && !pfd->mFrame->GetNextInFlow()) ||
|
||||
nsLayoutUtils::FrameIsInFirstPartOfIBSplit(pfd->mFrame))
|
||||
&& !pfd->GetFlag(PFD_ISLETTERFRAME)) {
|
||||
// Only apply end margin for the last-in-flow. Zero this out so
|
||||
// that when we compute the max-element-width of the frame we
|
||||
// will properly avoid adding in the end margin.
|
||||
if (ltr)
|
||||
pfd->mMargin.right = 0;
|
||||
else
|
||||
|
10
layout/reftests/inline-borderpadding/left-ltr-ref.html
Normal file
10
layout/reftests/inline-borderpadding/left-ltr-ref.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div>
|
||||
<span style="border: 2px solid; border-right-style: none; padding-left: 5px; margin-left: 30px;">One</span>
|
||||
<br>
|
||||
<span style="border: 2px solid; border-left-style: none; padding-right: 10px; margin-right: 60px;">Two</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
10
layout/reftests/inline-borderpadding/left-rtl-ref.html
Normal file
10
layout/reftests/inline-borderpadding/left-rtl-ref.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div>
|
||||
<span style="border: 2px solid; border-left-style: none; padding-right: 10px; margin-right: 60px;">One</span>
|
||||
<br>
|
||||
<span style="border: 2px solid; border-right-style: none; padding-left: 5px; margin-left: 30px;">Two</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
13
layout/reftests/inline-borderpadding/ltr-basic.html
Normal file
13
layout/reftests/inline-borderpadding/ltr-basic.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
.r { direction: rtl; }
|
||||
.l { direction: ltr; }
|
||||
span { border: 2px solid; padding: 0 10px 0 5px; margin: 0 60px 0 30px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div><span>One<br>Two</span></div>
|
||||
</body>
|
||||
</html>
|
13
layout/reftests/inline-borderpadding/ltr-ib.html
Normal file
13
layout/reftests/inline-borderpadding/ltr-ib.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
.r { direction: rtl; }
|
||||
.l { direction: ltr; }
|
||||
span { border: 2px solid; padding: 0 10px 0 5px; margin: 0 60px 0 30px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div><span>One<div></div>Two</span></div>
|
||||
</body>
|
||||
</html>
|
13
layout/reftests/inline-borderpadding/ltr-span-only-ib.html
Normal file
13
layout/reftests/inline-borderpadding/ltr-span-only-ib.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
.r { direction: rtl; }
|
||||
.l { direction: ltr; }
|
||||
span { border: 2px solid; padding: 0 10px 0 5px; margin: 0 60px 0 30px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="r"><span class="l">One<div></div>Two</span></div>
|
||||
</body>
|
||||
</html>
|
13
layout/reftests/inline-borderpadding/ltr-span-only.html
Normal file
13
layout/reftests/inline-borderpadding/ltr-span-only.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
.r { direction: rtl; }
|
||||
.l { direction: ltr; }
|
||||
span { border: 2px solid; padding: 0 10px 0 5px; margin: 0 60px 0 30px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="r"><span class="l">One<br>Two</span></div>
|
||||
</body>
|
||||
</html>
|
8
layout/reftests/inline-borderpadding/reftest.list
Normal file
8
layout/reftests/inline-borderpadding/reftest.list
Normal file
@ -0,0 +1,8 @@
|
||||
== ltr-basic.html left-ltr-ref.html
|
||||
== rtl-basic.html right-rtl-ref.html
|
||||
== rtl-span-only.html left-rtl-ref.html
|
||||
== ltr-span-only.html right-ltr-ref.html
|
||||
== ltr-ib.html left-ltr-ref.html
|
||||
== rtl-ib.html right-rtl-ref.html
|
||||
== rtl-span-only-ib.html left-rtl-ref.html
|
||||
== ltr-span-only-ib.html right-ltr-ref.html
|
10
layout/reftests/inline-borderpadding/right-ltr-ref.html
Normal file
10
layout/reftests/inline-borderpadding/right-ltr-ref.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div style="direction: rtl">
|
||||
<span style="border: 2px solid; border-right-style: none; padding-left: 5px; margin-left: 30px;">One</span>
|
||||
<br>
|
||||
<span style="border: 2px solid; border-left-style: none; padding-right: 10px; margin-right: 60px;">Two</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
10
layout/reftests/inline-borderpadding/right-rtl-ref.html
Normal file
10
layout/reftests/inline-borderpadding/right-rtl-ref.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div style="direction: rtl">
|
||||
<span style="border: 2px solid; border-left-style: none; padding-right: 10px; margin-right: 60px;">One</span>
|
||||
<br>
|
||||
<span style="border: 2px solid; border-right-style: none; padding-left: 5px; margin-left: 30px;">Two</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
13
layout/reftests/inline-borderpadding/rtl-basic.html
Normal file
13
layout/reftests/inline-borderpadding/rtl-basic.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
.r { direction: rtl; }
|
||||
.l { direction: ltr; }
|
||||
span { border: 2px solid; padding: 0 10px 0 5px; margin: 0 60px 0 30px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="r"><span>One<br>Two</span></div>
|
||||
</body>
|
||||
</html>
|
13
layout/reftests/inline-borderpadding/rtl-ib.html
Normal file
13
layout/reftests/inline-borderpadding/rtl-ib.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
.r { direction: rtl; }
|
||||
.l { direction: ltr; }
|
||||
span { border: 2px solid; padding: 0 10px 0 5px; margin: 0 60px 0 30px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="r"><span>One<div></div>Two</span></div>
|
||||
</body>
|
||||
</html>
|
13
layout/reftests/inline-borderpadding/rtl-span-only-ib.html
Normal file
13
layout/reftests/inline-borderpadding/rtl-span-only-ib.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
.r { direction: rtl; }
|
||||
.l { direction: ltr; }
|
||||
span { border: 2px solid; padding: 0 10px 0 5px; margin: 0 60px 0 30px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div><span class="r">One<div></div>Two</span></div>
|
||||
</body>
|
||||
</html>
|
13
layout/reftests/inline-borderpadding/rtl-span-only.html
Normal file
13
layout/reftests/inline-borderpadding/rtl-span-only.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
.r { direction: rtl; }
|
||||
.l { direction: ltr; }
|
||||
span { border: 2px solid; padding: 0 10px 0 5px; margin: 0 60px 0 30px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div><span class="r">One<br>Two</span></div>
|
||||
</body>
|
||||
</html>
|
@ -83,6 +83,9 @@ include image/reftest.list
|
||||
# image-region/
|
||||
include image-region/reftest.list
|
||||
|
||||
# inline borders and padding
|
||||
include inline-borderpadding/reftest.list
|
||||
|
||||
# line-breaking/
|
||||
include line-breaking/reftest.list
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user