From d01839633644e753f171ac671b03cd7be2cffd24 Mon Sep 17 00:00:00 2001 From: "rods%netscape.com" Date: Thu, 11 Nov 1999 22:13:33 +0000 Subject: [PATCH] Added new method "DoneAddingContent" so the select frame can be told that all the content has been added Reworked the select code to keep the state as to whether all the content and/or all the frames have been created and then whether it is initialized r=self&kmcclusk, bug 17965 git-svn-id: svn://10.0.0.236/trunk@53258 18797224-902f-48f8-a5cc-f745e15eee43 --- .../layout/forms/nsComboboxControlFrame.cpp | 23 +- mozilla/layout/forms/nsComboboxControlFrame.h | 1 + mozilla/layout/forms/nsISelectControlFrame.h | 10 +- mozilla/layout/forms/nsListControlFrame.cpp | 279 +++++++++++++++--- mozilla/layout/forms/nsListControlFrame.h | 8 + .../html/forms/public/nsISelectControlFrame.h | 10 +- .../html/forms/src/nsComboboxControlFrame.cpp | 23 +- .../html/forms/src/nsComboboxControlFrame.h | 1 + .../html/forms/src/nsListControlFrame.cpp | 279 +++++++++++++++--- .../html/forms/src/nsListControlFrame.h | 8 + 10 files changed, 558 insertions(+), 84 deletions(-) diff --git a/mozilla/layout/forms/nsComboboxControlFrame.cpp b/mozilla/layout/forms/nsComboboxControlFrame.cpp index 901ded8f3f1..0e49df28d11 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.cpp +++ b/mozilla/layout/forms/nsComboboxControlFrame.cpp @@ -210,7 +210,7 @@ nsComboboxControlFrame::MakeSureSomethingIsSelected(nsIPresContext* aPresContext rv = fcFrame->SetProperty(aPresContext, nsHTMLAtoms::selectedindex, "0"); mSelectedIndex = 0; } - UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // Needed to reflow when removing last option + // XXX UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // Needed to reflow when removing last option } // Don't NS_RELEASE fcFrame here as it isn't addRef'd in the QI (???) @@ -562,7 +562,7 @@ nsComboboxControlFrame::PositionDropdown(nsIPresContext& aPresContext, //if (currentRect != dropdownRect) { dropdownFrame->SetRect(&aPresContext, dropdownRect); -#ifdef DEBUG_rodsXXX +#ifdef DEBUG_rodsXXXXXX printf("%d Position Dropdown at: %d %d %d %d\n", counter++, dropdownRect.x, dropdownRect.y, dropdownRect.width, dropdownRect.height); #endif //} @@ -649,7 +649,7 @@ nsComboboxControlFrame::GetAbsoluteFramePosition(nsIPresContext& aPresContext, return rv; } -#ifdef DEBUG_rods +#ifdef DEBUG_rodsXXX static int myCounter = 0; #endif @@ -659,7 +659,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { -#ifdef DEBUG_rods +#ifdef DEBUG_rodsXXX printf("nsComboboxControlFrame::Reflow %d Reason: ", myCounter++); switch (aReflowState.reason) { case eReflowReason_Initial:printf("eReflowReason_Initial\n");break; @@ -822,7 +822,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext& aPresContext, PositionDropdown(aPresContext, aDesiredSize.height, absoluteTwips, absolutePixels); aStatus = NS_FRAME_COMPLETE; +#if 0 COMPARE_QUIRK_SIZE("nsComboboxControlFrame", 56, 22) +#endif return rv; } @@ -1082,6 +1084,19 @@ nsComboboxControlFrame::SelectionChanged() //---------------------------------------------------------------------- // nsISelectControlFrame //---------------------------------------------------------------------- +NS_IMETHODIMP +nsComboboxControlFrame::DoneAddingContent() +{ + nsISelectControlFrame* listFrame = nsnull; + nsIFrame* dropdownFrame = GetDropdownFrame(); + nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame), + (void**)&listFrame); + if (NS_SUCCEEDED(rv) && listFrame) { + rv = listFrame->DoneAddingContent(); + NS_RELEASE(listFrame); + } + return rv; +} NS_IMETHODIMP nsComboboxControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex) diff --git a/mozilla/layout/forms/nsComboboxControlFrame.h b/mozilla/layout/forms/nsComboboxControlFrame.h index c9a5c84117d..3d2d6cf7686 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.h +++ b/mozilla/layout/forms/nsComboboxControlFrame.h @@ -149,6 +149,7 @@ public: NS_IMETHOD RemoveOption(nsIPresContext* aPresContext, PRInt32 index); NS_IMETHOD SetOptionSelected(PRInt32 aIndex, PRBool aValue); NS_IMETHOD GetOptionSelected(PRInt32 aIndex, PRBool* aValue); + NS_IMETHOD DoneAddingContent(); //nsIDOMEventListener virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent); diff --git a/mozilla/layout/forms/nsISelectControlFrame.h b/mozilla/layout/forms/nsISelectControlFrame.h index b2d779e5131..86c77c4c900 100644 --- a/mozilla/layout/forms/nsISelectControlFrame.h +++ b/mozilla/layout/forms/nsISelectControlFrame.h @@ -54,10 +54,18 @@ public: /** * Sets the select state of the option at index */ - NS_IMETHOD SetOptionSelected(PRInt32 index, PRBool value) = 0; + /** + * Sets the select state of the option at index + */ NS_IMETHOD GetOptionSelected(PRInt32 index, PRBool* value) = 0; + + /** + * Sets the select state of the option at index + */ + NS_IMETHOD DoneAddingContent() = 0; + }; #endif diff --git a/mozilla/layout/forms/nsListControlFrame.cpp b/mozilla/layout/forms/nsListControlFrame.cpp index 380c0af89f2..e276e858bbf 100644 --- a/mozilla/layout/forms/nsListControlFrame.cpp +++ b/mozilla/layout/forms/nsListControlFrame.cpp @@ -52,12 +52,15 @@ #include "nsIComponentManager.h" #include "nsILookAndFeel.h" +#include "nsISelectElement.h" + static NS_DEFINE_IID(kIDOMMouseListenerIID, NS_IDOMMOUSELISTENER_IID); static NS_DEFINE_IID(kIDOMMouseMotionListenerIID, NS_IDOMMOUSEMOTIONLISTENER_IID); static NS_DEFINE_IID(kIDOMKeyListenerIID, NS_IDOMKEYLISTENER_IID); static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID); static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID); static NS_DEFINE_IID(kIPrivateDOMEventIID, NS_IPRIVATEDOMEVENT_IID); +//static NS_DEFINE_IID(kBlockFrameCID, NS_BLOCK_FRAME_CID); // Constants const nscoord kMaxDropDownRows = 20; // This matches the setting for 4.x browsers @@ -87,7 +90,6 @@ NS_NewListControlFrame(nsIFrame** aNewFrame) return NS_OK; } - //--------------------------------------------------------- nsListControlFrame::nsListControlFrame() { @@ -107,6 +109,10 @@ nsListControlFrame::nsListControlFrame() mIsCapturingMouseEvents = PR_FALSE; mSelectionCache = nsnull; mSelectionCacheLength = -1; + + mIsAllContentHere = PR_FALSE; + mIsAllFramesHere = PR_FALSE; + mHasBeenInitialized = PR_FALSE; } //--------------------------------------------------------- @@ -244,7 +250,7 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { -#ifdef DEBUG_rods +#ifdef DEBUG_rodsXXX printf("nsListControlFrame::Reflow Reason: "); switch (aReflowState.reason) { case eReflowReason_Initial:printf("eReflowReason_Initial\n");break; @@ -252,8 +258,40 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext, case eReflowReason_Resize:printf("eReflowReason_Resize\n");break; case eReflowReason_StyleChange:printf("eReflowReason_StyleChange\n");break; } -#endif // DEBUG_rods +#endif // DEBUG_rodsXXX +#if 0 + // reflow optimization - why reflow if all the contents + // and frames aren't there yet + if (!mIsAllContentHere || !mIsAllFramesHere) { + aDesiredSize.width = 30*15; + aDesiredSize.height = 30*15; + if (nsnull != aDesiredSize.maxElementSize) { + aDesiredSize.maxElementSize->width = aDesiredSize.width; + aDesiredSize.maxElementSize->height = aDesiredSize.height; + } + aStatus = NS_FRAME_COMPLETE; + printf("--------------------------> Skipping reflow\n"); + return NS_OK; + } +#endif + + // If all the content and frames are here + // then initialize it before reflow + if (mIsAllContentHere && !mHasBeenInitialized) { + if (PR_FALSE == mIsAllFramesHere) { + printf("**********************************************************\n"); + printf("**********************************************************\n"); + printf("**********************************************************\n"); + CheckIfAllFramesHere(); + } + if (mIsAllFramesHere && !mHasBeenInitialized) { + mHasBeenInitialized = PR_TRUE; + InitSelectionCache(-1); // Reset sel cache so as not to send event + Reset(mPresContext); + } + } + // Strategy: Let the inherited reflow happen as though the width and height of the // ScrollFrame are big enough to allow the listbox to // shrink to fit the longest option element line in the list. @@ -479,7 +517,7 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext, aStatus = NS_FRAME_COMPLETE; mDisplayed = PR_TRUE; -#ifdef DEBUG_rods +#ifdef DEBUG_rodsXXX if (!isInDropDownMode) { PRInt32 numRows = 1; GetSizeAttribute(&numRows); @@ -760,6 +798,10 @@ nsListControlFrame::SingleSelection() } // Display the new selection SetContentSelected(mSelectedIndex, PR_TRUE); + nsCOMPtr content = getter_AddRefs(GetOptionContent(mSelectedIndex)); + if (content) { + ScrollToFrame(content); + } } else { // Selecting the currently selected item so do nothing. } @@ -1000,8 +1042,30 @@ nsListControlFrame::SetInitialChildList(nsIPresContext& aPresContext, nsIAtom* aListName, nsIFrame* aChildList) { + // First check to see if all the content has been added + nsCOMPtr element(do_QueryInterface(mContent)); + if (element) { + element->IsDoneAddingContent(&mIsAllContentHere); + if (!mIsAllContentHere) { + mIsAllFramesHere = PR_FALSE; + mHasBeenInitialized = PR_FALSE; + } + } mContentFrame = aChildList; - return nsScrollFrame::SetInitialChildList(aPresContext, aListName, aChildList); + nsresult rv = nsScrollFrame::SetInitialChildList(aPresContext, aListName, aChildList); + + // If all the content is here now check + // to see if all the frames have been created + if (mIsAllContentHere) { + // If all content and frames are here + // the reset/initialize + if (CheckIfAllFramesHere()) { + InitSelectionCache(-1); + Reset(&aPresContext); + } + } + + return rv; } //--------------------------------------------------------- @@ -1385,7 +1449,13 @@ nsListControlFrame::GetMaxNumValues() void nsListControlFrame::Reset(nsIPresContext* aPresContext) { - nsIDOMHTMLCollection* options = GetOptions(mContent); + // if all the frames aren't here + // don't bother reseting + if (!mIsAllFramesHere) { + return; + } + + nsCOMPtr options = getter_AddRefs(GetOptions(mContent)); if (!options) { return; } @@ -1398,20 +1468,28 @@ nsListControlFrame::Reset(nsIPresContext* aPresContext) Deselect(); PRUint32 i; for (i = 0; i < numOptions; i++) { - nsIDOMHTMLOptionElement* option = GetOption(*options, i); + nsCOMPtr option = getter_AddRefs(GetOption(*options, i)); if (option) { PRBool selected = PR_FALSE; option->GetDefaultSelected(&selected); if (selected) { mSelectedIndex = i; SetContentSelected(i, PR_TRUE); + + // Now that it is selected scroll to it + nsCOMPtr content(do_QueryInterface(option)); + if (content) { + ScrollToFrame(content); + } + if (mComboboxFrame) { + mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event + } } - NS_RELEASE(option); } } - NS_RELEASE(options); InitSelectionCache(numOptions); + } //--------------------------------------------------------- @@ -1668,9 +1746,80 @@ nsListControlFrame::ToggleSelected(PRInt32 aIndex) //---------------------------------------------------------------------- // nsISelectControlFrame //---------------------------------------------------------------------- +PRBool nsListControlFrame::CheckIfAllFramesHere() +{ + // Get the number of optgroups and options + PRInt32 numContentItems = 0; + nsCOMPtr node(do_QueryInterface(mContent)); + if (node) { + CountAllChild(node, numContentItems); + } + //printf("number of items %d ", numContentItems); + + // now count the number of block frames + // each option is in a block frame + PRInt32 numFrames = 0; + nsIFrame * areaFrame = nsnull; + FirstChild(nsnull, &areaFrame); + if (areaFrame) { + nsIFrame * child = nsnull; + areaFrame->FirstChild(nsnull, &child); + while (child) { + nsIFrame * blkFrame; + if (NS_SUCCEEDED(child->QueryInterface(kBlockFrameCID,(void**)&blkFrame))) { + numFrames++; + } + child->GetNextSibling(&child); + } + } + // now make sure we have a frame each piece of content + mIsAllFramesHere = numFrames == numContentItems; + + return mIsAllFramesHere; +} + +NS_IMETHODIMP +nsListControlFrame::DoneAddingContent() +{ + mIsAllContentHere = PR_TRUE; + + // Here we check to see if all the frames have been created + // for all the content. + // If so, then we can initialize; + if (mIsAllFramesHere == PR_FALSE) { + // if all the frames are now present we can initalize + if (CheckIfAllFramesHere() && mPresContext) { + mHasBeenInitialized = PR_TRUE; + InitSelectionCache(-1); // Reset select cache so as not to send event + Reset(mPresContext); + } + } + return NS_OK; +} + NS_IMETHODIMP nsListControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex) { +/* + if (!mIsAllContentHere) { + nsCOMPtr element(do_QueryInterface(mContent)); + if (element) { + element->IsDoneAddingContent(&mIsAllContentHere); + if (!mIsAllContentHere) { + mIsAllFramesHere = PR_FALSE; + mHasBeenInitialized = PR_FALSE; + } else { + PRInt32 numOptions; + GetNumberOfOptions(&numOptions); + mIsAllFramesHere = aIndex == numOptions-1; + } + } + } + */ + if (!mHasBeenInitialized) { + return NS_OK; + } + PRInt32 oldSelection = mSelectedIndex; // Adding an option to the select can cause a change in selection @@ -1685,8 +1834,7 @@ nsListControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex) PRBool selected = PR_FALSE; option->GetDefaultSelected(&selected); if (selected) { - // XXX this is very bad to here - //Reset(aPresContext); // this sets mSelectedIndex to the defaulted selection + Reset(aPresContext); // this sets mSelectedIndex to the defaulted selection wasReset = PR_TRUE; } } @@ -1759,7 +1907,7 @@ nsListControlFrame::SetOptionSelected(PRInt32 aIndex, PRBool aValue) } } // Should we send an event here or not? - if (nsnull != mComboboxFrame) { + if (nsnull != mComboboxFrame && mIsAllFramesHere) { rv = mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, aIndex); // don't dispatch event } else { InitSelectionCache(-1); @@ -1804,6 +1952,9 @@ nsListControlFrame::InitSelectionCache(PRInt32 aLength) NS_IMETHODIMP nsListControlFrame::UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, nsIContent* aContent) { + if (!mIsAllFramesHere || !mIsAllContentHere) { + return NS_OK; + } nsresult rv = NS_OK; PRBool changed = PR_FALSE; @@ -1917,11 +2068,11 @@ nsListControlFrame::SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, co if (mSelectedIndex != selectedIndex) { ToggleSelected(selectedIndex);// sets mSelectedIndex // Should we send an event here? - if (nsnull != mComboboxFrame) { - // XXX mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, selectedIndex); // don't dispatch event + if (nsnull != mComboboxFrame && mIsAllFramesHere) { + mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, selectedIndex); // don't dispatch event } else { - InitSelectionCache(-1); - } + InitSelectionCache(-1); + } } } } @@ -1952,8 +2103,6 @@ nsListControlFrame::GetProperty(nsIAtom* aName, nsString& aValue) selectedIndex = 0; } aValue.Append(selectedIndex, 10); - //aValue.Append(mSelectedIndex, 10); - } return NS_OK; @@ -2074,6 +2223,15 @@ NS_IMETHODIMP nsListControlFrame::AboutToDropDown() { mSelectedIndexWhenPoppedDown = mSelectedIndex; + if (mIsAllContentHere && mIsAllFramesHere && mHasBeenInitialized && + mSelectedIndex != kNothingSelected) { + // make sure we scroll to the correct item before it drops down + nsCOMPtr content = getter_AddRefs(GetOptionContent(mSelectedIndex)); + if (content) { + ScrollToFrame(content); + } + } + return NS_OK; } @@ -2196,8 +2354,10 @@ nsListControlFrame::IsTargetOptionDisabled(PRBool &aIsDisabled) // This is used to reset the the list and it's selection because the // selection was cancelled and the list rolled up. void nsListControlFrame::ResetSelectedItem() -{ - ToggleSelected(mSelectedIndexWhenPoppedDown); +{ + if (mIsAllFramesHere) { + ToggleSelected(mSelectedIndexWhenPoppedDown); + } } //---------------------------------------------------------------------- @@ -2263,18 +2423,7 @@ nsListControlFrame::GetIndexFromDOMEvent(nsIDOMEvent* aMouseEvent, if (NS_OK == mPresContext->GetEventStateManager(&stateManager)) { nsIContent * content; stateManager->GetEventTargetContent(&content); -#ifdef DEBUG_rodsXXX - /////////////////// - { - nsCOMPtr optElem; - if (NS_SUCCEEDED(content->QueryInterface(nsCOMTypeInfo::GetIID(),(void**) getter_AddRefs(optElem)))) { - nsAutoString val; - optElem->GetValue(val); - printf("val [%s]\n", val.ToNewCString()); - } - } - /////////////////// -#endif + nsIContent * optionContent = GetOptionFromContent(content); NS_RELEASE(content); if (nsnull != optionContent) { @@ -2429,6 +2578,62 @@ nsListControlFrame::KeyPress(nsIDOMEvent* aKeyEvent) return NS_OK; } + +nsresult +nsListControlFrame::ScrollToFrame(nsIContent* aOptElement) +{ + nsIFrame * childframe; + nsresult result; + if (aOptElement) { + nsCOMPtr presShell; + mPresContext->GetShell(getter_AddRefs(presShell)); + result = presShell->GetPrimaryFrameFor(aOptElement, &childframe); + } else { + return NS_ERROR_FAILURE; + } + + if (childframe) { + nsIView * scrollView; + GetView(mPresContext, &scrollView); + nsIScrollableView * scrollableView = nsnull; + scrollView->QueryInterface(nsIScrollableView::GetIID(), (void**)&scrollableView); + if (scrollableView) { + const nsIView * clippedView; + scrollableView->GetClipView(&clippedView); + nscoord x; + nscoord y; + scrollableView->GetScrollPosition(x,y); + // get the clipped rect + nsRect rect; + clippedView->GetBounds(rect); + // now move it by the offset of the scroll position + rect.x = 0; + rect.y = 0; + rect.MoveBy(x,y); + + // get the child + nsRect fRect; + childframe->GetRect(fRect); + nsPoint pnt; + nsIView * view; + childframe->GetOffsetFromView(mPresContext, pnt, &view); + + // see if the selected frame is inside the scrolled area + if (!rect.Contains(fRect)) { + // figure out which direction we are going + if (fRect.y+fRect.height >= rect.y+rect.height) { + y = fRect.y-(rect.height-fRect.height); + } else { + y = fRect.y; + } + scrollableView->ScrollTo(pnt.x, y, PR_TRUE); + } + + } + } + return NS_OK; +} + nsresult nsListControlFrame::KeyDown(nsIDOMEvent* aKeyEvent) { @@ -2450,24 +2655,24 @@ nsListControlFrame::KeyDown(nsIDOMEvent* aKeyEvent) if (numOptions == 0) { rv = NS_OK; } else { - if (code == nsIDOMKeyEvent::DOM_VK_UP) { + if (code == nsIDOMKeyEvent::DOM_VK_UP || code == nsIDOMKeyEvent::DOM_VK_LEFT) { printf("DOM_VK_UP mSelectedIndex: %d ", mSelectedIndex); if (mSelectedIndex > 0) { mOldSelectedIndex = mSelectedIndex; mSelectedIndex--; SingleSelection(); - if (nsnull != mComboboxFrame) { + if (nsnull != mComboboxFrame && mIsAllFramesHere) { mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event } } printf(" After: %d\n", mSelectedIndex); - } if (code == nsIDOMKeyEvent::DOM_VK_DOWN) { + } if (code == nsIDOMKeyEvent::DOM_VK_DOWN || code == nsIDOMKeyEvent::DOM_VK_RIGHT) { printf("DOM_VK_DOWN mSelectedIndex: %d ", mSelectedIndex); if ((mSelectedIndex+1) < (PRInt32)numOptions) { mOldSelectedIndex = mSelectedIndex; mSelectedIndex++; SingleSelection(); - if (nsnull != mComboboxFrame) { + if (nsnull != mComboboxFrame && mIsAllFramesHere) { mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event } } @@ -2500,7 +2705,7 @@ nsListControlFrame::KeyDown(nsIDOMEvent* aKeyEvent) mOldSelectedIndex = mSelectedIndex; mSelectedIndex = selectedIndex; SingleSelection(); - if (nsnull != mComboboxFrame) { + if (nsnull != mComboboxFrame && mIsAllFramesHere) { mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event } break; diff --git a/mozilla/layout/forms/nsListControlFrame.h b/mozilla/layout/forms/nsListControlFrame.h index 1a7afaa9a54..0ed46aa5d85 100644 --- a/mozilla/layout/forms/nsListControlFrame.h +++ b/mozilla/layout/forms/nsListControlFrame.h @@ -129,6 +129,7 @@ public: NS_IMETHOD RemoveOption(nsIPresContext* aPresContext, PRInt32 index); NS_IMETHOD SetOptionSelected(PRInt32 aIndex, PRBool aValue); NS_IMETHOD GetOptionSelected(PRInt32 aIndex, PRBool* aValue); + NS_IMETHOD DoneAddingContent(); //nsIStatefulFrame NS_IMETHOD GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType); @@ -161,9 +162,11 @@ public: static PRBool GetOptionValue(nsIDOMHTMLCollection& aCollecton, PRInt32 aIndex, nsString& aValue); protected: + NS_IMETHOD GetSelectedIndexFromDOM(PRInt32* aIndex); // from DOM NS_IMETHOD IsTargetOptionDisabled(PRBool &aIsDisabled); nsresult CountAllChild(nsIDOMNode * aNode, PRInt32& aCount); + nsresult ScrollToFrame(nsIContent * aOptElement); nsListControlFrame(); virtual ~nsListControlFrame(); @@ -207,6 +210,7 @@ protected: void ClearSelection(); void ExtendedSelection(PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aDoInvert, PRBool aSetValue); void ResetSelectedItem(); + PRBool CheckIfAllFramesHere(); PRBool HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2); void HandleListSelection(nsIDOMEvent * aDOMEvent); @@ -238,6 +242,10 @@ protected: PRBool* mSelectionCache; PRInt32 mSelectionCacheLength; + PRBool mIsAllContentHere; + PRBool mIsAllFramesHere; + PRBool mHasBeenInitialized; + nsIPresContext* mPresContext; // XXX: Remove the need to cache the pres context. // XXX temprary only until full system mouse capture works diff --git a/mozilla/layout/html/forms/public/nsISelectControlFrame.h b/mozilla/layout/html/forms/public/nsISelectControlFrame.h index b2d779e5131..86c77c4c900 100644 --- a/mozilla/layout/html/forms/public/nsISelectControlFrame.h +++ b/mozilla/layout/html/forms/public/nsISelectControlFrame.h @@ -54,10 +54,18 @@ public: /** * Sets the select state of the option at index */ - NS_IMETHOD SetOptionSelected(PRInt32 index, PRBool value) = 0; + /** + * Sets the select state of the option at index + */ NS_IMETHOD GetOptionSelected(PRInt32 index, PRBool* value) = 0; + + /** + * Sets the select state of the option at index + */ + NS_IMETHOD DoneAddingContent() = 0; + }; #endif diff --git a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp index 901ded8f3f1..0e49df28d11 100644 --- a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp @@ -210,7 +210,7 @@ nsComboboxControlFrame::MakeSureSomethingIsSelected(nsIPresContext* aPresContext rv = fcFrame->SetProperty(aPresContext, nsHTMLAtoms::selectedindex, "0"); mSelectedIndex = 0; } - UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // Needed to reflow when removing last option + // XXX UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // Needed to reflow when removing last option } // Don't NS_RELEASE fcFrame here as it isn't addRef'd in the QI (???) @@ -562,7 +562,7 @@ nsComboboxControlFrame::PositionDropdown(nsIPresContext& aPresContext, //if (currentRect != dropdownRect) { dropdownFrame->SetRect(&aPresContext, dropdownRect); -#ifdef DEBUG_rodsXXX +#ifdef DEBUG_rodsXXXXXX printf("%d Position Dropdown at: %d %d %d %d\n", counter++, dropdownRect.x, dropdownRect.y, dropdownRect.width, dropdownRect.height); #endif //} @@ -649,7 +649,7 @@ nsComboboxControlFrame::GetAbsoluteFramePosition(nsIPresContext& aPresContext, return rv; } -#ifdef DEBUG_rods +#ifdef DEBUG_rodsXXX static int myCounter = 0; #endif @@ -659,7 +659,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { -#ifdef DEBUG_rods +#ifdef DEBUG_rodsXXX printf("nsComboboxControlFrame::Reflow %d Reason: ", myCounter++); switch (aReflowState.reason) { case eReflowReason_Initial:printf("eReflowReason_Initial\n");break; @@ -822,7 +822,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext& aPresContext, PositionDropdown(aPresContext, aDesiredSize.height, absoluteTwips, absolutePixels); aStatus = NS_FRAME_COMPLETE; +#if 0 COMPARE_QUIRK_SIZE("nsComboboxControlFrame", 56, 22) +#endif return rv; } @@ -1082,6 +1084,19 @@ nsComboboxControlFrame::SelectionChanged() //---------------------------------------------------------------------- // nsISelectControlFrame //---------------------------------------------------------------------- +NS_IMETHODIMP +nsComboboxControlFrame::DoneAddingContent() +{ + nsISelectControlFrame* listFrame = nsnull; + nsIFrame* dropdownFrame = GetDropdownFrame(); + nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame), + (void**)&listFrame); + if (NS_SUCCEEDED(rv) && listFrame) { + rv = listFrame->DoneAddingContent(); + NS_RELEASE(listFrame); + } + return rv; +} NS_IMETHODIMP nsComboboxControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex) diff --git a/mozilla/layout/html/forms/src/nsComboboxControlFrame.h b/mozilla/layout/html/forms/src/nsComboboxControlFrame.h index c9a5c84117d..3d2d6cf7686 100644 --- a/mozilla/layout/html/forms/src/nsComboboxControlFrame.h +++ b/mozilla/layout/html/forms/src/nsComboboxControlFrame.h @@ -149,6 +149,7 @@ public: NS_IMETHOD RemoveOption(nsIPresContext* aPresContext, PRInt32 index); NS_IMETHOD SetOptionSelected(PRInt32 aIndex, PRBool aValue); NS_IMETHOD GetOptionSelected(PRInt32 aIndex, PRBool* aValue); + NS_IMETHOD DoneAddingContent(); //nsIDOMEventListener virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent); diff --git a/mozilla/layout/html/forms/src/nsListControlFrame.cpp b/mozilla/layout/html/forms/src/nsListControlFrame.cpp index 380c0af89f2..e276e858bbf 100644 --- a/mozilla/layout/html/forms/src/nsListControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsListControlFrame.cpp @@ -52,12 +52,15 @@ #include "nsIComponentManager.h" #include "nsILookAndFeel.h" +#include "nsISelectElement.h" + static NS_DEFINE_IID(kIDOMMouseListenerIID, NS_IDOMMOUSELISTENER_IID); static NS_DEFINE_IID(kIDOMMouseMotionListenerIID, NS_IDOMMOUSEMOTIONLISTENER_IID); static NS_DEFINE_IID(kIDOMKeyListenerIID, NS_IDOMKEYLISTENER_IID); static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID); static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID); static NS_DEFINE_IID(kIPrivateDOMEventIID, NS_IPRIVATEDOMEVENT_IID); +//static NS_DEFINE_IID(kBlockFrameCID, NS_BLOCK_FRAME_CID); // Constants const nscoord kMaxDropDownRows = 20; // This matches the setting for 4.x browsers @@ -87,7 +90,6 @@ NS_NewListControlFrame(nsIFrame** aNewFrame) return NS_OK; } - //--------------------------------------------------------- nsListControlFrame::nsListControlFrame() { @@ -107,6 +109,10 @@ nsListControlFrame::nsListControlFrame() mIsCapturingMouseEvents = PR_FALSE; mSelectionCache = nsnull; mSelectionCacheLength = -1; + + mIsAllContentHere = PR_FALSE; + mIsAllFramesHere = PR_FALSE; + mHasBeenInitialized = PR_FALSE; } //--------------------------------------------------------- @@ -244,7 +250,7 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { -#ifdef DEBUG_rods +#ifdef DEBUG_rodsXXX printf("nsListControlFrame::Reflow Reason: "); switch (aReflowState.reason) { case eReflowReason_Initial:printf("eReflowReason_Initial\n");break; @@ -252,8 +258,40 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext, case eReflowReason_Resize:printf("eReflowReason_Resize\n");break; case eReflowReason_StyleChange:printf("eReflowReason_StyleChange\n");break; } -#endif // DEBUG_rods +#endif // DEBUG_rodsXXX +#if 0 + // reflow optimization - why reflow if all the contents + // and frames aren't there yet + if (!mIsAllContentHere || !mIsAllFramesHere) { + aDesiredSize.width = 30*15; + aDesiredSize.height = 30*15; + if (nsnull != aDesiredSize.maxElementSize) { + aDesiredSize.maxElementSize->width = aDesiredSize.width; + aDesiredSize.maxElementSize->height = aDesiredSize.height; + } + aStatus = NS_FRAME_COMPLETE; + printf("--------------------------> Skipping reflow\n"); + return NS_OK; + } +#endif + + // If all the content and frames are here + // then initialize it before reflow + if (mIsAllContentHere && !mHasBeenInitialized) { + if (PR_FALSE == mIsAllFramesHere) { + printf("**********************************************************\n"); + printf("**********************************************************\n"); + printf("**********************************************************\n"); + CheckIfAllFramesHere(); + } + if (mIsAllFramesHere && !mHasBeenInitialized) { + mHasBeenInitialized = PR_TRUE; + InitSelectionCache(-1); // Reset sel cache so as not to send event + Reset(mPresContext); + } + } + // Strategy: Let the inherited reflow happen as though the width and height of the // ScrollFrame are big enough to allow the listbox to // shrink to fit the longest option element line in the list. @@ -479,7 +517,7 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext, aStatus = NS_FRAME_COMPLETE; mDisplayed = PR_TRUE; -#ifdef DEBUG_rods +#ifdef DEBUG_rodsXXX if (!isInDropDownMode) { PRInt32 numRows = 1; GetSizeAttribute(&numRows); @@ -760,6 +798,10 @@ nsListControlFrame::SingleSelection() } // Display the new selection SetContentSelected(mSelectedIndex, PR_TRUE); + nsCOMPtr content = getter_AddRefs(GetOptionContent(mSelectedIndex)); + if (content) { + ScrollToFrame(content); + } } else { // Selecting the currently selected item so do nothing. } @@ -1000,8 +1042,30 @@ nsListControlFrame::SetInitialChildList(nsIPresContext& aPresContext, nsIAtom* aListName, nsIFrame* aChildList) { + // First check to see if all the content has been added + nsCOMPtr element(do_QueryInterface(mContent)); + if (element) { + element->IsDoneAddingContent(&mIsAllContentHere); + if (!mIsAllContentHere) { + mIsAllFramesHere = PR_FALSE; + mHasBeenInitialized = PR_FALSE; + } + } mContentFrame = aChildList; - return nsScrollFrame::SetInitialChildList(aPresContext, aListName, aChildList); + nsresult rv = nsScrollFrame::SetInitialChildList(aPresContext, aListName, aChildList); + + // If all the content is here now check + // to see if all the frames have been created + if (mIsAllContentHere) { + // If all content and frames are here + // the reset/initialize + if (CheckIfAllFramesHere()) { + InitSelectionCache(-1); + Reset(&aPresContext); + } + } + + return rv; } //--------------------------------------------------------- @@ -1385,7 +1449,13 @@ nsListControlFrame::GetMaxNumValues() void nsListControlFrame::Reset(nsIPresContext* aPresContext) { - nsIDOMHTMLCollection* options = GetOptions(mContent); + // if all the frames aren't here + // don't bother reseting + if (!mIsAllFramesHere) { + return; + } + + nsCOMPtr options = getter_AddRefs(GetOptions(mContent)); if (!options) { return; } @@ -1398,20 +1468,28 @@ nsListControlFrame::Reset(nsIPresContext* aPresContext) Deselect(); PRUint32 i; for (i = 0; i < numOptions; i++) { - nsIDOMHTMLOptionElement* option = GetOption(*options, i); + nsCOMPtr option = getter_AddRefs(GetOption(*options, i)); if (option) { PRBool selected = PR_FALSE; option->GetDefaultSelected(&selected); if (selected) { mSelectedIndex = i; SetContentSelected(i, PR_TRUE); + + // Now that it is selected scroll to it + nsCOMPtr content(do_QueryInterface(option)); + if (content) { + ScrollToFrame(content); + } + if (mComboboxFrame) { + mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event + } } - NS_RELEASE(option); } } - NS_RELEASE(options); InitSelectionCache(numOptions); + } //--------------------------------------------------------- @@ -1668,9 +1746,80 @@ nsListControlFrame::ToggleSelected(PRInt32 aIndex) //---------------------------------------------------------------------- // nsISelectControlFrame //---------------------------------------------------------------------- +PRBool nsListControlFrame::CheckIfAllFramesHere() +{ + // Get the number of optgroups and options + PRInt32 numContentItems = 0; + nsCOMPtr node(do_QueryInterface(mContent)); + if (node) { + CountAllChild(node, numContentItems); + } + //printf("number of items %d ", numContentItems); + + // now count the number of block frames + // each option is in a block frame + PRInt32 numFrames = 0; + nsIFrame * areaFrame = nsnull; + FirstChild(nsnull, &areaFrame); + if (areaFrame) { + nsIFrame * child = nsnull; + areaFrame->FirstChild(nsnull, &child); + while (child) { + nsIFrame * blkFrame; + if (NS_SUCCEEDED(child->QueryInterface(kBlockFrameCID,(void**)&blkFrame))) { + numFrames++; + } + child->GetNextSibling(&child); + } + } + // now make sure we have a frame each piece of content + mIsAllFramesHere = numFrames == numContentItems; + + return mIsAllFramesHere; +} + +NS_IMETHODIMP +nsListControlFrame::DoneAddingContent() +{ + mIsAllContentHere = PR_TRUE; + + // Here we check to see if all the frames have been created + // for all the content. + // If so, then we can initialize; + if (mIsAllFramesHere == PR_FALSE) { + // if all the frames are now present we can initalize + if (CheckIfAllFramesHere() && mPresContext) { + mHasBeenInitialized = PR_TRUE; + InitSelectionCache(-1); // Reset select cache so as not to send event + Reset(mPresContext); + } + } + return NS_OK; +} + NS_IMETHODIMP nsListControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex) { +/* + if (!mIsAllContentHere) { + nsCOMPtr element(do_QueryInterface(mContent)); + if (element) { + element->IsDoneAddingContent(&mIsAllContentHere); + if (!mIsAllContentHere) { + mIsAllFramesHere = PR_FALSE; + mHasBeenInitialized = PR_FALSE; + } else { + PRInt32 numOptions; + GetNumberOfOptions(&numOptions); + mIsAllFramesHere = aIndex == numOptions-1; + } + } + } + */ + if (!mHasBeenInitialized) { + return NS_OK; + } + PRInt32 oldSelection = mSelectedIndex; // Adding an option to the select can cause a change in selection @@ -1685,8 +1834,7 @@ nsListControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex) PRBool selected = PR_FALSE; option->GetDefaultSelected(&selected); if (selected) { - // XXX this is very bad to here - //Reset(aPresContext); // this sets mSelectedIndex to the defaulted selection + Reset(aPresContext); // this sets mSelectedIndex to the defaulted selection wasReset = PR_TRUE; } } @@ -1759,7 +1907,7 @@ nsListControlFrame::SetOptionSelected(PRInt32 aIndex, PRBool aValue) } } // Should we send an event here or not? - if (nsnull != mComboboxFrame) { + if (nsnull != mComboboxFrame && mIsAllFramesHere) { rv = mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, aIndex); // don't dispatch event } else { InitSelectionCache(-1); @@ -1804,6 +1952,9 @@ nsListControlFrame::InitSelectionCache(PRInt32 aLength) NS_IMETHODIMP nsListControlFrame::UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, nsIContent* aContent) { + if (!mIsAllFramesHere || !mIsAllContentHere) { + return NS_OK; + } nsresult rv = NS_OK; PRBool changed = PR_FALSE; @@ -1917,11 +2068,11 @@ nsListControlFrame::SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, co if (mSelectedIndex != selectedIndex) { ToggleSelected(selectedIndex);// sets mSelectedIndex // Should we send an event here? - if (nsnull != mComboboxFrame) { - // XXX mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, selectedIndex); // don't dispatch event + if (nsnull != mComboboxFrame && mIsAllFramesHere) { + mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, selectedIndex); // don't dispatch event } else { - InitSelectionCache(-1); - } + InitSelectionCache(-1); + } } } } @@ -1952,8 +2103,6 @@ nsListControlFrame::GetProperty(nsIAtom* aName, nsString& aValue) selectedIndex = 0; } aValue.Append(selectedIndex, 10); - //aValue.Append(mSelectedIndex, 10); - } return NS_OK; @@ -2074,6 +2223,15 @@ NS_IMETHODIMP nsListControlFrame::AboutToDropDown() { mSelectedIndexWhenPoppedDown = mSelectedIndex; + if (mIsAllContentHere && mIsAllFramesHere && mHasBeenInitialized && + mSelectedIndex != kNothingSelected) { + // make sure we scroll to the correct item before it drops down + nsCOMPtr content = getter_AddRefs(GetOptionContent(mSelectedIndex)); + if (content) { + ScrollToFrame(content); + } + } + return NS_OK; } @@ -2196,8 +2354,10 @@ nsListControlFrame::IsTargetOptionDisabled(PRBool &aIsDisabled) // This is used to reset the the list and it's selection because the // selection was cancelled and the list rolled up. void nsListControlFrame::ResetSelectedItem() -{ - ToggleSelected(mSelectedIndexWhenPoppedDown); +{ + if (mIsAllFramesHere) { + ToggleSelected(mSelectedIndexWhenPoppedDown); + } } //---------------------------------------------------------------------- @@ -2263,18 +2423,7 @@ nsListControlFrame::GetIndexFromDOMEvent(nsIDOMEvent* aMouseEvent, if (NS_OK == mPresContext->GetEventStateManager(&stateManager)) { nsIContent * content; stateManager->GetEventTargetContent(&content); -#ifdef DEBUG_rodsXXX - /////////////////// - { - nsCOMPtr optElem; - if (NS_SUCCEEDED(content->QueryInterface(nsCOMTypeInfo::GetIID(),(void**) getter_AddRefs(optElem)))) { - nsAutoString val; - optElem->GetValue(val); - printf("val [%s]\n", val.ToNewCString()); - } - } - /////////////////// -#endif + nsIContent * optionContent = GetOptionFromContent(content); NS_RELEASE(content); if (nsnull != optionContent) { @@ -2429,6 +2578,62 @@ nsListControlFrame::KeyPress(nsIDOMEvent* aKeyEvent) return NS_OK; } + +nsresult +nsListControlFrame::ScrollToFrame(nsIContent* aOptElement) +{ + nsIFrame * childframe; + nsresult result; + if (aOptElement) { + nsCOMPtr presShell; + mPresContext->GetShell(getter_AddRefs(presShell)); + result = presShell->GetPrimaryFrameFor(aOptElement, &childframe); + } else { + return NS_ERROR_FAILURE; + } + + if (childframe) { + nsIView * scrollView; + GetView(mPresContext, &scrollView); + nsIScrollableView * scrollableView = nsnull; + scrollView->QueryInterface(nsIScrollableView::GetIID(), (void**)&scrollableView); + if (scrollableView) { + const nsIView * clippedView; + scrollableView->GetClipView(&clippedView); + nscoord x; + nscoord y; + scrollableView->GetScrollPosition(x,y); + // get the clipped rect + nsRect rect; + clippedView->GetBounds(rect); + // now move it by the offset of the scroll position + rect.x = 0; + rect.y = 0; + rect.MoveBy(x,y); + + // get the child + nsRect fRect; + childframe->GetRect(fRect); + nsPoint pnt; + nsIView * view; + childframe->GetOffsetFromView(mPresContext, pnt, &view); + + // see if the selected frame is inside the scrolled area + if (!rect.Contains(fRect)) { + // figure out which direction we are going + if (fRect.y+fRect.height >= rect.y+rect.height) { + y = fRect.y-(rect.height-fRect.height); + } else { + y = fRect.y; + } + scrollableView->ScrollTo(pnt.x, y, PR_TRUE); + } + + } + } + return NS_OK; +} + nsresult nsListControlFrame::KeyDown(nsIDOMEvent* aKeyEvent) { @@ -2450,24 +2655,24 @@ nsListControlFrame::KeyDown(nsIDOMEvent* aKeyEvent) if (numOptions == 0) { rv = NS_OK; } else { - if (code == nsIDOMKeyEvent::DOM_VK_UP) { + if (code == nsIDOMKeyEvent::DOM_VK_UP || code == nsIDOMKeyEvent::DOM_VK_LEFT) { printf("DOM_VK_UP mSelectedIndex: %d ", mSelectedIndex); if (mSelectedIndex > 0) { mOldSelectedIndex = mSelectedIndex; mSelectedIndex--; SingleSelection(); - if (nsnull != mComboboxFrame) { + if (nsnull != mComboboxFrame && mIsAllFramesHere) { mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event } } printf(" After: %d\n", mSelectedIndex); - } if (code == nsIDOMKeyEvent::DOM_VK_DOWN) { + } if (code == nsIDOMKeyEvent::DOM_VK_DOWN || code == nsIDOMKeyEvent::DOM_VK_RIGHT) { printf("DOM_VK_DOWN mSelectedIndex: %d ", mSelectedIndex); if ((mSelectedIndex+1) < (PRInt32)numOptions) { mOldSelectedIndex = mSelectedIndex; mSelectedIndex++; SingleSelection(); - if (nsnull != mComboboxFrame) { + if (nsnull != mComboboxFrame && mIsAllFramesHere) { mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event } } @@ -2500,7 +2705,7 @@ nsListControlFrame::KeyDown(nsIDOMEvent* aKeyEvent) mOldSelectedIndex = mSelectedIndex; mSelectedIndex = selectedIndex; SingleSelection(); - if (nsnull != mComboboxFrame) { + if (nsnull != mComboboxFrame && mIsAllFramesHere) { mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event } break; diff --git a/mozilla/layout/html/forms/src/nsListControlFrame.h b/mozilla/layout/html/forms/src/nsListControlFrame.h index 1a7afaa9a54..0ed46aa5d85 100644 --- a/mozilla/layout/html/forms/src/nsListControlFrame.h +++ b/mozilla/layout/html/forms/src/nsListControlFrame.h @@ -129,6 +129,7 @@ public: NS_IMETHOD RemoveOption(nsIPresContext* aPresContext, PRInt32 index); NS_IMETHOD SetOptionSelected(PRInt32 aIndex, PRBool aValue); NS_IMETHOD GetOptionSelected(PRInt32 aIndex, PRBool* aValue); + NS_IMETHOD DoneAddingContent(); //nsIStatefulFrame NS_IMETHOD GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType); @@ -161,9 +162,11 @@ public: static PRBool GetOptionValue(nsIDOMHTMLCollection& aCollecton, PRInt32 aIndex, nsString& aValue); protected: + NS_IMETHOD GetSelectedIndexFromDOM(PRInt32* aIndex); // from DOM NS_IMETHOD IsTargetOptionDisabled(PRBool &aIsDisabled); nsresult CountAllChild(nsIDOMNode * aNode, PRInt32& aCount); + nsresult ScrollToFrame(nsIContent * aOptElement); nsListControlFrame(); virtual ~nsListControlFrame(); @@ -207,6 +210,7 @@ protected: void ClearSelection(); void ExtendedSelection(PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aDoInvert, PRBool aSetValue); void ResetSelectedItem(); + PRBool CheckIfAllFramesHere(); PRBool HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2); void HandleListSelection(nsIDOMEvent * aDOMEvent); @@ -238,6 +242,10 @@ protected: PRBool* mSelectionCache; PRInt32 mSelectionCacheLength; + PRBool mIsAllContentHere; + PRBool mIsAllFramesHere; + PRBool mHasBeenInitialized; + nsIPresContext* mPresContext; // XXX: Remove the need to cache the pres context. // XXX temprary only until full system mouse capture works