From b751c53c83f43aca022fa58ae8f1b1ffac804c54 Mon Sep 17 00:00:00 2001 From: "roc+%cs.cmu.edu" Date: Sun, 18 Jul 2004 12:02:53 +0000 Subject: [PATCH] Bug 251501. Refactor handling where frames get inserted on content insertion. r+sr=dbaron --- layout/base/nsCSSFrameConstructor.cpp | 55 +------------------ layout/base/public/nsIFrame.h | 5 ++ layout/forms/nsComboboxControlFrame.cpp | 4 ++ layout/forms/nsComboboxControlFrame.h | 2 + layout/forms/nsListControlFrame.cpp | 6 ++ layout/forms/nsListControlFrame.h | 2 + layout/generic/nsGfxScrollFrame.cpp | 12 ++-- layout/generic/nsGfxScrollFrame.h | 16 ++++++ layout/generic/nsIFrame.h | 5 ++ layout/html/base/src/nsGfxScrollFrame.cpp | 12 ++-- layout/html/base/src/nsGfxScrollFrame.h | 16 ++++++ .../html/forms/src/nsComboboxControlFrame.cpp | 4 ++ .../html/forms/src/nsComboboxControlFrame.h | 2 + layout/html/forms/src/nsListControlFrame.cpp | 6 ++ layout/html/forms/src/nsListControlFrame.h | 2 + .../html/style/src/nsCSSFrameConstructor.cpp | 55 +------------------ layout/html/table/src/nsTableCellFrame.h | 4 ++ layout/html/table/src/nsTableOuterFrame.h | 4 ++ layout/tables/nsTableCellFrame.h | 4 ++ layout/tables/nsTableOuterFrame.h | 4 ++ 20 files changed, 100 insertions(+), 120 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index b61a07df7b09..bc97854bf064 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -7364,59 +7364,10 @@ nsCSSFrameConstructor::GetFrameFor(nsIPresShell* aPresShell, nsIFrame* frame; aPresShell->GetPrimaryFrameFor(aContent, &frame); - if (nsnull != frame) { - // Check to see if the content is a select and - // then if it has a drop down (thus making it a combobox) - // The drop down is a ListControlFrame derived from a - // nsHTMLScrollFrame then get the area frame and that will be the parent - // What is unclear here, is if any of this fails, should it return - // the nsComboboxControlFrame or null? - nsCOMPtr selectElement; - nsresult res = aContent->QueryInterface(NS_GET_IID(nsIDOMHTMLSelectElement), - (void**)getter_AddRefs(selectElement)); - if (NS_SUCCEEDED(res) && selectElement) { - nsIComboboxControlFrame * comboboxFrame; - res = frame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), - (void**)&comboboxFrame); - nsIFrame * listFrame; - if (NS_SUCCEEDED(res) && comboboxFrame) { - comboboxFrame->GetDropDown(&listFrame); - } else { - listFrame = frame; - } + if (!frame) + return nsnull; - if (listFrame != nsnull) { - nsIListControlFrame * list; - res = listFrame->QueryInterface(NS_GET_IID(nsIListControlFrame), - (void**)&list); - if (NS_SUCCEEDED(res) && list) { - list->GetOptionsContainer(aPresContext, &frame); - } - } - } else { - // If the primary frame is a scroll frame, then get the scrolled frame. - // That's the frame that gets the reflow command - const nsStyleDisplay* display = frame->GetStyleDisplay(); - - // If the primary frame supports IScrollableFrame, then get the scrolled frame. - // That's the frame that gets the reflow command - nsIScrollableFrame *pScrollableFrame = nsnull; - if (NS_SUCCEEDED( frame->QueryInterface(NS_GET_IID(nsIScrollableFrame), - (void **)&pScrollableFrame) )) - { - pScrollableFrame->GetScrolledFrame( aPresContext, frame ); - } - - // if we get an outer table frame use its 1st child which is a table inner frame - // if we get a table cell frame use its 1st child which is an area frame - else if ((NS_STYLE_DISPLAY_TABLE == display->mDisplay) || - (NS_STYLE_DISPLAY_TABLE_CELL == display->mDisplay)) { - frame = frame->GetFirstChild(nsnull); - } - } - } - - return frame; + return frame->GetContentInsertionFrame(); } nsIFrame* diff --git a/layout/base/public/nsIFrame.h b/layout/base/public/nsIFrame.h index bba9a79a33fa..5c66d5468163 100644 --- a/layout/base/public/nsIFrame.h +++ b/layout/base/public/nsIFrame.h @@ -549,6 +549,11 @@ public: */ nsIContent* GetContent() const { return mContent; } + /** + * Get the frame that should be the parent for the frames of child elements + */ + virtual nsIFrame* GetContentInsertionFrame() { return this; } + /** * Get the offsets of the frame. most will be 0,0 * diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index 29cbb0a7bebb..340cae42854e 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -1962,6 +1962,10 @@ nsComboboxControlFrame::GetProperty(nsIAtom* aName, nsAString& aValue) return result; } +nsIFrame* +nsComboboxControlFrame::GetContentInsertionFrame() { + return mDropdownFrame->GetContentInsertionFrame(); +} NS_IMETHODIMP nsComboboxControlFrame::CreateDisplayFrame(nsIPresContext* aPresContext) diff --git a/layout/forms/nsComboboxControlFrame.h b/layout/forms/nsComboboxControlFrame.h index 6aceb016dbc1..a2f16d6e98ad 100644 --- a/layout/forms/nsComboboxControlFrame.h +++ b/layout/forms/nsComboboxControlFrame.h @@ -138,6 +138,8 @@ public: NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext, const nsPoint& aPoint, nsFramePaintLayer aWhichLayer, nsIFrame** aFrame); + virtual nsIFrame* GetContentInsertionFrame(); + // nsIFormControlFrame NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight); NS_IMETHOD GetName(nsAString* aName); diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp index da83f5cc192a..40491c72ee63 100644 --- a/layout/forms/nsListControlFrame.cpp +++ b/layout/forms/nsListControlFrame.cpp @@ -1441,6 +1441,12 @@ nsListControlFrame::IsOptionElement(nsIContent* aContent) return result; } +nsIFrame* +nsListControlFrame::GetContentInsertionFrame() { + nsIFrame* frame; + GetOptionsContainer(GetPresContext(), &frame); + return frame->GetContentInsertionFrame(); +} //--------------------------------------------------------- // Starts at the passed in content object and walks up the diff --git a/layout/forms/nsListControlFrame.h b/layout/forms/nsListControlFrame.h index fb0fd9237c7a..d370f521bd36 100644 --- a/layout/forms/nsListControlFrame.h +++ b/layout/forms/nsListControlFrame.h @@ -119,6 +119,8 @@ public: nsFramePaintLayer aWhichLayer, PRUint32 aFlags = 0); + virtual nsIFrame* GetContentInsertionFrame(); + /** * Get the "type" of the frame * diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 952612f85846..c4e2f49fda3f 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -102,10 +102,8 @@ nsHTMLScrollFrame::nsHTMLScrollFrame(nsIPresShell* aShell, PRBool aIsRoot) NS_IMETHODIMP nsHTMLScrollFrame::GetScrolledFrame(nsIPresContext* aPresContext, nsIFrame *&aScrolledFrame) const { - nsIBox* child = nsnull; - mInner.mScrollAreaBox->GetChildBox(&child); - child->GetFrame(&aScrolledFrame); - return NS_OK; + aScrolledFrame = mInner.GetScrolledFrame(); + return NS_OK; } NS_IMETHODIMP @@ -644,10 +642,8 @@ nsXULScrollFrame::nsXULScrollFrame(nsIPresShell* aShell, PRBool aIsRoot) NS_IMETHODIMP nsXULScrollFrame::GetScrolledFrame(nsIPresContext* aPresContext, nsIFrame *&aScrolledFrame) const { - nsIBox* child = nsnull; - mInner.mScrollAreaBox->GetChildBox(&child); - child->GetFrame(&aScrolledFrame); - return NS_OK; + aScrolledFrame = mInner.GetScrolledFrame(); + return NS_OK; } NS_IMETHODIMP diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index b7225b4c60e5..fe94df56851f 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -112,6 +112,14 @@ public: nsIScrollableView* GetScrollableView() const; + nsIFrame* GetScrolledFrame() const { + nsIBox* childBox; + nsIFrame* frame; + mScrollAreaBox->GetChildBox(&childBox); + childBox->GetFrame(&frame); + return frame; + } + void ScrollbarChanged(nsIPresContext* aPresContext, nscoord aX, nscoord aY, PRUint32 aFlags); void SetScrollbarVisibility(nsIBox* aScrollbar, PRBool aVisible); @@ -207,6 +215,10 @@ public: PRInt32& aContentOffsetEnd, PRBool& aBeginFrameContent); + virtual nsIFrame* GetContentInsertionFrame() { + return mInner.GetScrolledFrame()->GetContentInsertionFrame(); + } + // nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aAnonymousItems); @@ -330,6 +342,10 @@ public: PRInt32& aContentOffsetEnd, PRBool& aBeginFrameContent); + virtual nsIFrame* GetContentInsertionFrame() { + return mInner.GetScrolledFrame()->GetContentInsertionFrame(); + } + // nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aAnonymousItems); diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index bba9a79a33fa..5c66d5468163 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -549,6 +549,11 @@ public: */ nsIContent* GetContent() const { return mContent; } + /** + * Get the frame that should be the parent for the frames of child elements + */ + virtual nsIFrame* GetContentInsertionFrame() { return this; } + /** * Get the offsets of the frame. most will be 0,0 * diff --git a/layout/html/base/src/nsGfxScrollFrame.cpp b/layout/html/base/src/nsGfxScrollFrame.cpp index 952612f85846..c4e2f49fda3f 100644 --- a/layout/html/base/src/nsGfxScrollFrame.cpp +++ b/layout/html/base/src/nsGfxScrollFrame.cpp @@ -102,10 +102,8 @@ nsHTMLScrollFrame::nsHTMLScrollFrame(nsIPresShell* aShell, PRBool aIsRoot) NS_IMETHODIMP nsHTMLScrollFrame::GetScrolledFrame(nsIPresContext* aPresContext, nsIFrame *&aScrolledFrame) const { - nsIBox* child = nsnull; - mInner.mScrollAreaBox->GetChildBox(&child); - child->GetFrame(&aScrolledFrame); - return NS_OK; + aScrolledFrame = mInner.GetScrolledFrame(); + return NS_OK; } NS_IMETHODIMP @@ -644,10 +642,8 @@ nsXULScrollFrame::nsXULScrollFrame(nsIPresShell* aShell, PRBool aIsRoot) NS_IMETHODIMP nsXULScrollFrame::GetScrolledFrame(nsIPresContext* aPresContext, nsIFrame *&aScrolledFrame) const { - nsIBox* child = nsnull; - mInner.mScrollAreaBox->GetChildBox(&child); - child->GetFrame(&aScrolledFrame); - return NS_OK; + aScrolledFrame = mInner.GetScrolledFrame(); + return NS_OK; } NS_IMETHODIMP diff --git a/layout/html/base/src/nsGfxScrollFrame.h b/layout/html/base/src/nsGfxScrollFrame.h index b7225b4c60e5..fe94df56851f 100644 --- a/layout/html/base/src/nsGfxScrollFrame.h +++ b/layout/html/base/src/nsGfxScrollFrame.h @@ -112,6 +112,14 @@ public: nsIScrollableView* GetScrollableView() const; + nsIFrame* GetScrolledFrame() const { + nsIBox* childBox; + nsIFrame* frame; + mScrollAreaBox->GetChildBox(&childBox); + childBox->GetFrame(&frame); + return frame; + } + void ScrollbarChanged(nsIPresContext* aPresContext, nscoord aX, nscoord aY, PRUint32 aFlags); void SetScrollbarVisibility(nsIBox* aScrollbar, PRBool aVisible); @@ -207,6 +215,10 @@ public: PRInt32& aContentOffsetEnd, PRBool& aBeginFrameContent); + virtual nsIFrame* GetContentInsertionFrame() { + return mInner.GetScrolledFrame()->GetContentInsertionFrame(); + } + // nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aAnonymousItems); @@ -330,6 +342,10 @@ public: PRInt32& aContentOffsetEnd, PRBool& aBeginFrameContent); + virtual nsIFrame* GetContentInsertionFrame() { + return mInner.GetScrolledFrame()->GetContentInsertionFrame(); + } + // nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aAnonymousItems); diff --git a/layout/html/forms/src/nsComboboxControlFrame.cpp b/layout/html/forms/src/nsComboboxControlFrame.cpp index 29cbb0a7bebb..340cae42854e 100644 --- a/layout/html/forms/src/nsComboboxControlFrame.cpp +++ b/layout/html/forms/src/nsComboboxControlFrame.cpp @@ -1962,6 +1962,10 @@ nsComboboxControlFrame::GetProperty(nsIAtom* aName, nsAString& aValue) return result; } +nsIFrame* +nsComboboxControlFrame::GetContentInsertionFrame() { + return mDropdownFrame->GetContentInsertionFrame(); +} NS_IMETHODIMP nsComboboxControlFrame::CreateDisplayFrame(nsIPresContext* aPresContext) diff --git a/layout/html/forms/src/nsComboboxControlFrame.h b/layout/html/forms/src/nsComboboxControlFrame.h index 6aceb016dbc1..a2f16d6e98ad 100644 --- a/layout/html/forms/src/nsComboboxControlFrame.h +++ b/layout/html/forms/src/nsComboboxControlFrame.h @@ -138,6 +138,8 @@ public: NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext, const nsPoint& aPoint, nsFramePaintLayer aWhichLayer, nsIFrame** aFrame); + virtual nsIFrame* GetContentInsertionFrame(); + // nsIFormControlFrame NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight); NS_IMETHOD GetName(nsAString* aName); diff --git a/layout/html/forms/src/nsListControlFrame.cpp b/layout/html/forms/src/nsListControlFrame.cpp index da83f5cc192a..40491c72ee63 100644 --- a/layout/html/forms/src/nsListControlFrame.cpp +++ b/layout/html/forms/src/nsListControlFrame.cpp @@ -1441,6 +1441,12 @@ nsListControlFrame::IsOptionElement(nsIContent* aContent) return result; } +nsIFrame* +nsListControlFrame::GetContentInsertionFrame() { + nsIFrame* frame; + GetOptionsContainer(GetPresContext(), &frame); + return frame->GetContentInsertionFrame(); +} //--------------------------------------------------------- // Starts at the passed in content object and walks up the diff --git a/layout/html/forms/src/nsListControlFrame.h b/layout/html/forms/src/nsListControlFrame.h index fb0fd9237c7a..d370f521bd36 100644 --- a/layout/html/forms/src/nsListControlFrame.h +++ b/layout/html/forms/src/nsListControlFrame.h @@ -119,6 +119,8 @@ public: nsFramePaintLayer aWhichLayer, PRUint32 aFlags = 0); + virtual nsIFrame* GetContentInsertionFrame(); + /** * Get the "type" of the frame * diff --git a/layout/html/style/src/nsCSSFrameConstructor.cpp b/layout/html/style/src/nsCSSFrameConstructor.cpp index b61a07df7b09..bc97854bf064 100644 --- a/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -7364,59 +7364,10 @@ nsCSSFrameConstructor::GetFrameFor(nsIPresShell* aPresShell, nsIFrame* frame; aPresShell->GetPrimaryFrameFor(aContent, &frame); - if (nsnull != frame) { - // Check to see if the content is a select and - // then if it has a drop down (thus making it a combobox) - // The drop down is a ListControlFrame derived from a - // nsHTMLScrollFrame then get the area frame and that will be the parent - // What is unclear here, is if any of this fails, should it return - // the nsComboboxControlFrame or null? - nsCOMPtr selectElement; - nsresult res = aContent->QueryInterface(NS_GET_IID(nsIDOMHTMLSelectElement), - (void**)getter_AddRefs(selectElement)); - if (NS_SUCCEEDED(res) && selectElement) { - nsIComboboxControlFrame * comboboxFrame; - res = frame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), - (void**)&comboboxFrame); - nsIFrame * listFrame; - if (NS_SUCCEEDED(res) && comboboxFrame) { - comboboxFrame->GetDropDown(&listFrame); - } else { - listFrame = frame; - } + if (!frame) + return nsnull; - if (listFrame != nsnull) { - nsIListControlFrame * list; - res = listFrame->QueryInterface(NS_GET_IID(nsIListControlFrame), - (void**)&list); - if (NS_SUCCEEDED(res) && list) { - list->GetOptionsContainer(aPresContext, &frame); - } - } - } else { - // If the primary frame is a scroll frame, then get the scrolled frame. - // That's the frame that gets the reflow command - const nsStyleDisplay* display = frame->GetStyleDisplay(); - - // If the primary frame supports IScrollableFrame, then get the scrolled frame. - // That's the frame that gets the reflow command - nsIScrollableFrame *pScrollableFrame = nsnull; - if (NS_SUCCEEDED( frame->QueryInterface(NS_GET_IID(nsIScrollableFrame), - (void **)&pScrollableFrame) )) - { - pScrollableFrame->GetScrolledFrame( aPresContext, frame ); - } - - // if we get an outer table frame use its 1st child which is a table inner frame - // if we get a table cell frame use its 1st child which is an area frame - else if ((NS_STYLE_DISPLAY_TABLE == display->mDisplay) || - (NS_STYLE_DISPLAY_TABLE_CELL == display->mDisplay)) { - frame = frame->GetFirstChild(nsnull); - } - } - } - - return frame; + return frame->GetContentInsertionFrame(); } nsIFrame* diff --git a/layout/html/table/src/nsTableCellFrame.h b/layout/html/table/src/nsTableCellFrame.h index 53e15b5eeee0..50f3cf1dae8e 100644 --- a/layout/html/table/src/nsTableCellFrame.h +++ b/layout/html/table/src/nsTableCellFrame.h @@ -116,6 +116,10 @@ public: nsIAtom* aListName, nsIFrame* aOldFrame); + virtual nsIFrame* GetContentInsertionFrame() { + return GetFirstChild(nsnull)->GetContentInsertionFrame(); + } + virtual void NotifyPercentHeight(const nsHTMLReflowState& aReflowState); virtual PRBool NeedsToObserve(const nsHTMLReflowState& aReflowState); diff --git a/layout/html/table/src/nsTableOuterFrame.h b/layout/html/table/src/nsTableOuterFrame.h index 95556d9bc10e..0b2ca81c911f 100644 --- a/layout/html/table/src/nsTableOuterFrame.h +++ b/layout/html/table/src/nsTableOuterFrame.h @@ -122,6 +122,10 @@ public: nsIAtom* aListName, nsIFrame* aOldFrame); + virtual nsIFrame* GetContentInsertionFrame() { + return GetFirstChild(nsnull)->GetContentInsertionFrame(); + } + #ifdef ACCESSIBILITY NS_IMETHOD GetAccessible(nsIAccessible** aAccessible); #endif diff --git a/layout/tables/nsTableCellFrame.h b/layout/tables/nsTableCellFrame.h index 53e15b5eeee0..50f3cf1dae8e 100644 --- a/layout/tables/nsTableCellFrame.h +++ b/layout/tables/nsTableCellFrame.h @@ -116,6 +116,10 @@ public: nsIAtom* aListName, nsIFrame* aOldFrame); + virtual nsIFrame* GetContentInsertionFrame() { + return GetFirstChild(nsnull)->GetContentInsertionFrame(); + } + virtual void NotifyPercentHeight(const nsHTMLReflowState& aReflowState); virtual PRBool NeedsToObserve(const nsHTMLReflowState& aReflowState); diff --git a/layout/tables/nsTableOuterFrame.h b/layout/tables/nsTableOuterFrame.h index 95556d9bc10e..0b2ca81c911f 100644 --- a/layout/tables/nsTableOuterFrame.h +++ b/layout/tables/nsTableOuterFrame.h @@ -122,6 +122,10 @@ public: nsIAtom* aListName, nsIFrame* aOldFrame); + virtual nsIFrame* GetContentInsertionFrame() { + return GetFirstChild(nsnull)->GetContentInsertionFrame(); + } + #ifdef ACCESSIBILITY NS_IMETHOD GetAccessible(nsIAccessible** aAccessible); #endif