Bug 580869 - Cache the frame found in nsTextFrame::GetChildFrameContainingOffset; r=roc approval2.0=dbaron

--HG--
extra : rebase_source : c04666fc452be4108ed717686086a5f7baba753d
This commit is contained in:
Ehsan Akhgari 2010-07-23 17:37:55 -04:00
Родитель 75109990ca
Коммит 5105968c9e
3 изменённых файлов: 47 добавлений и 3 удалений

Просмотреть файл

@ -253,8 +253,8 @@ typedef PRUint64 nsFrameState;
// frame instead of the root frame.
#define NS_FRAME_REFLOW_ROOT NS_FRAME_STATE_BIT(19)
// Bits 20-31 of the frame state are reserved for implementations.
#define NS_FRAME_IMPL_RESERVED nsFrameState(0xFFF00000)
// Bits 20-31 and 60-63 of the frame state are reserved for implementations.
#define NS_FRAME_IMPL_RESERVED nsFrameState(0xF0000000FFF00000)
// This bit is set on floats whose parent does not contain their
// placeholder. This can happen for two reasons: (1) the float was

Просмотреть файл

@ -453,6 +453,8 @@ protected:
ContentOffsets GetCharacterOffsetAtFramePointInternal(const nsPoint &aPoint,
PRBool aForInsertionPoint);
void ClearFrameOffsetCache();
};
#endif

Просмотреть файл

@ -138,6 +138,8 @@ static void DestroyTabWidth(void* aPropertyValue)
NS_DECLARE_FRAME_PROPERTY(TabWidthProperty, DestroyTabWidth)
NS_DECLARE_FRAME_PROPERTY(OffsetToFrameProperty, nsnull)
// The following flags are set during reflow
// This bit is set on the first frame in a continuation indicating
@ -183,6 +185,9 @@ NS_DECLARE_FRAME_PROPERTY(TabWidthProperty, DestroyTabWidth)
// nsTextFrame.h has
// #define TEXT_HAS_NONCOLLAPSED_CHARACTERS NS_FRAME_STATE_BIT(31)
// Whether this frame is cached in the Offset Frame Cache (OffsetToFrameProperty)
#define TEXT_IN_OFFSET_CACHE NS_FRAME_STATE_BIT(63)
/*
* Some general notes
*
@ -3464,9 +3469,23 @@ nsTextFrame::Init(nsIContent* aContent,
return nsFrame::Init(aContent, aParent, aPrevInFlow);
}
void
nsTextFrame::ClearFrameOffsetCache()
{
// See if we need to remove ourselves from the offset cache
if (GetStateBits() & TEXT_IN_OFFSET_CACHE) {
nsIFrame* primaryFrame = mContent->GetPrimaryFrame();
NS_ASSERTION(primaryFrame, "We should have a primary frame");
primaryFrame->Properties().Delete(OffsetToFrameProperty());
RemoveStateBits(TEXT_IN_OFFSET_CACHE);
}
}
void
nsTextFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
ClearFrameOffsetCache();
// We might want to clear NS_CREATE_FRAME_IF_NON_WHITESPACE or
// NS_REFRAME_IF_WHITESPACE on mContent here, since our parent frame
// type might be changing. Not clear whether it's worth it.
@ -3596,6 +3615,8 @@ nsContinuingTextFrame::Init(nsIContent* aContent,
void
nsContinuingTextFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
ClearFrameOffsetCache();
// The text associated with this frame will become associated with our
// prev-continuation. If that means the text has changed style, then
// we need to wipe out the text run for the text.
@ -5282,9 +5303,25 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 aContentOffset,
NS_ASSERTION(aOutOffset && aOutFrame, "Bad out parameters");
NS_ASSERTION(aContentOffset >= 0, "Negative content offset, existing code was very broken!");
NS_ASSERTION(this == mContent->GetPrimaryFrame(),
"GetChildFrameContainingOffset should only be called on the primary frame");
nsTextFrame* f = this;
if (aContentOffset >= mContentOffset) {
PRInt32 offset = mContentOffset;
// Try to look up the offset to frame property
nsTextFrame* cachedFrame = static_cast<nsTextFrame*>
(Properties().Get(OffsetToFrameProperty()));
if (cachedFrame) {
f = cachedFrame;
offset = f->GetContentOffset();
f->RemoveStateBits(TEXT_IN_OFFSET_CACHE);
}
if ((aContentOffset >= offset) &&
(aHint || aContentOffset != offset)) {
while (PR_TRUE) {
nsTextFrame* next = static_cast<nsTextFrame*>(f->GetNextContinuation());
if (!next || aContentOffset < next->GetContentOffset())
@ -5314,6 +5351,11 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 aContentOffset,
*aOutOffset = aContentOffset - f->GetContentOffset();
*aOutFrame = f;
// cache the frame we found
Properties().Set(OffsetToFrameProperty(), f);
f->AddStateBits(TEXT_IN_OFFSET_CACHE);
return NS_OK;
}