Backout bug 504524 due to test failure

This commit is contained in:
Robert O'Callahan 2009-08-05 17:33:51 +12:00
commit 9033246e16
10 changed files with 66 additions and 239 deletions

View File

@ -3816,6 +3816,16 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
// Split line, but after the frame just reflowed
rv = SplitLine(aState, aLineLayout, aLine, aFrame->GetNextSibling(), aLineReflowStatus);
NS_ENSURE_SUCCESS(rv, rv);
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();
}
}
}
}
}
@ -3850,6 +3860,13 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
*aLineReflowStatus = LINE_REFLOW_STOP;
rv = SplitLine(aState, aLineLayout, aLine, aFrame->GetNextSibling(), aLineReflowStatus);
NS_ENSURE_SUCCESS(rv, rv);
// 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();
}
}
}

View File

@ -177,7 +177,7 @@ public:
NS_IMETHOD CheckVisibility(nsPresContext* aContext, PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aRecurse, PRBool *aFinished, PRBool *_retval);
// Update offsets to account for new length. This may clear mTextRun.
void SetLength(PRInt32 aLength, nsLineLayout* aLineLayout);
void SetLength(PRInt32 aLength);
NS_IMETHOD GetOffsets(PRInt32 &start, PRInt32 &end)const;

View File

