They now cache their state properly in the PresState

b 21945 r=pollmann
This commit is contained in:
rods%netscape.com 2000-02-15 15:04:38 +00:00
Родитель f88694fec6
Коммит 1acec82129
8 изменённых файлов: 162 добавлений и 200 удалений

Просмотреть файл

@ -559,7 +559,7 @@ nsHTMLSelectElement::SetSelectedIndex(PRInt32 aIndex)
// Set the index as selected and add it to the array
nsCOMPtr<nsISupportsPRInt32> thisVal;
nsresult res = nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_PROGID,
res = nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_PROGID,
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(thisVal));
if (NS_SUCCEEDED(res) && thisVal) {
res = thisVal->SetData(aIndex);

Просмотреть файл

@ -1361,7 +1361,10 @@ nsComboboxControlFrame::SetDropDown(nsIFrame* aDropDownFrame)
return NS_ERROR_FAILURE;
}
if (mPresState) {
mListControlFrame->SetPresState(mPresState);
mPresState = do_QueryInterface(nsnull);
}
return NS_OK;
}
@ -1506,14 +1509,16 @@ nsComboboxControlFrame::SelectionChanged()
NS_IMETHODIMP
nsComboboxControlFrame::DoneAddingContent(PRBool aIsDone)
{
nsISelectControlFrame* listFrame = nsnull;
nsIFrame* dropdownFrame = GetDropdownFrame();
nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame),
(void**)&listFrame);
if (NS_SUCCEEDED(rv) && listFrame) {
rv = listFrame->DoneAddingContent(aIsDone);
NS_RELEASE(listFrame);
nsresult rv = NS_ERROR_FAILURE;
if (dropdownFrame != nsnull) {
rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame),
(void**)&listFrame);
if (NS_SUCCEEDED(rv) && listFrame) {
rv = listFrame->DoneAddingContent(aIsDone);
NS_RELEASE(listFrame);
}
}
return rv;
}
@ -1663,9 +1668,9 @@ nsComboboxControlFrame::CreateAnonymousContent(nsIPresContext* aPresContext,
// create content used for display
//nsIAtom* tag = NS_NewAtom("mozcombodisplay");
nsIAtom* tag = NS_NewAtom("input");
NS_NewHTMLInputElement(&mDisplayContent, tag);
//NS_ADDREF(mDisplayContent);
NS_NewHTMLInputElement(&mDisplayContent, nsHTMLAtoms::input);
mDisplayContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, nsAutoString("button"), PR_FALSE);
//XXX: Do not use nsHTMLAtoms::id use nsHTMLAtoms::kClass instead. There will end up being multiple
@ -1676,13 +1681,11 @@ nsComboboxControlFrame::CreateAnonymousContent(nsIPresContext* aPresContext,
aChildList.AppendElement(mDisplayContent);
// create button which drops the list down
NS_NewHTMLInputElement(&mButtonContent, tag);
NS_NewHTMLInputElement(&mButtonContent, nsHTMLAtoms::input);
//NS_ADDREF(mButtonContent);
mButtonContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, nsAutoString("button"), PR_FALSE);
aChildList.AppendElement(mButtonContent);
NS_RELEASE(tag);
return NS_OK;
}

Просмотреть файл

