mirror of
https://github.com/classilla/tenfourfox.git
synced 2025-01-01 06:33:22 +00:00
#438: M1393098
This commit is contained in:
parent
da843afa12
commit
539efce0cc
@ -397,6 +397,7 @@ nsFrame::nsFrame(nsStyleContext* aContext)
|
||||
|
||||
mState = NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY;
|
||||
mMayHaveRoundedCorners = false;
|
||||
mReflowRequestedForCharDataChange = false;
|
||||
mStyleContext = aContext;
|
||||
mStyleContext->AddRef();
|
||||
#ifdef DEBUG
|
||||
|
@ -3154,6 +3154,23 @@ protected:
|
||||
|
||||
bool mMayHaveRoundedCorners : 1;
|
||||
|
||||
/**
|
||||
* This bit is used in nsTextFrame::CharacterDataChanged() as an optimization
|
||||
* to skip redundant reflow-requests when the character data changes multiple
|
||||
* times between reflows. If this flag is set, then it implies that the
|
||||
* NS_FRAME_IS_DIRTY state bit is also set (and that intrinsic sizes have
|
||||
* been marked as dirty on our ancestor chain).
|
||||
*
|
||||
* XXXdholbert This bit is *only* used on nsTextFrame, but it lives here on
|
||||
* nsIFrame simply because this is where we've got unused state bits
|
||||
* available in a gap. If bits become more scarce, we should perhaps consider
|
||||
* expanding the range of frame-specific state bits in nsFrameStateBits.h and
|
||||
* moving this to be one of those (e.g. by swapping one of the adjacent
|
||||
* general-purpose bits to take the place of this bool:1 here, so we can grow
|
||||
* that range of frame-specific bits by 1).
|
||||
*/
|
||||
bool mReflowRequestedForCharDataChange : 1;
|
||||
|
||||
// Helpers
|
||||
/**
|
||||
* Can we stop inside this frame when we're skipping non-rendered whitespace?
|
||||
|
@ -4589,7 +4589,12 @@ nsTextFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
|
||||
}
|
||||
|
||||
int32_t endOfChangedText = aInfo->mChangeStart + aInfo->mReplaceLength;
|
||||
nsTextFrame* lastDirtiedFrame = nullptr;
|
||||
|
||||
// Parent of the last frame that we passed to FrameNeedsReflow (or noticed
|
||||
// had already received an earlier FrameNeedsReflow call).
|
||||
// (For subsequent frames with this same parent, we can just set their
|
||||
// dirty bit without bothering to call FrameNeedsReflow again.)
|
||||
nsIFrame* lastDirtiedFrameParent = nullptr;
|
||||
|
||||
nsIPresShell* shell = PresContext()->GetPresShell();
|
||||
do {
|
||||
@ -4597,17 +4602,39 @@ nsTextFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
|
||||
// if this was a pure insertion).
|
||||
textFrame->mState &= ~TEXT_WHITESPACE_FLAGS;
|
||||
textFrame->ClearTextRuns();
|
||||
if (!lastDirtiedFrame ||
|
||||
lastDirtiedFrame->GetParent() != textFrame->GetParent()) {
|
||||
// Ask the parent frame to reflow me.
|
||||
shell->FrameNeedsReflow(textFrame, nsIPresShell::eStyleChange,
|
||||
NS_FRAME_IS_DIRTY);
|
||||
lastDirtiedFrame = textFrame;
|
||||
|
||||
nsIFrame* parentOfTextFrame = textFrame->GetParent();
|
||||
bool areAncestorsAwareOfReflowRequest = false;
|
||||
if (lastDirtiedFrameParent == parentOfTextFrame) {
|
||||
// An earlier iteration of this loop already called
|
||||
// FrameNeedsReflow for a sibling of |textFrame|.
|
||||
areAncestorsAwareOfReflowRequest = true;
|
||||
} 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);
|
||||
lastDirtiedFrameParent = parentOfTextFrame;
|
||||
}
|
||||
|
||||
if (textFrame->mReflowRequestedForCharDataChange) {
|
||||
// We already requested a reflow for this frame; nothing to do.
|
||||
MOZ_ASSERT(textFrame->HasAnyStateBits(NS_FRAME_IS_DIRTY),
|
||||
"mReflowRequestedForCharDataChange should only be set "
|
||||
"on dirty frames");
|
||||
} else {
|
||||
// Make sure textFrame is queued up for a reflow. Also set a flag so we
|
||||
// don't waste time doing this again in repeated calls to this method.
|
||||
textFrame->mReflowRequestedForCharDataChange = true;
|
||||
if (!areAncestorsAwareOfReflowRequest) {
|
||||
// Ask the parent frame to reflow me.
|
||||
shell->FrameNeedsReflow(textFrame, nsIPresShell::eStyleChange,
|
||||
NS_FRAME_IS_DIRTY);
|
||||
} else {
|
||||
// We already called FrameNeedsReflow on behalf of an earlier sibling,
|
||||
// so we can just mark this frame as dirty and don't need to bother
|
||||
// telling its ancestors.
|
||||
// Note: 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);
|
||||
}
|
||||
}
|
||||
textFrame->InvalidateFrame();
|
||||
|
||||
@ -8514,8 +8541,10 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
|
||||
|
||||
// Clear out the reflow state flags in mState. We also clear the whitespace
|
||||
// flags because this can change whether the frame maps whitespace-only text
|
||||
// or not.
|
||||
// or not. We also clear the flag that tracks whether we had a pending
|
||||
// reflow request from CharacterDataChanged (since we're reflowing now).
|
||||
RemoveStateBits(TEXT_REFLOW_FLAGS | TEXT_WHITESPACE_FLAGS);
|
||||
mReflowRequestedForCharDataChange = false;
|
||||
|
||||
// Temporarily map all possible content while we construct our new textrun.
|
||||
// so that when doing reflow our styles prevail over any part of the
|
||||
|
Loading…
Reference in New Issue
Block a user