@ -221,8 +221,8 @@ struct TextRunMappedFlow {
/**
* This is our user data for the textrun, when textRun->GetFlags() does not
* have TEXT_IS_SIMPLE_FLOW set. When TEXT_IS_SIMPLE_FLOW is set, there is
* just one flow, the textrun's user data pointer is a pointer to mStartFrame
* have TEXT_SIMPLE_FLOW set. When TEXT_SIMPLE_FLOW is set, there is just one
* flow, the textrun's user data pointer is a pointer to mStartFrame
* for that flow, mDOMOffsetToBeforeTransformOffset is zero, and mContentLength
* is the length of the text node.
*/
@ -3779,73 +3779,53 @@ nsTextFrame::ClearTextRun()
}
}
static void
ClearTextRunsInFlowChain(nsTextFrame* aFrame)
{
nsTextFrame* f;
for (f = aFrame; f; f = static_cast<nsTextFrame*>(f->GetNextInFlow())) {
f->ClearTextRun();
}
}
NS_IMETHODIMP
nsTextFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
{
// Find the first frame whose text has changed. Frames that are entirely
// before the text change are completely unaffected.
nsTextFrame* next;
nsTextFrame* textFrame = this;
while (PR_TRUE) {
next = static_cast<nsTextFrame*>(textFrame->GetNextContinuation());
if (!next || next->GetContentOffset() > PRInt32(aInfo->mChangeStart))
break;
textFrame = next;
}
ClearTextRunsInFlowChain(this);
PRInt32 endOfChangedText = aInfo->mChangeStart + aInfo->mReplaceLength;
nsTextFrame* lastDirtiedFrame = nsnull;
nsTextFrame* targetTextFrame;
PRInt32 nodeLength = mContent->GetText()->GetLength();
nsIPresShell* shell = PresContext()->GetPresShell();
do {
// textFrame contained deleted text (or the insertion point,
// if this was a pure insertion).
textFrame->mState &= ~TEXT_WHITESPACE_FLAGS;
textFrame->ClearTextRun();
if (!lastDirtiedFrame ||
lastDirtiedFrame->GetParent() != textFrame->GetParent()) {
// Ask the parent frame to reflow me.
shell->FrameNeedsReflow(textFrame, nsIPresShell::eStyleChange,
NS_FRAME_IS_DIRTY);
lastDirtiedFrame = textFrame;
} else {
// if the parent is a block, we're cheating here because we should
// be marking our line dirty, but we're not. nsTextFrame::SetLength
// will do that when it gets called during reflow.
textFrame->AddStateBits(NS_FRAME_IS_DIRTY);
}
// Below, frames that start after the deleted text will be adjusted so that
// their offsets move with the trailing unchanged text. If this change
// deletes more text than it inserts, those frame offsets will decrease.
// We need to maintain the invariant that mContentOffset is non-decreasing
// along the continuation chain. So we need to ensure that frames that
// started in the deleted text are all still starting before the
// unchanged text.
if (textFrame->mContentOffset > endOfChangedText) {
textFrame->mContentOffset = endOfChangedText;
}
textFrame = static_cast<nsTextFrame*>(textFrame->GetNextContinuation());
} while (textFrame && textFrame->GetContentOffset() < PRInt32(aInfo->mChangeEnd));
// This is how much the length of the string changed by --- i.e.,
// how much the trailing unchanged text moved.
PRInt32 sizeChange =
aInfo->mChangeStart + aInfo->mReplaceLength - aInfo->mChangeEnd;
if (sizeChange) {
// Fix the offsets of the text frames that start in the trailing
// unchanged text.
while (textFrame) {
textFrame->mContentOffset += sizeChange;
// XXX we could rescue some text runs by adjusting their user data
// to reflect the change in DOM offsets
textFrame->ClearTextRun();
if (aInfo->mAppend) {
targetTextFrame = static_cast<nsTextFrame*>(GetLastContinuation());
targetTextFrame->mState &= ~TEXT_WHITESPACE_FLAGS;
} else {
// Mark all the continuation frames as dirty, and fix up content offsets to
// be valid.
// Don't set NS_FRAME_IS_DIRTY on |this|, since we call FrameNeedsReflow
// below.
nsTextFrame* textFrame = this;
PRInt32 newLength = nodeLength;
do {
textFrame->mState &= ~TEXT_WHITESPACE_FLAGS;
// If the text node has shrunk, clip the frame contentlength as necessary
if (textFrame->mContentOffset > newLength) {
textFrame->mContentOffset = newLength;
}
textFrame = static_cast<nsTextFrame*>(textFrame->GetNextContinuation());
}
if (!textFrame) {
break;
}
textFrame->mState |= NS_FRAME_IS_DIRTY;
} while (1);
targetTextFrame = this;
}
// Ask the parent frame to reflow me.
PresContext()->GetPresShell()->FrameNeedsReflow(targetTextFrame,
nsIPresShell::eStyleChange,
NS_FRAME_IS_DIRTY);
return NS_OK;
}
@ -5918,33 +5898,13 @@ HasSoftHyphenBefore(const nsTextFragment* aFrag, gfxTextRun* aTextRun,
}
void
nsTextFrame::SetLength(PRInt32 aLength, nsLineLayout* aLineLayout)
nsTextFrame::SetLength(PRInt32 aLength)
{
mContentLengthHint = aLength;
PRInt32 end = GetContentOffset() + aLength;
nsTextFrame* f = static_cast<nsTextFrame*>(GetNextInFlow());
if (!f)
return;
// If our end offset is moving, then even if frames are not being pushed or
// pulled, content is moving to or from the next line and the next line
// must be reflowed.
// If the next-continuation is dirty, then we should dirty the next line now
// because we may have skipped doing it if we dirtied it in
// CharacterDataChanged. This is ugly but teaching FrameNeedsReflow
// 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();
}
}
}
if (end < f->mContentOffset) {
// Our frame is shrinking. Give the text to our next in flow.
f->mContentOffset = end;
@ -5954,12 +5914,8 @@ nsTextFrame::SetLength(PRInt32 aLength, nsLineLayout* aLineLayout)
}
return;
}
// Our frame is growing. Take text from our in-flow(s).
// We can take text from frames in lines beyond just the next line.
// We don't dirty those lines. That's OK, because when we reflow
// our empty next-in-flow, it will take text from its next-in-flow and
// dirty that line.
while (f && f->mContentOffset < end) {
// Our frame is growing. Take text from our in-flow.
f->mContentOffset = end;
if (f->GetTextRun() != mTextRun) {
ClearTextRun();
@ -5967,7 +5923,6 @@ nsTextFrame::SetLength(PRInt32 aLength, nsLineLayout* aLineLayout)
}
f = static_cast<nsTextFrame*>(f->GetNextInFlow());
}
#ifdef DEBUG
f = this;
PRInt32 iterations = 0;
@ -6091,7 +6046,7 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
// Layout dependent styles are a problem because we need to reconstruct
// the gfxTextRun based on our layout.
if (lineLayout.GetInFirstLetter() || lineLayout.GetInFirstLine()) {
SetLength(maxContentLength, &lineLayout);
SetLength(maxContentLength);
if (lineLayout.GetInFirstLetter()) {
// floating first-letter boundaries are significant in textrun
@ -6133,7 +6088,7 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
// Change this frame's length to the first-letter length right now
// so that when we rebuild the textrun it will be built with the
// right first-letter boundary
SetLength(offset + length - GetContentOffset(), &lineLayout);
SetLength(offset + length - GetContentOffset());
// Ensure that the textrun will be rebuilt
ClearTextRun();
}
@ -6430,9 +6385,10 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
charsFit - numJustifiableCharacters);
}
SetLength(contentLength, &lineLayout);
SetLength(contentLength);
if (mContent->HasFlag(NS_TEXT_IN_SELECTION)) {
// XXXroc Watch out, this could be slow!!! Speed up GetSelectionDetails?
SelectionDetails* details = GetSelectionDetails();
if (details) {
AddStateBits(NS_FRAME_SELECTED_CONTENT);
@ -6863,7 +6819,7 @@ nsTextFrame::AdjustOffsetsForBidi(PRInt32 aStart, PRInt32 aEnd)
}
mContentOffset = aStart;
SetLength(aEnd - aStart, nsnull);
SetLength(aEnd - aStart);
}
/**

View File

@ -1,14 +0,0 @@
<!DOCTYPE HTML>
<html>
<body style="white-space:pre; margin:0;">
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
</body>
</html>

View File

@ -1,27 +0,0 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<head>
<script>
function doTest() {
var text = document.body.firstChild;
// Delete a line, then make a change after it
text.deleteData(8, 7);
text.replaceData(55, 1, "8");
document.documentElement.removeAttribute('class');
}
document.addEventListener("MozReftestInvalidate", doTest, false);
</script>
</head>
<body style="white-space:pre; margin:0;">
Line 1
Line 2
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line X
Line 9
</body>
</html>

View File

@ -1,25 +0,0 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<head>
<script>
function doTest() {
var text = document.body.firstChild;
// Insert a line, then make a change after it
text.insertData(8, "Line 2\n");
text.replaceData(55, 1, "8");
document.documentElement.removeAttribute('class');
}
document.addEventListener("MozReftestInvalidate", doTest, false);
</script>
</head>
<body style="white-space:pre; margin:0;">
Line 1
Line 3
Line 4
Line 5
Line 6
Line 7
Line X
Line 9
</body>
</html>

View File

@ -1,25 +0,0 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<head>
<script>
function doTest() {
var text = document.body.firstChild;
// Just make a change
text.replaceData(55, 1, "8");
document.documentElement.removeAttribute('class');
}
document.addEventListener("MozReftestInvalidate", doTest, false);
</script>
</head>
<body style="white-space:pre; margin:0;">
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line X
Line 9
</body>
</html>

View File

@ -1,26 +0,0 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<head>
<script>
function doTest() {
var text = document.body.firstChild;
// Replace three lines with two lines (but not at line boundaries)
text.replaceData(34, 21, "5\nLine 6\nLine ");
document.documentElement.removeAttribute('class');
}
document.addEventListener("MozReftestInvalidate", doTest, false);
</script>
</head>
<body style="white-space:pre; margin:0;">
Line 1
Line 2
Line 3
Line 4
Line X
Line X
Line X
Line 7
Line 8
Line 9
</body>
</html>

View File

@ -1,24 +0,0 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<head>
<script>
function doTest() {
var text = document.body.firstChild;
// Replace two lines with three lines (but not at line boundaries)
text.replaceData(34, 7, "5\nLine 6\nLine ");
document.documentElement.removeAttribute('class');
}
document.addEventListener("MozReftestInvalidate", doTest, false);
</script>
</head>
<body style="white-space:pre; margin:0;">
Line 1
Line 2
Line 3
Line 4
Line X
Line 7
Line 8
Line 9
</body>
</html>

View File

@ -12,11 +12,6 @@ random-if(MOZ_WIDGET_TOOLKIT!="cocoa") == font-size-adjust-02.html font-size-adj
== justification-1.html justification-1-ref.html
== justification-2a.html justification-2-ref.html
== justification-2b.html justification-2-ref.html
== line-editing-1a.html line-editing-1-ref.html
== line-editing-1b.html line-editing-1-ref.html
== line-editing-1c.html line-editing-1-ref.html
== line-editing-1d.html line-editing-1-ref.html
== line-editing-1e.html line-editing-1-ref.html
== long-1.html long-ref.html
== pre-line-1.html pre-line-1-ref.html
== pre-line-2.html pre-line-2-ref.html