@ -54,6 +54,7 @@
#include "nsILookAndFeel.h"
#include "nsLayoutAtoms.h"
#include "nsIFontMetrics.h"
#include "nsVoidArray.h"
#include "nsISelectElement.h"
@ -107,8 +108,10 @@ nsListControlFrame::nsListControlFrame()
mEndExtendedIndex = kNothingSelected;
mStartExtendedIndex = kNothingSelected;
mIsCapturingMouseEvents = PR_FALSE;
mSelectionCache = nsnull;
mSelectionCacheLength = -1;
mWasRestored = PR_FALSE;
mSelectionCache = new nsVoidArray();
mSelectionCacheLength = 0;
mIsAllContentHere = PR_FALSE;
mIsAllFramesHere = PR_FALSE;
@ -151,7 +154,7 @@ nsListControlFrame::~nsListControlFrame()
}
NS_IF_RELEASE(mPresContext);
if (mSelectionCache) {
delete[] mSelectionCache;
delete mSelectionCache;
}
}
@ -208,7 +211,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;
@ -273,8 +276,8 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
}
if (mIsAllFramesHere && !mHasBeenInitialized) {
mHasBeenInitialized = PR_TRUE;
InitSelectionCache(-1); // Reset sel cache so as not to send event
Reset(mPresContext);
Reset(!mWasRestored);
mWasRestored = PR_FALSE;
#if 1
nsCOMPtr<nsIReflowCommand> cmd;
nsresult rv = NS_NewHTMLReflowCommand(getter_AddRefs(cmd), this, nsIReflowCommand::StyleChanged);
@ -1097,7 +1100,6 @@ nsListControlFrame::SetInitialChildList(nsIPresContext* aPresContext,
// If all content and frames are here
// the reset/initialize
if (CheckIfAllFramesHere()) {
InitSelectionCache(-1);
Reset(aPresContext);
mHasBeenInitialized = PR_TRUE;
}
@ -1132,17 +1134,6 @@ nsListControlFrame::Init(nsIPresContext* aPresContext,
NS_ADDREF(mPresContext);
nsresult result = nsScrollFrame::Init(aPresContext, aContent, aParent, aContext,
aPrevInFlow);
// Initialize the current selected and not selected state's for
// the listbox items from the content. This is done here because
// The selected content sets an attribute that must be on the content
// before the option element's frames are constructed so the frames will
// get the proper style based on attribute selectors which refer to the
// selected attribute.
if (!mIsInitializedFromContent) {
Reset(aPresContext);
} else {
InitSelectionCache(-1);
}
// get the reciever interface from the browser button's content node
nsCOMPtr<nsIDOMEventReceiver> reciever(do_QueryInterface(mContent));
@ -1484,6 +1475,16 @@ nsListControlFrame::GetMaxNumValues()
//---------------------------------------------------------
void
nsListControlFrame::Reset(nsIPresContext* aPresContext)
{
Reset(PR_TRUE);
}
//---------------------------------------------------------
// Resets the select back to it's original default values;
// those values as determined by the original HTML
//---------------------------------------------------------
void
nsListControlFrame::Reset(PRBool aDoSelect)
{
// if all the frames aren't here
// don't bother reseting
@ -1505,33 +1506,42 @@ nsListControlFrame::Reset(nsIPresContext* aPresContext)
PRBool multiple;
GetMultiple(&multiple);
Deselect();
if (aDoSelect) {
Deselect();
}
mSelectionCache->Clear();
mSelectionCacheLength = 0;
PRUint32 i;
for (i = 0; i < numOptions; i++) {
nsCOMPtr<nsIDOMHTMLOptionElement> option = getter_AddRefs(GetOption(*options, i));
if (option) {
PRBool selected = PR_FALSE;
option->GetDefaultSelected(&selected);
mSelectionCache->AppendElement((void*)selected);
mSelectionCacheLength++;
if (selected) {
mSelectedIndex = i;
SetContentSelected(i, PR_TRUE);
if (multiple) {
mStartExtendedIndex = i;
if (mEndExtendedIndex == kNothingSelected) {
mEndExtendedIndex = i;
}
}
if (mComboboxFrame) {
mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event
}
}
}
}
InitSelectionCache(numOptions);
if (mComboboxFrame) {
mComboboxFrame->MakeSureSomethingIsSelected(mPresContext);
if (mComboboxFrame != nsnull) {
if (mSelectedIndex == kNothingSelected) {
mComboboxFrame->MakeSureSomethingIsSelected(mPresContext);
} else {
mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event
}
}
}
@ -1809,6 +1819,7 @@ PRBool nsListControlFrame::CheckIfAllFramesHere()
return mIsAllFramesHere;
}
//-------------------------------------------------------------------
NS_IMETHODIMP
nsListControlFrame::DoneAddingContent(PRBool aIsDone)
{
@ -1821,7 +1832,6 @@ nsListControlFrame::DoneAddingContent(PRBool aIsDone)
// 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);
}
}
@ -1829,6 +1839,7 @@ nsListControlFrame::DoneAddingContent(PRBool aIsDone)
return NS_OK;
}
//-------------------------------------------------------------------
NS_IMETHODIMP
nsListControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex)
{
@ -1865,12 +1876,16 @@ nsListControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex)
if (option) {
PRBool selected = PR_FALSE;
option->GetDefaultSelected(&selected);
mSelectionCache->InsertElementAt((void*)selected, aIndex);
mSelectionCacheLength++;
if (selected) {
Reset(aPresContext); // this sets mSelectedIndex to the defaulted selection
Reset(aPresContext); // this sets mSelectedIndex to the defaulted selection
wasReset = PR_TRUE;
}
#if DEBUG_rods
#if DEBUG_rodsXXX
{
nsAutoString text = "No Value";
nsresult rv = option->GetLabel(text);
@ -1889,18 +1904,18 @@ nsListControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex)
// if selection changed because of the new option being added
// notify the combox if necessary
if (nsnull != mComboboxFrame && oldSelection != mSelectedIndex) {
mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event
if (mComboboxFrame != nsnull) {
if (mSelectedIndex == kNothingSelected) {
mComboboxFrame->MakeSureSomethingIsSelected(mPresContext);
} else if (oldSelection != mSelectedIndex) {
mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event
}
}
// selectionChanged = (1 == numOptions ||
// kNothingSelected == oldSelectedIndex || mSelectedIndex != oldSelectedIndex)
// For now, we don't care because we're not dispatching an event:
InitSelectionCache(-1); // Reset sel cache so as not to send event
return NS_OK;
}
//-------------------------------------------------------------------
NS_IMETHODIMP
nsListControlFrame::RemoveOption(nsIPresContext* aPresContext, PRInt32 aIndex)
{
@ -1916,13 +1931,9 @@ nsListControlFrame::RemoveOption(nsIPresContext* aPresContext, PRInt32 aIndex)
SetContentSelected(mSelectedIndex, PR_TRUE);
}
// Only if aIndex != -1 can we determine if there was a change in selection
// selectionChanged = (aIndex == mSelectedIndex) || (mSelectedIndex ==
// oldSelectedIndex - (oldSelectedIndex > aIndex)?1:0);
// Call SelectionChanged to dispatch an event if so!
mSelectionCache->RemoveElementAt(aIndex);
mSelectionCacheLength--;
// For now, we don't care because we're not dispatching an event:
InitSelectionCache(-1); // Reset cache to not send event
return NS_OK;
}
@ -1952,39 +1963,6 @@ nsListControlFrame::SetOptionSelected(PRInt32 aIndex, PRBool aValue)
// Should we send an event here or not?
if (nsnull != mComboboxFrame && mIsAllFramesHere) {
rv = mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, aIndex); // don't dispatch event
//} else {
// InitSelectionCache(-1);
}
}
return rv;
}
// Initialize selection cache from content state;
nsresult
nsListControlFrame::InitSelectionCache(PRInt32 aLength)
{
nsresult rv = NS_OK;
// Get number of options from content if needed
if (0 > aLength) {
rv = GetNumberOfOptions(&aLength);
}
// Allocate a new array or realloc if the length has changed
if (NS_SUCCEEDED(rv) && (mSelectionCacheLength != aLength)) {
if (mSelectionCache) {
delete[] mSelectionCache;
mSelectionCacheLength = 0;
}
mSelectionCache = new PRBool[aLength];
if (!mSelectionCache) return NS_ERROR_OUT_OF_MEMORY;
mSelectionCacheLength = aLength;
}
// Sync the cache to the content
if (NS_SUCCEEDED(rv)) {
for (PRInt32 i = 0; i < mSelectionCacheLength; i++) {
mSelectionCache[i] = IsContentSelectedByIndex(i);
}
}
return rv;
@ -2006,7 +1984,6 @@ nsListControlFrame::UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate
GetNumberOfOptions(&length);
if (mSelectionCacheLength != length) {
NS_ASSERTION(0,"nsListControlFrame: Cache sync'd with content!\n");
rv = InitSelectionCache(length);
changed = PR_TRUE; // Assume the worst, there was a change.
}
@ -2016,8 +1993,8 @@ nsListControlFrame::UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate
PRBool selected;
for (PRInt32 i = 0; i < length; i++) {
selected = IsContentSelectedByIndex(i);
if (selected != mSelectionCache[i]) {
mSelectionCache[i] = selected;
if (selected != (PRBool)mSelectionCache->ElementAt(i)) {
mSelectionCache->ReplaceElementAt((void*)selected, i);
changed = PR_TRUE;
}
}
@ -2133,8 +2110,6 @@ nsListControlFrame::SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, co
ToggleSelected(selectedIndex); // sets mSelectedIndex
if (nsnull != mComboboxFrame && mIsAllFramesHere) {
mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, selectedIndex); // don't dispatch event
//} else {
//InitSelectionCache(-1);
}
}
}
@ -2939,11 +2914,11 @@ nsListControlFrame::RestoreState(nsIPresContext* aPresContext,
if (!value)
return res;
Deselect();
PRUint32 count = 0;
value->Count(&count);
mWasRestored = PR_TRUE;
nsCOMPtr<nsISupportsPRInt32> thisVal;
PRInt32 j=0;
for (PRUint32 i=0; i<count; i++) {

Просмотреть файл

@ -38,6 +38,7 @@ class nsIDOMHTMLOptionElement;
class nsIComboboxControlFrame;
class nsIViewManager;
class nsIPresContext;
class nsVoidArray;
/**
* Frame-based listbox.
@ -94,6 +95,7 @@ public:
virtual void SetFocus(PRBool aOn = PR_TRUE, PRBool aRepaint = PR_FALSE);
virtual void ScrollIntoView(nsIPresContext* aPresContext);
virtual void MouseClicked(nsIPresContext* aPresContext);
virtual void Reset(PRBool aDoSelect = PR_TRUE);
virtual void Reset(nsIPresContext* aPresContext);
virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter);
virtual PRInt32 GetMaxNumValues();
@ -220,7 +222,6 @@ protected:
PRBool IsLeftButton(nsIDOMEvent* aMouseEvent);
// onChange detection
nsresult InitSelectionCache(PRInt32 aLength);
nsresult SelectionChanged(nsIContent* aContent);
// Data Members
@ -236,12 +237,14 @@ protected:
nscoord mMaxWidth;
nscoord mMaxHeight;
PRBool mIsCapturingMouseEvents;
PRBool* mSelectionCache;
PRInt32 mSelectionCacheLength;
nsVoidArray * mSelectionCache;
PRInt32 mSelectionCacheLength;
PRBool mIsAllContentHere;
PRBool mIsAllFramesHere;
PRBool mHasBeenInitialized;
PRBool mWasRestored;
nsIPresContext* mPresContext; // XXX: Remove the need to cache the pres context.

Просмотреть файл

@ -559,7 +559,7 @@ nsHTMLSelectElement::SetSelectedIndex(PRInt32 aIndex)
// Set the index as selected and add it to the array
nsCOMPtr<nsISupportsPRInt32> thisVal;
nsresult res = nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_PROGID,
res = nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_PROGID,
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(thisVal));
if (NS_SUCCEEDED(res) && thisVal) {
res = thisVal->SetData(aIndex);

Просмотреть файл

@ -1361,7 +1361,10 @@ nsComboboxControlFrame::SetDropDown(nsIFrame* aDropDownFrame)
return NS_ERROR_FAILURE;
}
if (mPresState) {
mListControlFrame->SetPresState(mPresState);
mPresState = do_QueryInterface(nsnull);
}
return NS_OK;
}
@ -1506,14 +1509,16 @@ nsComboboxControlFrame::SelectionChanged()
NS_IMETHODIMP
nsComboboxControlFrame::DoneAddingContent(PRBool aIsDone)
{
nsISelectControlFrame* listFrame = nsnull;
nsIFrame* dropdownFrame = GetDropdownFrame();
nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame),
(void**)&listFrame);
if (NS_SUCCEEDED(rv) && listFrame) {
rv = listFrame->DoneAddingContent(aIsDone);
NS_RELEASE(listFrame);
nsresult rv = NS_ERROR_FAILURE;
if (dropdownFrame != nsnull) {
rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame),
(void**)&listFrame);
if (NS_SUCCEEDED(rv) && listFrame) {
rv = listFrame->DoneAddingContent(aIsDone);
NS_RELEASE(listFrame);
}
}
return rv;
}
@ -1663,9 +1668,9 @@ nsComboboxControlFrame::CreateAnonymousContent(nsIPresContext* aPresContext,
// create content used for display
//nsIAtom* tag = NS_NewAtom("mozcombodisplay");
nsIAtom* tag = NS_NewAtom("input");
NS_NewHTMLInputElement(&mDisplayContent, tag);
//NS_ADDREF(mDisplayContent);
NS_NewHTMLInputElement(&mDisplayContent, nsHTMLAtoms::input);
mDisplayContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, nsAutoString("button"), PR_FALSE);
//XXX: Do not use nsHTMLAtoms::id use nsHTMLAtoms::kClass instead. There will end up being multiple
@ -1676,13 +1681,11 @@ nsComboboxControlFrame::CreateAnonymousContent(nsIPresContext* aPresContext,
aChildList.AppendElement(mDisplayContent);
// create button which drops the list down
NS_NewHTMLInputElement(&mButtonContent, tag);
NS_NewHTMLInputElement(&mButtonContent, nsHTMLAtoms::input);
//NS_ADDREF(mButtonContent);
mButtonContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, nsAutoString("button"), PR_FALSE);
aChildList.AppendElement(mButtonContent);
NS_RELEASE(tag);
return NS_OK;
}

Просмотреть файл

@ -54,6 +54,7 @@
#include "nsILookAndFeel.h"
#include "nsLayoutAtoms.h"
#include "nsIFontMetrics.h"
#include "nsVoidArray.h"
#include "nsISelectElement.h"
@ -107,8 +108,10 @@ nsListControlFrame::nsListControlFrame()
mEndExtendedIndex = kNothingSelected;
mStartExtendedIndex = kNothingSelected;
mIsCapturingMouseEvents = PR_FALSE;
mSelectionCache = nsnull;
mSelectionCacheLength = -1;
mWasRestored = PR_FALSE;
mSelectionCache = new nsVoidArray();
mSelectionCacheLength = 0;
mIsAllContentHere = PR_FALSE;
mIsAllFramesHere = PR_FALSE;
@ -151,7 +154,7 @@ nsListControlFrame::~nsListControlFrame()
}
NS_IF_RELEASE(mPresContext);
if (mSelectionCache) {
delete[] mSelectionCache;
delete mSelectionCache;
}
}
@ -208,7 +211,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;
@ -273,8 +276,8 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
}
if (mIsAllFramesHere && !mHasBeenInitialized) {
mHasBeenInitialized = PR_TRUE;
InitSelectionCache(-1); // Reset sel cache so as not to send event
Reset(mPresContext);
Reset(!mWasRestored);
mWasRestored = PR_FALSE;
#if 1
nsCOMPtr<nsIReflowCommand> cmd;
nsresult rv = NS_NewHTMLReflowCommand(getter_AddRefs(cmd), this, nsIReflowCommand::StyleChanged);
@ -1097,7 +1100,6 @@ nsListControlFrame::SetInitialChildList(nsIPresContext* aPresContext,
// If all content and frames are here
// the reset/initialize
if (CheckIfAllFramesHere()) {
InitSelectionCache(-1);
Reset(aPresContext);
mHasBeenInitialized = PR_TRUE;
}
@ -1132,17 +1134,6 @@ nsListControlFrame::Init(nsIPresContext* aPresContext,
NS_ADDREF(mPresContext);
nsresult result = nsScrollFrame::Init(aPresContext, aContent, aParent, aContext,
aPrevInFlow);
// Initialize the current selected and not selected state's for
// the listbox items from the content. This is done here because
// The selected content sets an attribute that must be on the content
// before the option element's frames are constructed so the frames will
// get the proper style based on attribute selectors which refer to the
// selected attribute.
if (!mIsInitializedFromContent) {
Reset(aPresContext);
} else {
InitSelectionCache(-1);
}
// get the reciever interface from the browser button's content node
nsCOMPtr<nsIDOMEventReceiver> reciever(do_QueryInterface(mContent));
@ -1484,6 +1475,16 @@ nsListControlFrame::GetMaxNumValues()
//---------------------------------------------------------
void
nsListControlFrame::Reset(nsIPresContext* aPresContext)
{
Reset(PR_TRUE);
}
//---------------------------------------------------------
// Resets the select back to it's original default values;
// those values as determined by the original HTML
//---------------------------------------------------------
void
nsListControlFrame::Reset(PRBool aDoSelect)
{
// if all the frames aren't here
// don't bother reseting
@ -1505,33 +1506,42 @@ nsListControlFrame::Reset(nsIPresContext* aPresContext)
PRBool multiple;
GetMultiple(&multiple);
Deselect();
if (aDoSelect) {
Deselect();
}
mSelectionCache->Clear();
mSelectionCacheLength = 0;
PRUint32 i;
for (i = 0; i < numOptions; i++) {
nsCOMPtr<nsIDOMHTMLOptionElement> option = getter_AddRefs(GetOption(*options, i));
if (option) {
PRBool selected = PR_FALSE;
option->GetDefaultSelected(&selected);
mSelectionCache->AppendElement((void*)selected);
mSelectionCacheLength++;
if (selected) {
mSelectedIndex = i;
SetContentSelected(i, PR_TRUE);
if (multiple) {
mStartExtendedIndex = i;
if (mEndExtendedIndex == kNothingSelected) {
mEndExtendedIndex = i;
}
}
if (mComboboxFrame) {
mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event
}
}
}
}
InitSelectionCache(numOptions);
if (mComboboxFrame) {
mComboboxFrame->MakeSureSomethingIsSelected(mPresContext);
if (mComboboxFrame != nsnull) {
if (mSelectedIndex == kNothingSelected) {
mComboboxFrame->MakeSureSomethingIsSelected(mPresContext);
} else {
mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event
}
}
}
@ -1809,6 +1819,7 @@ PRBool nsListControlFrame::CheckIfAllFramesHere()
return mIsAllFramesHere;
}
//-------------------------------------------------------------------
NS_IMETHODIMP
nsListControlFrame::DoneAddingContent(PRBool aIsDone)
{
@ -1821,7 +1832,6 @@ nsListControlFrame::DoneAddingContent(PRBool aIsDone)
// 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);
}
}
@ -1829,6 +1839,7 @@ nsListControlFrame::DoneAddingContent(PRBool aIsDone)
return NS_OK;
}
//-------------------------------------------------------------------
NS_IMETHODIMP
nsListControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex)
{
@ -1865,12 +1876,16 @@ nsListControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex)
if (option) {
PRBool selected = PR_FALSE;
option->GetDefaultSelected(&selected);
mSelectionCache->InsertElementAt((void*)selected, aIndex);
mSelectionCacheLength++;
if (selected) {
Reset(aPresContext); // this sets mSelectedIndex to the defaulted selection
Reset(aPresContext); // this sets mSelectedIndex to the defaulted selection
wasReset = PR_TRUE;
}
#if DEBUG_rods
#if DEBUG_rodsXXX
{
nsAutoString text = "No Value";
nsresult rv = option->GetLabel(text);
@ -1889,18 +1904,18 @@ nsListControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex)
// if selection changed because of the new option being added
// notify the combox if necessary
if (nsnull != mComboboxFrame && oldSelection != mSelectedIndex) {
mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event
if (mComboboxFrame != nsnull) {
if (mSelectedIndex == kNothingSelected) {
mComboboxFrame->MakeSureSomethingIsSelected(mPresContext);
} else if (oldSelection != mSelectedIndex) {
mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, mSelectedIndex); // don't dispatch event
}
}
// selectionChanged = (1 == numOptions ||
// kNothingSelected == oldSelectedIndex || mSelectedIndex != oldSelectedIndex)
// For now, we don't care because we're not dispatching an event:
InitSelectionCache(-1); // Reset sel cache so as not to send event
return NS_OK;
}
//-------------------------------------------------------------------
NS_IMETHODIMP
nsListControlFrame::RemoveOption(nsIPresContext* aPresContext, PRInt32 aIndex)
{
@ -1916,13 +1931,9 @@ nsListControlFrame::RemoveOption(nsIPresContext* aPresContext, PRInt32 aIndex)
SetContentSelected(mSelectedIndex, PR_TRUE);
}
// Only if aIndex != -1 can we determine if there was a change in selection
// selectionChanged = (aIndex == mSelectedIndex) || (mSelectedIndex ==
// oldSelectedIndex - (oldSelectedIndex > aIndex)?1:0);
// Call SelectionChanged to dispatch an event if so!
mSelectionCache->RemoveElementAt(aIndex);
mSelectionCacheLength--;
// For now, we don't care because we're not dispatching an event:
InitSelectionCache(-1); // Reset cache to not send event
return NS_OK;
}
@ -1952,39 +1963,6 @@ nsListControlFrame::SetOptionSelected(PRInt32 aIndex, PRBool aValue)
// Should we send an event here or not?
if (nsnull != mComboboxFrame && mIsAllFramesHere) {
rv = mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, aIndex); // don't dispatch event
//} else {
// InitSelectionCache(-1);
}
}
return rv;
}
// Initialize selection cache from content state;
nsresult
nsListControlFrame::InitSelectionCache(PRInt32 aLength)
{
nsresult rv = NS_OK;
// Get number of options from content if needed
if (0 > aLength) {
rv = GetNumberOfOptions(&aLength);
}
// Allocate a new array or realloc if the length has changed
if (NS_SUCCEEDED(rv) && (mSelectionCacheLength != aLength)) {
if (mSelectionCache) {
delete[] mSelectionCache;
mSelectionCacheLength = 0;
}
mSelectionCache = new PRBool[aLength];
if (!mSelectionCache) return NS_ERROR_OUT_OF_MEMORY;
mSelectionCacheLength = aLength;
}
// Sync the cache to the content
if (NS_SUCCEEDED(rv)) {
for (PRInt32 i = 0; i < mSelectionCacheLength; i++) {
mSelectionCache[i] = IsContentSelectedByIndex(i);
}
}
return rv;
@ -2006,7 +1984,6 @@ nsListControlFrame::UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate
GetNumberOfOptions(&length);
if (mSelectionCacheLength != length) {
NS_ASSERTION(0,"nsListControlFrame: Cache sync'd with content!\n");
rv = InitSelectionCache(length);
changed = PR_TRUE; // Assume the worst, there was a change.
}
@ -2016,8 +1993,8 @@ nsListControlFrame::UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate
PRBool selected;
for (PRInt32 i = 0; i < length; i++) {
selected = IsContentSelectedByIndex(i);
if (selected != mSelectionCache[i]) {
mSelectionCache[i] = selected;
if (selected != (PRBool)mSelectionCache->ElementAt(i)) {
mSelectionCache->ReplaceElementAt((void*)selected, i);
changed = PR_TRUE;
}
}
@ -2133,8 +2110,6 @@ nsListControlFrame::SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, co
ToggleSelected(selectedIndex); // sets mSelectedIndex
if (nsnull != mComboboxFrame && mIsAllFramesHere) {
mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, selectedIndex); // don't dispatch event
//} else {
//InitSelectionCache(-1);
}
}
}
@ -2939,11 +2914,11 @@ nsListControlFrame::RestoreState(nsIPresContext* aPresContext,
if (!value)
return res;
Deselect();
PRUint32 count = 0;
value->Count(&count);
mWasRestored = PR_TRUE;
nsCOMPtr<nsISupportsPRInt32> thisVal;
PRInt32 j=0;
for (PRUint32 i=0; i<count; i++) {

Просмотреть файл

@ -38,6 +38,7 @@ class nsIDOMHTMLOptionElement;
class nsIComboboxControlFrame;
class nsIViewManager;
class nsIPresContext;
class nsVoidArray;
/**
* Frame-based listbox.
@ -94,6 +95,7 @@ public:
virtual void SetFocus(PRBool aOn = PR_TRUE, PRBool aRepaint = PR_FALSE);
virtual void ScrollIntoView(nsIPresContext* aPresContext);
virtual void MouseClicked(nsIPresContext* aPresContext);
virtual void Reset(PRBool aDoSelect = PR_TRUE);
virtual void Reset(nsIPresContext* aPresContext);
virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter);
virtual PRInt32 GetMaxNumValues();
@ -220,7 +222,6 @@ protected:
PRBool IsLeftButton(nsIDOMEvent* aMouseEvent);
// onChange detection
nsresult InitSelectionCache(PRInt32 aLength);
nsresult SelectionChanged(nsIContent* aContent);
// Data Members
@ -236,12 +237,14 @@ protected:
nscoord mMaxWidth;
nscoord mMaxHeight;
PRBool mIsCapturingMouseEvents;
PRBool* mSelectionCache;
PRInt32 mSelectionCacheLength;
nsVoidArray * mSelectionCache;
PRInt32 mSelectionCacheLength;
PRBool mIsAllContentHere;
PRBool mIsAllFramesHere;
PRBool mHasBeenInitialized;
PRBool mWasRestored;
nsIPresContext* mPresContext; // XXX: Remove the need to cache the pres context.