mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 504221 part 1. Introduce framelist slice and enumerator classes and make the framelist versions of nsFrameList::AppendFrames/InsertFrames return a slice for the new frames. r=fantasai, r+sr=roc
This commit is contained in:
parent
b47c10e3d6
commit
58ab0561e4
@ -39,7 +39,8 @@
|
||||
/* class for maintaining a linked list of child frames */
|
||||
|
||||
#include "nsFrameList.h"
|
||||
#ifdef NS_DEBUG
|
||||
#include "nsIFrame.h"
|
||||
#ifdef DEBUG
|
||||
#include "nsIFrameDebug.h"
|
||||
#endif
|
||||
#include "nsLayoutUtils.h"
|
||||
@ -417,18 +418,7 @@ nsFrameList::GetPrevSiblingFor(nsIFrame* aFrame) const
|
||||
return frame;
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameList::VerifyParent(nsIFrame* aParent) const
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
for (nsIFrame* frame = mFirstChild; frame;
|
||||
frame = frame->GetNextSibling()) {
|
||||
NS_ASSERTION(frame->GetParent() == aParent, "bad parent");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
#ifdef DEBUG
|
||||
void
|
||||
nsFrameList::List(FILE* out) const
|
||||
{
|
||||
|
@ -40,27 +40,43 @@
|
||||
#ifndef nsFrameList_h___
|
||||
#define nsFrameList_h___
|
||||
|
||||
#include "nsIFrame.h"
|
||||
#include "nscore.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include <stdio.h> /* for FILE* */
|
||||
#include "nsDebug.h"
|
||||
|
||||
class nsIFrame;
|
||||
|
||||
/**
|
||||
* A class for managing a singly linked list of frames. Frames are
|
||||
* linked together through their next-sibling pointer.
|
||||
* A class for managing a list of frames.
|
||||
*/
|
||||
|
||||
class nsFrameList {
|
||||
public:
|
||||
nsFrameList() {
|
||||
mFirstChild = nsnull;
|
||||
nsFrameList() :
|
||||
mFirstChild(nsnull)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsFrameList);
|
||||
}
|
||||
|
||||
nsFrameList(nsIFrame* aHead) {
|
||||
mFirstChild = aHead;
|
||||
// XXX We should make this explicit when we can!
|
||||
nsFrameList(nsIFrame* aHead) :
|
||||
mFirstChild(aHead)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsFrameList);
|
||||
#ifdef DEBUG
|
||||
CheckForLoops();
|
||||
#endif
|
||||
}
|
||||
|
||||
nsFrameList(const nsFrameList& aOther) :
|
||||
mFirstChild(aOther.mFirstChild)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsFrameList);
|
||||
}
|
||||
|
||||
~nsFrameList() {
|
||||
MOZ_COUNT_DTOR(nsFrameList);
|
||||
// Don't destroy our frames here, so that we can have temporary nsFrameLists
|
||||
}
|
||||
|
||||
void DestroyFrames();
|
||||
@ -75,56 +91,83 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
// Appends frames from aFrameList to this list. If aParent
|
||||
// is not null, reparents the newly-added frames.
|
||||
class Slice;
|
||||
|
||||
/**
|
||||
* Appends frames from aFrameList to this list. If aParent
|
||||
* is not null, reparents the newly-added frames.
|
||||
*/
|
||||
void AppendFrames(nsIFrame* aParent, nsIFrame* aFrameList);
|
||||
|
||||
void AppendFrames(nsIFrame* aParent, nsFrameList& aFrameList) {
|
||||
AppendFrames(aParent, aFrameList.mFirstChild);
|
||||
/**
|
||||
* Appends aFrameList to this list. If aParent is not null,
|
||||
* reparents the newly added frames. Clears out aFrameList and
|
||||
* returns a list slice represening the newly-appended frames.
|
||||
*/
|
||||
Slice AppendFrames(nsIFrame* aParent, nsFrameList& aFrameList) {
|
||||
NS_PRECONDITION(!aFrameList.IsEmpty(), "Unexpected empty list");
|
||||
nsIFrame* firstNewFrame = aFrameList.FirstChild();
|
||||
AppendFrames(aParent, firstNewFrame);
|
||||
aFrameList.mFirstChild = nsnull;
|
||||
return Slice(*this, firstNewFrame, nsnull);
|
||||
}
|
||||
|
||||
void AppendFrame(nsIFrame* aParent, nsIFrame* aFrame);
|
||||
|
||||
// Take aFrame out of the frame list. This also disconnects aFrame
|
||||
// from the sibling list. This will return PR_FALSE if aFrame is
|
||||
// nsnull or if aFrame is not in the list. The second frame is
|
||||
// a hint for the prev-sibling of aFrame; if the hint is correct,
|
||||
// then this is O(1) time. If successfully removed, the child's
|
||||
// NextSibling pointer is cleared.
|
||||
/**
|
||||
* Take aFrame out of the frame list. This also disconnects aFrame
|
||||
* from the sibling list. This will return PR_FALSE if aFrame is
|
||||
* nsnull or if aFrame is not in the list. The second frame is
|
||||
* a hint for the prev-sibling of aFrame; if the hint is correct,
|
||||
* then this is O(1) time. If successfully removed, the child's
|
||||
* NextSibling pointer is cleared.
|
||||
*/
|
||||
PRBool RemoveFrame(nsIFrame* aFrame, nsIFrame* aPrevSiblingHint = nsnull);
|
||||
|
||||
// Remove the first child from the list. The caller is assumed to be
|
||||
// holding a reference to the first child. This call is equivalent
|
||||
// in behavior to calling RemoveFrame(FirstChild()). If successfully
|
||||
// removed the first child's NextSibling pointer is cleared.
|
||||
/**
|
||||
* Remove the first child from the list. The caller is assumed to be
|
||||
* holding a reference to the first child. This call is equivalent
|
||||
* in behavior to calling RemoveFrame(FirstChild()). If successfully
|
||||
* removed the first child's NextSibling pointer is cleared.
|
||||
*/
|
||||
PRBool RemoveFirstChild();
|
||||
|
||||
// Take aFrame out of the frame list and then destroy it. This also
|
||||
// disconnects aFrame from the sibling list. This will return
|
||||
// PR_FALSE if aFrame is nsnull or if aFrame is not in the list.
|
||||
/**
|
||||
* Take aFrame out of the frame list and then destroy it. This also
|
||||
* disconnects aFrame from the sibling list. This will return
|
||||
* PR_FALSE if aFrame is nsnull or if aFrame is not in the list.
|
||||
*/
|
||||
PRBool DestroyFrame(nsIFrame* aFrame);
|
||||
|
||||
// Inserts aNewFrame right after aPrevSibling, or prepends to
|
||||
// list if aPrevSibling is null. If aParent is not null, also
|
||||
// reparents newly-added frame. Note that this method always
|
||||
// sets the frame's nextSibling pointer.
|
||||
/**
|
||||
* Inserts aNewFrame right after aPrevSibling, or prepends to
|
||||
* list if aPrevSibling is null. If aParent is not null, also
|
||||
* reparents newly-added frame. Note that this method always
|
||||
* sets the frame's nextSibling pointer.
|
||||
*/
|
||||
void InsertFrame(nsIFrame* aParent,
|
||||
nsIFrame* aPrevSibling,
|
||||
nsIFrame* aNewFrame);
|
||||
|
||||
// Inserts aFrameList right after aPrevSibling, or prepends to
|
||||
// list if aPrevSibling is null. If aParent is not null, also
|
||||
// reparents newly-added frame.
|
||||
/**
|
||||
* Inserts aFrameList right after aPrevSibling, or prepends to
|
||||
* list if aPrevSibling is null. If aParent is not null, also
|
||||
* reparents newly-added frame.
|
||||
*/
|
||||
void InsertFrames(nsIFrame* aParent,
|
||||
nsIFrame* aPrevSibling,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
void InsertFrames(nsIFrame* aParent, nsIFrame* aPrevSibling,
|
||||
nsFrameList& aFrameList) {
|
||||
InsertFrames(aParent, aPrevSibling, aFrameList.FirstChild());
|
||||
aFrameList.mFirstChild = nsnull;
|
||||
}
|
||||
/**
|
||||
* Inserts aFrameList into this list after aPrevSibling (at the beginning if
|
||||
* aPrevSibling is null). If aParent is not null, reparents the newly added
|
||||
* frames. Clears out aFrameList and returns a list slice representing the
|
||||
* newly-inserted frames.
|
||||
*
|
||||
* This is implemented in nsIFrame.h because it needs to know about nsIFrame.
|
||||
*/
|
||||
inline Slice InsertFrames(nsIFrame* aParent, nsIFrame* aPrevSibling,
|
||||
nsFrameList& aFrameList);
|
||||
|
||||
PRBool Split(nsIFrame* aAfterFrame, nsIFrame** aNextFrameResult);
|
||||
|
||||
@ -174,12 +217,90 @@ public:
|
||||
nsIFrame* GetNextVisualFor(nsIFrame* aFrame) const;
|
||||
#endif // IBMBIDI
|
||||
|
||||
void VerifyParent(nsIFrame* aParent) const;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
#ifdef DEBUG
|
||||
void List(FILE* out) const;
|
||||
#endif
|
||||
|
||||
class Enumerator;
|
||||
|
||||
/**
|
||||
* A class representing a slice of a frame list.
|
||||
*/
|
||||
class Slice {
|
||||
friend class Enumerator;
|
||||
|
||||
public:
|
||||
// Implicit on purpose, so that we can easily create enumerators from
|
||||
// nsFrameList via this impicit constructor.
|
||||
Slice(const nsFrameList& aList) :
|
||||
#ifdef DEBUG
|
||||
mList(aList),
|
||||
#endif
|
||||
mStart(aList.FirstChild()),
|
||||
mEnd(nsnull)
|
||||
{}
|
||||
|
||||
Slice(const nsFrameList& aList, nsIFrame* aStart, nsIFrame* aEnd) :
|
||||
#ifdef DEBUG
|
||||
mList(aList),
|
||||
#endif
|
||||
mStart(aStart),
|
||||
mEnd(aEnd)
|
||||
{}
|
||||
|
||||
Slice(const Slice& aOther) :
|
||||
#ifdef DEBUG
|
||||
mList(aOther.mList),
|
||||
#endif
|
||||
mStart(aOther.mStart),
|
||||
mEnd(aOther.mEnd)
|
||||
{}
|
||||
|
||||
private:
|
||||
#ifdef DEBUG
|
||||
const nsFrameList& mList;
|
||||
#endif
|
||||
nsIFrame* const mStart; // our starting frame
|
||||
const nsIFrame* const mEnd; // The first frame that is NOT in the slice.
|
||||
// May be null.
|
||||
};
|
||||
|
||||
class Enumerator {
|
||||
public:
|
||||
Enumerator(const Slice& aSlice) :
|
||||
#ifdef DEBUG
|
||||
mSlice(aSlice),
|
||||
#endif
|
||||
mFrame(aSlice.mStart),
|
||||
mEnd(aSlice.mEnd)
|
||||
{}
|
||||
|
||||
Enumerator(const Enumerator& aOther) :
|
||||
#ifdef DEBUG
|
||||
mSlice(aOther.mSlice),
|
||||
#endif
|
||||
mFrame(aOther.mFrame),
|
||||
mEnd(aOther.mEnd)
|
||||
{}
|
||||
|
||||
PRBool AtEnd() const { return mFrame == mEnd; }
|
||||
|
||||
/* Next() needs to know about nsIFrame, and nsIFrame will need to
|
||||
know about nsFrameList methods, so in order to inline this put
|
||||
the implementation in nsIFrame.h */
|
||||
inline void Next();
|
||||
|
||||
nsIFrame* get() const { return mFrame; }
|
||||
|
||||
private:
|
||||
#ifdef DEBUG
|
||||
const Slice& mSlice;
|
||||
#endif
|
||||
nsIFrame* mFrame; // our current frame.
|
||||
const nsIFrame* const mEnd; // The first frame we should NOT enumerate.
|
||||
// May be null.
|
||||
};
|
||||
|
||||
private:
|
||||
#ifdef DEBUG
|
||||
void CheckForLoops();
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "nsIContent.h"
|
||||
#include "nsHTMLReflowMetrics.h"
|
||||
#include "gfxMatrix.h"
|
||||
#include "nsFrameList.h"
|
||||
|
||||
/**
|
||||
* New rules of reflow:
|
||||
@ -2535,4 +2536,21 @@ private:
|
||||
nsIFrame* mFrame;
|
||||
};
|
||||
|
||||
inline void
|
||||
nsFrameList::Enumerator::Next() {
|
||||
NS_ASSERTION(!AtEnd(), "Should have checked AtEnd()!");
|
||||
mFrame = mFrame->GetNextSibling();
|
||||
}
|
||||
|
||||
inline nsFrameList::Slice
|
||||
nsFrameList::InsertFrames(nsIFrame* aParent, nsIFrame* aPrevSibling,
|
||||
nsFrameList& aFrameList) {
|
||||
NS_PRECONDITION(!aFrameList.IsEmpty(), "Unexpected empty list");
|
||||
nsIFrame* firstNewFrame = aFrameList.FirstChild();
|
||||
nsIFrame* nextSibling =
|
||||
aPrevSibling ? aPrevSibling->GetNextSibling() : FirstChild();
|
||||
InsertFrames(aParent, aPrevSibling, firstNewFrame);
|
||||
aFrameList.mFirstChild = nsnull;
|
||||
return Slice(*this, firstNewFrame, nextSibling);
|
||||
}
|
||||
#endif /* nsIFrame_h___ */
|
||||
|
Loading…
Reference in New Issue
Block a user