mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 580869 - Cache the frame found in nsTextFrame::GetChildFrameContainingOffset; r=roc approval2.0=dbaron
--HG-- extra : rebase_source : 3bdd49e0e039c212b5faa8d12bcbdd785da267a4
This commit is contained in:
parent
ce0b3f1a9f
commit
c07d2babfd
@ -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,28 @@ 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();
|
||||
if (primaryFrame) {
|
||||
// The primary frame might be null here. For example, nsLineBox::DeleteLineList
|
||||
// just destroys the frames in order, which means that the primary frame is already
|
||||
// dead if we're a continuing text frame, in which case, all of its properties are
|
||||
// gone, and we don't need to worry about deleting this property here.
|
||||
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 +3620,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 +5308,29 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 aContentOffset,
|
||||
|
||||
NS_ASSERTION(aOutOffset && aOutFrame, "Bad out parameters");
|
||||
NS_ASSERTION(aContentOffset >= 0, "Negative content offset, existing code was very broken!");
|
||||
nsIFrame* primaryFrame = mContent->GetPrimaryFrame();
|
||||
if (this != primaryFrame) {
|
||||
// This call needs to happen on the primary frame
|
||||
return primaryFrame->GetChildFrameContainingOffset(aContentOffset, aHint,
|
||||
aOutOffset, aOutFrame);
|
||||
}
|
||||
|
||||
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 +5360,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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user