mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 523468. Make sure we reflow the next line when content is pushed or pulled from an inline frame. r=dbaron
This commit is contained in:
parent
45ab6b1eff
commit
40e5fe01a0
@ -3683,6 +3683,28 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
||||
printf("Line reflow status = %s\n", LineReflowStatusNames[lineReflowStatus]);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (aLineLayout.GetDirtyNextLine()) {
|
||||
// aLine may have been pushed to the overflow lines.
|
||||
nsLineList* overflowLines = GetOverflowLines();
|
||||
// We can't just compare iterators front() to aLine here, since they may be in
|
||||
// different lists.
|
||||
PRBool pushedToOverflowLines = overflowLines &&
|
||||
overflowLines->front() == aLine.get();
|
||||
if (pushedToOverflowLines) {
|
||||
// aLine is stale, it's associated with the main line list but it should
|
||||
// be associated with the overflow line list now
|
||||
aLine = overflowLines->begin();
|
||||
}
|
||||
nsBlockInFlowLineIterator iter(this, aLine, pushedToOverflowLines);
|
||||
if (iter.Next() && iter.GetLine()->IsInline()) {
|
||||
iter.GetLine()->MarkDirty();
|
||||
if (iter.GetContainer() != this) {
|
||||
aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*aLineReflowStatus = lineReflowStatus;
|
||||
|
||||
return rv;
|
||||
@ -3723,16 +3745,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (frameReflowStatus & NS_FRAME_REFLOW_NEXTINFLOW) {
|
||||
// we need to ensure that the frame's nextinflow gets reflowed.
|
||||
aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
|
||||
nsBlockFrame* ourNext = static_cast<nsBlockFrame*>(GetNextInFlow());
|
||||
if (ourNext && aFrame->GetNextInFlow()) {
|
||||
PRBool isValid;
|
||||
nsBlockInFlowLineIterator iter(ourNext, aFrame->GetNextInFlow(), &isValid);
|
||||
if (isValid) {
|
||||
iter.GetLine()->MarkDirty();
|
||||
}
|
||||
}
|
||||
aLineLayout.SetDirtyNextLine();
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -3819,12 +3832,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
|
||||
|
||||
if (NS_INLINE_IS_BREAK_AFTER(frameReflowStatus) &&
|
||||
!aLineLayout.GetLineEndsInBR()) {
|
||||
// Mark next line dirty in case SplitLine didn't end up
|
||||
// pushing any frames.
|
||||
nsLineList_iterator next = aLine.next();
|
||||
if (next != end_lines() && !next->IsBlock()) {
|
||||
next->MarkDirty();
|
||||
}
|
||||
aLineLayout.SetDirtyNextLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -400,6 +400,7 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext,
|
||||
InlineReflowState irs;
|
||||
irs.mPrevFrame = nsnull;
|
||||
irs.mLineContainer = lineContainer;
|
||||
irs.mLineLayout = aReflowState.mLineLayout;
|
||||
irs.mNextInFlow = (nsInlineFrame*) GetNextInFlow();
|
||||
irs.mSetParentPointer = lazilySetParentPointer;
|
||||
|
||||
@ -693,7 +694,7 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext,
|
||||
aStatus = NS_FRAME_NOT_COMPLETE |
|
||||
NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER |
|
||||
(aStatus & NS_INLINE_BREAK_TYPE_MASK);
|
||||
PushFrames(aPresContext, aFrame, irs.mPrevFrame);
|
||||
PushFrames(aPresContext, aFrame, irs.mPrevFrame, irs);
|
||||
}
|
||||
else {
|
||||
// Preserve reflow status when breaking-before our first child
|
||||
@ -725,7 +726,7 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext,
|
||||
nsIFrame* nextFrame = aFrame->GetNextSibling();
|
||||
if (nextFrame) {
|
||||
NS_FRAME_SET_INCOMPLETE(aStatus);
|
||||
PushFrames(aPresContext, nextFrame, aFrame);
|
||||
PushFrames(aPresContext, nextFrame, aFrame, irs);
|
||||
}
|
||||
else if (nsnull != GetNextInFlow()) {
|
||||
// We must return an incomplete status if there are more child
|
||||
@ -759,7 +760,7 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext,
|
||||
if (!reflowingFirstLetter) {
|
||||
nsIFrame* nextFrame = aFrame->GetNextSibling();
|
||||
if (nextFrame) {
|
||||
PushFrames(aPresContext, nextFrame, aFrame);
|
||||
PushFrames(aPresContext, nextFrame, aFrame, irs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -791,6 +792,9 @@ nsInlineFrame::PullOneFrame(nsPresContext* aPresContext,
|
||||
nextInFlow->mFrames.RemoveFirstChild();
|
||||
mFrames.InsertFrame(this, irs.mPrevFrame, frame);
|
||||
isComplete = PR_FALSE;
|
||||
if (irs.mLineLayout) {
|
||||
irs.mLineLayout->SetDirtyNextLine();
|
||||
}
|
||||
nsHTMLContainerFrame::ReparentFrameView(aPresContext, frame, nextInFlow, this);
|
||||
break;
|
||||
}
|
||||
@ -805,7 +809,8 @@ nsInlineFrame::PullOneFrame(nsPresContext* aPresContext,
|
||||
void
|
||||
nsInlineFrame::PushFrames(nsPresContext* aPresContext,
|
||||
nsIFrame* aFromChild,
|
||||
nsIFrame* aPrevSibling)
|
||||
nsIFrame* aPrevSibling,
|
||||
InlineReflowState& aState)
|
||||
{
|
||||
NS_PRECONDITION(aFromChild, "null pointer");
|
||||
NS_PRECONDITION(aPrevSibling, "pushing first child");
|
||||
@ -819,6 +824,9 @@ nsInlineFrame::PushFrames(nsPresContext* aPresContext,
|
||||
// Add the frames to our overflow list (let our next in flow drain
|
||||
// our overflow list when it is ready)
|
||||
SetOverflowFrames(aPresContext, mFrames.RemoveFramesAfter(aPrevSibling));
|
||||
if (aState.mLineLayout) {
|
||||
aState.mLineLayout->SetDirtyNextLine();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -154,6 +154,7 @@ protected:
|
||||
nsIFrame* mPrevFrame;
|
||||
nsInlineFrame* mNextInFlow;
|
||||
nsIFrame* mLineContainer;
|
||||
nsLineLayout* mLineLayout;
|
||||
PRPackedBool mSetParentPointer; // when reflowing child frame first set its
|
||||
// parent frame pointer
|
||||
|
||||
@ -161,6 +162,7 @@ protected:
|
||||
mPrevFrame = nsnull;
|
||||
mNextInFlow = nsnull;
|
||||
mLineContainer = nsnull;
|
||||
mLineLayout = nsnull;
|
||||
mSetParentPointer = PR_FALSE;
|
||||
}
|
||||
};
|
||||
@ -196,7 +198,8 @@ protected:
|
||||
|
||||
virtual void PushFrames(nsPresContext* aPresContext,
|
||||
nsIFrame* aFromChild,
|
||||
nsIFrame* aPrevSibling);
|
||||
nsIFrame* aPrevSibling,
|
||||
InlineReflowState& aState);
|
||||
|
||||
};
|
||||
|
||||
|
@ -156,7 +156,8 @@ protected:
|
||||
#define LL_GOTLINEBOX 0x00001000
|
||||
#define LL_INFIRSTLETTER 0x00002000
|
||||
#define LL_HASBULLET 0x00004000
|
||||
#define LL_LASTFLAG LL_HASBULLET
|
||||
#define LL_DIRTYNEXTLINE 0x00008000
|
||||
#define LL_LASTFLAG LL_DIRTYNEXTLINE
|
||||
|
||||
void SetFlag(PRUint32 aFlag, PRBool aValue)
|
||||
{
|
||||
@ -246,6 +247,15 @@ public:
|
||||
SetFlag(LL_INFIRSTLINE, aSetting);
|
||||
}
|
||||
|
||||
// Calling this during block reflow ensures that the next line of inlines
|
||||
// will be marked dirty, if there is one.
|
||||
void SetDirtyNextLine() {
|
||||
SetFlag(LL_DIRTYNEXTLINE, PR_TRUE);
|
||||
}
|
||||
PRBool GetDirtyNextLine() {
|
||||
return GetFlag(LL_DIRTYNEXTLINE);
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
nsPresContext* mPresContext;
|
||||
|
@ -5987,14 +5987,7 @@ nsTextFrame::SetLength(PRInt32 aLength, nsLineLayout* aLineLayout)
|
||||
// and ChildIsDirty to handle a range of frames would be worse.
|
||||
if (aLineLayout &&
|
||||
(end != f->mContentOffset || (f->GetStateBits() & NS_FRAME_IS_DIRTY))) {
|
||||
const nsLineList::iterator* line = aLineLayout->GetLine();
|
||||
nsBlockFrame* block = do_QueryFrame(aLineLayout->GetLineContainerFrame());
|
||||
if (line && block) {
|
||||
nsLineList::iterator next = line->next();
|
||||
if (next != block->end_lines() && !next->IsBlock()) {
|
||||
next->MarkDirty();
|
||||
}
|
||||
}
|
||||
aLineLayout->SetDirtyNextLine();
|
||||
}
|
||||
|
||||
if (end < f->mContentOffset) {
|
||||
|
8
layout/reftests/bugs/523468-1-ref.html
Normal file
8
layout/reftests/bugs/523468-1-ref.html
Normal file
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
c<br>
|
||||
da<br>
|
||||
b
|
||||
</body>
|
||||
</html>
|
10
layout/reftests/bugs/523468-1.html
Normal file
10
layout/reftests/bugs/523468-1.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html style="width:1px">
|
||||
<body><span><span id="y"></span>a b</span>
|
||||
<script>
|
||||
var y = document.getElementById("y");
|
||||
document.documentElement.offsetHeight;
|
||||
y.appendChild(document.createTextNode("c d"));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1325,11 +1325,12 @@ fails-if(MOZ_WIDGET_TOOLKIT!="cocoa") == 488692-1.html 488692-1-ref.html # needs
|
||||
== 513318-1.xul 513318-1-ref.xul
|
||||
!= 513318-2.xul 513318-2-ref.xul
|
||||
!= 513318-3.xul 513318-3-ref.xul
|
||||
== 520421-1.html 520421-1-ref.html
|
||||
== 520563-1.xhtml 520563-1-ref.xhtml
|
||||
== 521525-1.html 521525-1-ref.html
|
||||
== 521525-2.html 521525-2-ref.html
|
||||
== 521539-1.html 521539-1-ref.html
|
||||
== 520421-1.html 520421-1-ref.html
|
||||
== 521685-1.html 521685-1-ref.html
|
||||
== 524175-1.html 524175-1-ref.html
|
||||
== 523096-1.html 523096-1-ref.html
|
||||
== 523468-1.html 523468-1-ref.html
|
||||
== 524175-1.html 524175-1-ref.html
|
||||
|
Loading…
Reference in New Issue
Block a user