From 97e02084abb4ef9beabe943d969062c8a2e2b46b Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Sun, 26 Jul 2009 21:27:32 -0400 Subject: [PATCH] Bug 496823. Blocks can implement GetLastChild() much faster than by just getting first child and iterating its siblings. r=roc --- layout/base/nsCSSFrameConstructor.cpp | 4 ++-- layout/generic/nsBlockFrame.cpp | 14 ++++++++++++++ layout/generic/nsBlockFrame.h | 1 + layout/generic/nsFrame.cpp | 6 ++++++ layout/generic/nsIFrame.h | 10 ++++++++++ 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index edc6d59bcd5e..6afe705c6f73 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -5725,13 +5725,13 @@ AdjustAppendParentForAfterContent(nsPresContext* aPresContext, static nsIFrame* FindAppendPrevSibling(nsIFrame* aParentFrame, nsIFrame* aAfterFrame) { - nsFrameList childList(aParentFrame->GetFirstChild(nsnull)); if (aAfterFrame) { + nsFrameList childList(aParentFrame->GetFirstChild(nsnull)); NS_ASSERTION(aAfterFrame->GetParent() == aParentFrame, "Wrong parent"); return childList.GetPrevSiblingFor(aAfterFrame); } - return childList.LastChild(); + return aParentFrame->GetLastChild(nsnull); } /** diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 429367e4ba6f..eaff8870779b 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -538,6 +538,20 @@ nsBlockFrame::GetFirstChild(nsIAtom* aListName) const return nsContainerFrame::GetFirstChild(aListName);; } +nsIFrame* +nsBlockFrame::GetLastChild(nsIAtom* aListName) const +{ + if (aListName) { + return nsBlockFrameSuper::GetLastChild(aListName); + } + + if (mLines.empty()) { + return nsnull; + } + + return mLines.back()->LastChild(); +} + #define NS_BLOCK_FRAME_OVERFLOW_OOF_LIST_INDEX (NS_CONTAINER_LIST_COUNT_INCL_OC + 0) #define NS_BLOCK_FRAME_FLOAT_LIST_INDEX (NS_CONTAINER_LIST_COUNT_INCL_OC + 1) #define NS_BLOCK_FRAME_BULLET_LIST_INDEX (NS_CONTAINER_LIST_COUNT_INCL_OC + 2) diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index f81778ffd4eb..54f0b226372a 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -177,6 +177,7 @@ public: NS_IMETHOD RemoveFrame(nsIAtom* aListName, nsIFrame* aOldFrame); virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const; + virtual nsIFrame* GetLastChild(nsIAtom* aListName) const; virtual nscoord GetBaseline() const; virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const; virtual void Destroy(); diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 45ad63dc5f94..47947090599e 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -1667,6 +1667,12 @@ nsIFrame::CreateWidgetForView(nsIView* aView) return aView->CreateWidget(kWidgetCID); } +nsIFrame* +nsIFrame::GetLastChild(nsIAtom* aListName) const +{ + return nsLayoutUtils::GetLastSibling(GetFirstChild(aListName)); +} + /** * */ diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index fcbd412d8594..f42460b67508 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -856,6 +856,16 @@ public: */ virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const = 0; + /** + * Get the last child frame from the specified child list. + * + * @param aListName the name of the child list. A NULL pointer for the atom + * name means the unnamed principal child list + * @return the child frame, or NULL if there is no such child + * @see #GetAdditionalListName() + */ + virtual nsIFrame* GetLastChild(nsIAtom* aListName) const; + /** * Child frames are linked together in a singly-linked list */