mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-26 06:38:36 +00:00
Make onChange, reflow system in comboboxes/lists better (bug 112241). r=rods, sr=kin
This commit is contained in:
parent
a7723c632d
commit
a555e7ec64
@ -57,7 +57,7 @@
|
||||
#include "nsIDOMHTMLCollection.h"
|
||||
#include "nsIJSNativeInitializer.h"
|
||||
#include "nsISelectElement.h"
|
||||
#include "nsIComboboxControlFrame.h"
|
||||
#include "nsISelectControlFrame.h"
|
||||
|
||||
// Notify/query select frame for selected state
|
||||
#include "nsIFormControlFrame.h"
|
||||
@ -386,12 +386,12 @@ nsHTMLOptionElement::SetLabel(const nsAReadableString& aValue)
|
||||
nsIFormControlFrame* fcFrame = GetSelectFrame();
|
||||
|
||||
if (fcFrame) {
|
||||
nsIComboboxControlFrame* selectFrame = nsnull;
|
||||
nsISelectControlFrame* selectFrame = nsnull;
|
||||
|
||||
CallQueryInterface(fcFrame, &selectFrame);
|
||||
|
||||
if (selectFrame) {
|
||||
selectFrame->UpdateSelection(PR_FALSE, PR_TRUE, 0);
|
||||
selectFrame->OnOptionTextChanged(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -610,12 +610,12 @@ nsHTMLOptionElement::SetText(const nsAReadableString& aText)
|
||||
nsIFormControlFrame* fcFrame = GetSelectFrame();
|
||||
|
||||
if (fcFrame) {
|
||||
nsIComboboxControlFrame* selectFrame = nsnull;
|
||||
nsISelectControlFrame* selectFrame = nsnull;
|
||||
|
||||
CallQueryInterface(fcFrame, &selectFrame);
|
||||
|
||||
if (selectFrame) {
|
||||
selectFrame->UpdateSelection(PR_FALSE, PR_TRUE, 0);
|
||||
selectFrame->OnOptionTextChanged(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -291,7 +291,6 @@ nsComboboxControlFrame::nsComboboxControlFrame()
|
||||
mDisplayFrame = nsnull;
|
||||
mButtonFrame = nsnull;
|
||||
mDropdownFrame = nsnull;
|
||||
mSelectedIndex = -1;
|
||||
|
||||
mCacheSize.width = kSizeNotSet;
|
||||
mCacheSize.height = kSizeNotSet;
|
||||
@ -412,17 +411,15 @@ nsComboboxControlFrame::Init(nsIPresContext* aPresContext,
|
||||
void
|
||||
nsComboboxControlFrame::InitTextStr()
|
||||
{
|
||||
nsAutoString textToDisplay;
|
||||
PRInt32 selectedIndex;
|
||||
mListControlFrame->GetSelectedIndex(&selectedIndex);
|
||||
// Update the selected text string
|
||||
if (selectedIndex == -1) {
|
||||
mListControlFrame->GetOptionText(0, mTextStr);
|
||||
} else {
|
||||
mListControlFrame->GetOptionText(selectedIndex, mTextStr);
|
||||
if (selectedIndex != -1) {
|
||||
mListControlFrame->GetOptionText(selectedIndex, textToDisplay);
|
||||
}
|
||||
|
||||
// Update the display by setting the value attribute
|
||||
mDisplayContent->SetText(mTextStr.get(), mTextStr.Length(), PR_FALSE);
|
||||
mDisplayedIndex = selectedIndex;
|
||||
ActuallyDisplayText(textToDisplay, PR_FALSE);
|
||||
}
|
||||
|
||||
|
||||
@ -1848,22 +1845,6 @@ nsComboboxControlFrame::GetDropDown(nsIFrame** aDropDownFrame)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::ListWasSelected(nsIPresContext* aPresContext, PRBool aForceUpdate, PRBool aSendEvent) // Added "aForceUpdate" for Bug 42661
|
||||
{
|
||||
if (aPresContext == nsnull) {
|
||||
aPresContext = mPresContext;
|
||||
}
|
||||
ShowList(aPresContext, PR_FALSE);
|
||||
mListControlFrame->CaptureMouseEvents(aPresContext, PR_FALSE);
|
||||
|
||||
PRInt32 indx;
|
||||
mListControlFrame->GetSelectedIndex(&indx);
|
||||
|
||||
UpdateSelection(aSendEvent, aForceUpdate, indx); // Added "aForceUpdate" for Bug 42661
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
// Toggle dropdown list.
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1875,29 +1856,6 @@ nsComboboxControlFrame::ToggleList(nsIPresContext* aPresContext)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex)
|
||||
{
|
||||
if (mListControlFrame) {
|
||||
// Check to see if the selection changed
|
||||
if (mSelectedIndex != aNewIndex || aForceUpdate) {
|
||||
mListControlFrame->GetOptionText(aNewIndex, mTextStr);
|
||||
SelectionChanged();
|
||||
|
||||
// Fix for Bug 42661 (remove comment later)
|
||||
#ifdef DO_REFLOW_DEBUG
|
||||
char * str = ToNewCString(mTextStr);
|
||||
REFLOW_DEBUG_MSG2("UpdateSelection %s\n", str);
|
||||
delete [] str;
|
||||
#endif
|
||||
mSelectedIndex = aNewIndex;
|
||||
mListControlFrame->UpdateSelection();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::AbsolutelyPositionDropDown()
|
||||
{
|
||||
@ -1926,8 +1884,30 @@ nsComboboxControlFrame::GetAbsoluteRect(nsRect* aRect)
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::SelectionChanged()
|
||||
nsComboboxControlFrame::RedisplaySelectedText()
|
||||
{
|
||||
PRInt32 selectedIndex;
|
||||
mListControlFrame->GetSelectedIndex(&selectedIndex);
|
||||
|
||||
return RedisplayText(selectedIndex);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComboboxControlFrame::RedisplayText(PRInt32 aIndex)
|
||||
{
|
||||
// Get the text to display
|
||||
nsAutoString textToDisplay;
|
||||
if (aIndex != -1) {
|
||||
mListControlFrame->GetOptionText(aIndex, textToDisplay);
|
||||
}
|
||||
mDisplayedIndex = aIndex;
|
||||
|
||||
#ifdef DO_REFLOW_DEBUG
|
||||
char * str = ToNewCString(textToDisplay);
|
||||
REFLOW_DEBUG_MSG2("RedisplayText %s\n", str);
|
||||
delete [] str;
|
||||
#endif
|
||||
|
||||
// Send reflow command because the new text maybe larger
|
||||
nsresult rv = NS_OK;
|
||||
if (mDisplayContent) {
|
||||
@ -1941,16 +1921,13 @@ nsComboboxControlFrame::SelectionChanged()
|
||||
if (NS_FAILED(result) || value.Length() == 0) {
|
||||
shouldSetValue = PR_TRUE;
|
||||
} else {
|
||||
shouldSetValue = value != mTextStr;
|
||||
REFLOW_DEBUG_MSG3("**** CBX::SelectionChanged Old[%s] New[%s]\n", NS_LossyConvertUCS2toASCII(value).get(), NS_LossyConvertUCS2toASCII(mTextStr).get());
|
||||
shouldSetValue = value != textToDisplay;
|
||||
REFLOW_DEBUG_MSG3("**** CBX::RedisplayText Old[%s] New[%s]\n",
|
||||
NS_LossyConvertUCS2toASCII(value).get(),
|
||||
NS_LossyConvertUCS2toASCII(textToDisplay).get());
|
||||
}
|
||||
if (shouldSetValue) {
|
||||
if (mTextStr.Length() == 0) {
|
||||
nsAutoString space(NS_LITERAL_STRING(" "));
|
||||
rv = mDisplayContent->SetText(space.get(), space.Length(), PR_TRUE);
|
||||
} else {
|
||||
rv = mDisplayContent->SetText(mTextStr.get(), mTextStr.Length(), PR_TRUE);
|
||||
}
|
||||
rv = ActuallyDisplayText(textToDisplay, PR_TRUE);
|
||||
nsFrameState state;
|
||||
//mTextFrame->GetFrameState(&state);
|
||||
//state |= NS_FRAME_IS_DIRTY;
|
||||
@ -1970,11 +1947,26 @@ nsComboboxControlFrame::SelectionChanged()
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComboboxControlFrame::ActuallyDisplayText(nsAString& aText, PRBool aNotify)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (aText.IsEmpty()) {
|
||||
nsAutoString space(PRUnichar(' '));
|
||||
rv = mDisplayContent->SetText(space.get(), space.Length(), aNotify);
|
||||
} else {
|
||||
const nsAFlatString& flat = PromiseFlatString(aText);
|
||||
rv = mDisplayContent->SetText(flat.get(), flat.Length(), aNotify);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::GetIndexOfDisplayArea(PRInt32* aSelectedIndex)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSelectedIndex);
|
||||
*aSelectedIndex = mSelectedIndex;
|
||||
*aSelectedIndex = mDisplayedIndex;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2473,6 +2465,15 @@ nsComboboxControlFrame::Rollup()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::RollupFromList(nsIPresContext* aPresContext)
|
||||
{
|
||||
ShowList(aPresContext, PR_FALSE);
|
||||
mListControlFrame->CaptureMouseEvents(aPresContext, PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsComboboxControlFrame::Paint(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
@ -2579,13 +2580,36 @@ nsComboboxControlFrame::OnOptionSelected(nsIPresContext* aPresContext,
|
||||
PRInt32 aIndex,
|
||||
PRBool aSelected)
|
||||
{
|
||||
if (aSelected && !mDroppedDown) {
|
||||
mListControlFrame->GetOptionText(aIndex, mTextStr);
|
||||
SelectionChanged();
|
||||
if (aSelected) {
|
||||
if (!mDroppedDown) {
|
||||
RedisplayText(aIndex);
|
||||
} else {
|
||||
nsCOMPtr<nsISelectControlFrame> selectFrame
|
||||
= do_QueryInterface(mListControlFrame);
|
||||
if (selectFrame) {
|
||||
selectFrame->OnOptionSelected(aPresContext, aIndex, aSelected);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::OnOptionTextChanged(nsIDOMHTMLOptionElement* option)
|
||||
{
|
||||
RedisplaySelectedText();
|
||||
if (mDroppedDown) {
|
||||
nsCOMPtr<nsISelectControlFrame> selectFrame
|
||||
= do_QueryInterface(mListControlFrame);
|
||||
if (selectFrame) {
|
||||
selectFrame->OnOptionTextChanged(option);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::OnContentReset()
|
||||
{
|
||||
|
@ -169,10 +169,6 @@ public:
|
||||
nscoord aCharWidth) const;
|
||||
virtual nsresult RequiresWidget(PRBool &aRequiresWidget);
|
||||
|
||||
NS_IMETHOD SelectionChanged();// Called when the selection has changed.
|
||||
// If the the same item in the list is selected
|
||||
// it is NOT called.
|
||||
|
||||
// nsIFormMouseListener
|
||||
virtual void MouseClicked(nsIPresContext* aPresContext);
|
||||
|
||||
@ -181,11 +177,11 @@ public:
|
||||
NS_IMETHOD ShowDropDown(PRBool aDoDropDown);
|
||||
NS_IMETHOD GetDropDown(nsIFrame** aDropDownFrame);
|
||||
NS_IMETHOD SetDropDown(nsIFrame* aDropDownFrame);
|
||||
NS_IMETHOD ListWasSelected(nsIPresContext* aPresContext, PRBool aForceUpdate, PRBool aSendEvent);
|
||||
NS_IMETHOD UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex);
|
||||
NS_IMETHOD RollupFromList(nsIPresContext* aPresContext);
|
||||
NS_IMETHOD AbsolutelyPositionDropDown();
|
||||
NS_IMETHOD GetAbsoluteRect(nsRect* aRect);
|
||||
NS_IMETHOD GetIndexOfDisplayArea(PRInt32* aSelectedIndex);
|
||||
NS_IMETHOD RedisplaySelectedText();
|
||||
|
||||
// nsISelectControlFrame
|
||||
NS_IMETHOD AddOption(nsIPresContext* aPresContext, PRInt32 index);
|
||||
@ -195,6 +191,7 @@ public:
|
||||
NS_IMETHOD OnOptionSelected(nsIPresContext* aPresContext,
|
||||
PRInt32 aIndex,
|
||||
PRBool aSelected);
|
||||
NS_IMETHOD OnOptionTextChanged(nsIDOMHTMLOptionElement* option);
|
||||
NS_IMETHOD GetDummyFrame(nsIFrame** aFrame);
|
||||
NS_IMETHOD SetDummyFrame(nsIFrame* aFrame);
|
||||
|
||||
@ -223,6 +220,7 @@ public:
|
||||
NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState);
|
||||
|
||||
protected:
|
||||
|
||||
NS_IMETHOD CreateDisplayFrame(nsIPresContext* aPresContext);
|
||||
|
||||
#ifdef DO_NEW_REFLOW
|
||||
@ -253,6 +251,8 @@ protected:
|
||||
void ShowList(nsIPresContext* aPresContext, PRBool aShowList);
|
||||
void SetChildFrameSize(nsIFrame* aFrame, nscoord aWidth, nscoord aHeight);
|
||||
void InitTextStr();
|
||||
nsresult RedisplayText(PRInt32 aIndex);
|
||||
nsresult ActuallyDisplayText(nsAString& aText, PRBool aNotify);
|
||||
nsresult GetPrimaryComboFrame(nsIPresContext* aPresContext, nsIContent* aContent, nsIFrame** aFrame);
|
||||
NS_IMETHOD ToggleList(nsIPresContext* aPresContext);
|
||||
|
||||
@ -271,8 +271,6 @@ protected:
|
||||
nsFrameList mPopupFrames; // additional named child list
|
||||
nsIPresContext* mPresContext; // XXX: Remove the need to cache the pres context.
|
||||
nsFormFrame* mFormFrame; // Parent Form Frame
|
||||
nsString mTextStr; // Current Combo box selection
|
||||
PRInt32 mSelectedIndex; // current selected index
|
||||
nsCOMPtr<nsITextContent> mDisplayContent; // Anonymous content used to display the current selection
|
||||
PRPackedBool mDroppedDown; // Current state of the dropdown list, PR_TRUE is dropped down
|
||||
nsIFrame* mDisplayFrame; // frame to display selection
|
||||
@ -295,6 +293,8 @@ protected:
|
||||
|
||||
PRPackedBool mGoodToGo;
|
||||
|
||||
PRInt32 mDisplayedIndex;
|
||||
|
||||
// make someone to listen to the button. If its programmatically pressed by someone like Accessibility
|
||||
// then open or close the combo box.
|
||||
nsCOMPtr<nsIDOMMouseListener> mButtonListener;
|
||||
|
@ -89,26 +89,15 @@ public:
|
||||
NS_IMETHOD SetDropDown(nsIFrame* aDropDownFrame) = 0;
|
||||
|
||||
/**
|
||||
* Notifies the Combobox the List was selected
|
||||
* Tells the combobox to roll up
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD ListWasSelected(nsIPresContext* aPresContext, PRBool aForceUpdate, PRBool aSendEvent) = 0;
|
||||
NS_IMETHOD RollupFromList(nsIPresContext* aPresContext) = 0;
|
||||
|
||||
/**
|
||||
* Asks the Combobox to update the display frame
|
||||
* aDoDispatchEvent - indicates whether an event should be dispatched to the DOM
|
||||
* aForceUpdate - indicates whether the indexx and the text value should both be
|
||||
* whether the index has changed or not.
|
||||
*
|
||||
* Redisplay the selected text (will do nothing if text has not changed)
|
||||
*/
|
||||
NS_IMETHOD UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex) = 0;
|
||||
|
||||
/**
|
||||
* Asks the Combobox to update the display frame when the selection has
|
||||
* changed
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD SelectionChanged() = 0;
|
||||
NS_IMETHOD RedisplaySelectedText() = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -46,6 +46,8 @@
|
||||
{ 0x96, 0xea, 0x0, 0x60, 0xb0, 0xfb, 0x99, 0x56 } }
|
||||
// {162A2AE3-5A79-11d3-96EA-0060B0FB9956}
|
||||
|
||||
class nsIDOMHTMLOptionElement;
|
||||
|
||||
/**
|
||||
* nsISelectControlFrame is the interface for combo boxes and listboxes
|
||||
*/
|
||||
@ -83,6 +85,13 @@ public:
|
||||
PRInt32 aIndex,
|
||||
PRBool aSelected) = 0;
|
||||
|
||||
/**
|
||||
* Notify the frame when an option's text changes
|
||||
* (We don't pass in the index because it would be expensive for
|
||||
* the option to figure that out)
|
||||
*/
|
||||
NS_IMETHOD OnOptionTextChanged(nsIDOMHTMLOptionElement* option) = 0;
|
||||
|
||||
/**
|
||||
* For the content model to tell if there's a dummy frame or not
|
||||
*/
|
||||
|
@ -1234,37 +1234,41 @@ nsListControlFrame::GetIndexFromContent(nsIContent *aContent)
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
void
|
||||
PRBool
|
||||
nsListControlFrame::ExtendedSelection(PRInt32 aStartIndex,
|
||||
PRInt32 aEndIndex,
|
||||
PRBool aClearAll)
|
||||
{
|
||||
SetOptionsSelectedFromFrame(aStartIndex, aEndIndex, PR_TRUE, aClearAll);
|
||||
return SetOptionsSelectedFromFrame(aStartIndex, aEndIndex,
|
||||
PR_TRUE, aClearAll);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
void
|
||||
PRBool
|
||||
nsListControlFrame::SingleSelection(PRInt32 aSelectedIndex, PRBool aDoToggle)
|
||||
{
|
||||
PRBool wasChanged = PR_FALSE;
|
||||
// Get Current selection
|
||||
if (aDoToggle) {
|
||||
ToggleOptionSelectedFromFrame(aSelectedIndex);
|
||||
wasChanged = ToggleOptionSelectedFromFrame(aSelectedIndex);
|
||||
} else {
|
||||
SetOptionsSelectedFromFrame(aSelectedIndex, aSelectedIndex,
|
||||
wasChanged = SetOptionsSelectedFromFrame(aSelectedIndex, aSelectedIndex,
|
||||
PR_TRUE, PR_TRUE);
|
||||
}
|
||||
ScrollToIndex(aSelectedIndex);
|
||||
mStartSelectionIndex = aSelectedIndex;
|
||||
mEndSelectionIndex = aSelectedIndex;
|
||||
mChangesNotNotified = PR_TRUE;
|
||||
return wasChanged;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
void
|
||||
PRBool
|
||||
nsListControlFrame::PerformSelection(PRInt32 aSelectedIndex,
|
||||
PRBool aIsShift,
|
||||
PRBool aIsControl)
|
||||
{
|
||||
PRBool wasChanged = PR_FALSE;
|
||||
|
||||
PRBool isMultiple;
|
||||
GetMultiple(&isMultiple);
|
||||
|
||||
@ -1286,7 +1290,7 @@ nsListControlFrame::PerformSelection(PRInt32 aSelectedIndex,
|
||||
endIndex = mStartSelectionIndex;
|
||||
}
|
||||
|
||||
ExtendedSelection(startIndex, endIndex, PR_TRUE);
|
||||
wasChanged = ExtendedSelection(startIndex, endIndex, PR_TRUE);
|
||||
ScrollToIndex(aSelectedIndex);
|
||||
|
||||
if (mStartSelectionIndex == kNothingSelected) {
|
||||
@ -1295,14 +1299,13 @@ nsListControlFrame::PerformSelection(PRInt32 aSelectedIndex,
|
||||
} else {
|
||||
mEndSelectionIndex = aSelectedIndex;
|
||||
}
|
||||
mChangesNotNotified = PR_TRUE;
|
||||
} else if (aIsControl) {
|
||||
SingleSelection(aSelectedIndex, PR_TRUE);
|
||||
wasChanged = SingleSelection(aSelectedIndex, PR_TRUE);
|
||||
} else {
|
||||
SingleSelection(aSelectedIndex, PR_FALSE);
|
||||
wasChanged = SingleSelection(aSelectedIndex, PR_FALSE);
|
||||
}
|
||||
} else {
|
||||
SingleSelection(aSelectedIndex, PR_FALSE);
|
||||
wasChanged = SingleSelection(aSelectedIndex, PR_FALSE);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_rodsX
|
||||
@ -1311,10 +1314,12 @@ nsListControlFrame::PerformSelection(PRInt32 aSelectedIndex,
|
||||
printf("mLastStartIndex: %d\n", mLastStartIndex);
|
||||
printf("mLastEndIndex: %d\n", mLastEndIndex);
|
||||
#endif
|
||||
|
||||
return wasChanged;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
void
|
||||
PRBool
|
||||
nsListControlFrame::HandleListSelection(nsIDOMEvent* aEvent,
|
||||
PRInt32 aSelectedIndex)
|
||||
{
|
||||
@ -1327,7 +1332,7 @@ nsListControlFrame::HandleListSelection(nsIDOMEvent* aEvent,
|
||||
mouseEvent->GetCtrlKey(&isControl);
|
||||
#endif
|
||||
mouseEvent->GetShiftKey(&isShift);
|
||||
PerformSelection(aSelectedIndex, isShift, isControl);
|
||||
return PerformSelection(aSelectedIndex, isShift, isControl);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
@ -1518,7 +1523,6 @@ nsListControlFrame::Init(nsIPresContext* aPresContext,
|
||||
|
||||
mStartSelectionIndex = kNothingSelected;
|
||||
mEndSelectionIndex = kNothingSelected;
|
||||
mChangesNotNotified = PR_FALSE;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1711,6 +1715,12 @@ nsListControlFrame::OnOptionSelected(nsIPresContext* aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsListControlFrame::OnOptionTextChanged(nsIDOMHTMLOptionElement* option)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
PRIntn
|
||||
@ -1777,13 +1787,8 @@ nsListControlFrame::ResetList(nsIPresContext* aPresContext, nsVoidArray * aInxLi
|
||||
|
||||
mStartSelectionIndex = kNothingSelected;
|
||||
mEndSelectionIndex = kNothingSelected;
|
||||
mChangesNotNotified = PR_FALSE;
|
||||
|
||||
if (mComboboxFrame != nsnull) {
|
||||
// don't dispatch event
|
||||
mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, indexToSelect);
|
||||
}
|
||||
|
||||
// Combobox will redisplay itself with the OnOptionSelected event
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
@ -2030,7 +2035,7 @@ nsListControlFrame::RemoveOption(nsIPresContext* aPresContext, PRInt32 aIndex)
|
||||
// Set the option selected in the DOM. This method is named
|
||||
// as it is because it indicates that the frame is the source
|
||||
// of this event rather than the receiver.
|
||||
nsresult
|
||||
PRBool
|
||||
nsListControlFrame::SetOptionsSelectedFromFrame(PRInt32 aStartIndex,
|
||||
PRInt32 aEndIndex,
|
||||
PRBool aValue,
|
||||
@ -2046,25 +2051,22 @@ nsListControlFrame::SetOptionsSelectedFromFrame(PRInt32 aStartIndex,
|
||||
PR_TRUE,
|
||||
&wasChanged);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "SetSelected failed");
|
||||
if (NS_SUCCEEDED(rv) && !mChangesNotNotified && wasChanged) {
|
||||
mChangesNotNotified = PR_TRUE;
|
||||
}
|
||||
return rv;
|
||||
return wasChanged;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PRBool
|
||||
nsListControlFrame::ToggleOptionSelectedFromFrame(PRInt32 aIndex)
|
||||
{
|
||||
nsCOMPtr<nsIDOMHTMLCollection> options(getter_AddRefs(GetOptions(mContent)));
|
||||
NS_ASSERTION(options, "No options");
|
||||
if (!options) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
nsCOMPtr<nsIDOMHTMLOptionElement> option(
|
||||
getter_AddRefs(GetOption(*options, aIndex)));
|
||||
NS_ASSERTION(option, "No option");
|
||||
if (!option) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool value = PR_FALSE;
|
||||
@ -2082,11 +2084,8 @@ nsListControlFrame::ToggleOptionSelectedFromFrame(PRInt32 aIndex)
|
||||
&wasChanged);
|
||||
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "SetSelected failed");
|
||||
if (wasChanged) {
|
||||
mChangesNotNotified = PR_TRUE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
return wasChanged;
|
||||
}
|
||||
|
||||
|
||||
@ -2094,7 +2093,7 @@ nsListControlFrame::ToggleOptionSelectedFromFrame(PRInt32 aIndex)
|
||||
NS_IMETHODIMP
|
||||
nsListControlFrame::UpdateSelection()
|
||||
{
|
||||
if (!mIsAllFramesHere || !mIsAllContentHere || !mChangesNotNotified) {
|
||||
if (!mIsAllFramesHere || !mIsAllContentHere) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult rv = NS_OK;
|
||||
@ -2104,23 +2103,30 @@ nsListControlFrame::UpdateSelection()
|
||||
mComboboxFrame->IsDroppedDown(&isDroppedDown);
|
||||
}
|
||||
if (!isDroppedDown) {
|
||||
rv = SelectionChanged(); // Dispatch event
|
||||
mChangesNotNotified = PR_FALSE;
|
||||
rv = FireOnChange(); // Dispatch event
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsListControlFrame::ComboboxUpdateSelection(PRBool aForceUpdate,
|
||||
PRBool aSendEvent)
|
||||
void
|
||||
nsListControlFrame::ComboboxFinish(PRInt32 aIndex)
|
||||
{
|
||||
if (mComboboxFrame) {
|
||||
mComboboxFrame->ListWasSelected(mPresContext, aForceUpdate, aSendEvent);
|
||||
}
|
||||
mChangesNotNotified = PR_FALSE;
|
||||
PerformSelection(aIndex, PR_FALSE, PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
PRInt32 displayIndex;
|
||||
mComboboxFrame->GetIndexOfDisplayArea(&displayIndex);
|
||||
|
||||
if (displayIndex != aIndex) {
|
||||
mComboboxFrame->RedisplaySelectedText();
|
||||
}
|
||||
|
||||
mComboboxFrame->RollupFromList(mPresContext);
|
||||
if (aIndex != mSelectedIndexWhenPoppedDown) {
|
||||
FireOnChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -2132,7 +2138,7 @@ nsListControlFrame::GetOptionsContainer(nsIPresContext* aPresContext,
|
||||
|
||||
// Send out an onchange notification.
|
||||
nsresult
|
||||
nsListControlFrame::SelectionChanged()
|
||||
nsListControlFrame::FireOnChange()
|
||||
{
|
||||
nsresult ret = NS_ERROR_FAILURE;
|
||||
|
||||
@ -2353,31 +2359,21 @@ nsListControlFrame::AboutToDropDown()
|
||||
NS_IMETHODIMP
|
||||
nsListControlFrame::AboutToRollup()
|
||||
{
|
||||
// XXX To have clicking outside the combobox ALWAYS reset the contents to the
|
||||
// state before it was dropped, remove the all the code in the "if" below and replace it
|
||||
// with just the call to ResetSelectedItem()
|
||||
// We've been updating the combobox with the keyboard up until now, but not
|
||||
// with the mouse. The problem is, even with mouse selection, we are
|
||||
// updating the <select>. So if the mouse goes over an option just before
|
||||
// he leaves the box and clicks, that's what the <select> will show.
|
||||
//
|
||||
//
|
||||
// When the dropdown is dropped down via a mouse click and the user moves the mouse
|
||||
// up and down without clicking, the currently selected item is being tracking inside
|
||||
// the dropdown, but the combobox is not being updated. When the user selects items
|
||||
// with the arrow keys, the combobox is being updated. So when the user clicks outside
|
||||
// the dropdown and it needs to roll up it has to decide whether to keep the current
|
||||
// selection or not. The GetIndexOfDisplayArea method is used to get the current index
|
||||
// in the combobox to compare it to the current index in the dropdown to see if the combox
|
||||
// has been updated and that way it knows whether to "cancel" the the current selection
|
||||
// residing in the dropdown. Or whether to leave the selection alone.
|
||||
// To deal with this we say "whatever is in the combobox is canonical."
|
||||
// - IF the combobox is different from the current selected index, we
|
||||
// reset the index.
|
||||
// - IF the combobox is different from the index when it was popped down,
|
||||
// we fire onChange() since it has changed.
|
||||
|
||||
if (IsInDropDownMode() == PR_TRUE) {
|
||||
PRInt32 index;
|
||||
mComboboxFrame->GetIndexOfDisplayArea(&index);
|
||||
// if the indexes do NOT match then the selection in the combobox
|
||||
// was never updated, and therefore we should reset the the selection back to
|
||||
// whatever it was before it was dropped down.
|
||||
if (index != mStartSelectionIndex) {
|
||||
ResetSelectedItem();
|
||||
} else {
|
||||
ComboboxUpdateSelection(PR_FALSE, PR_TRUE);
|
||||
}
|
||||
ComboboxFinish(index);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2500,21 +2496,6 @@ nsListControlFrame::IsOptionDisabled(PRInt32 anIndex, PRBool &aIsDisabled)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 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()
|
||||
{
|
||||
if (mIsAllFramesHere) {
|
||||
SingleSelection(mSelectedIndexWhenPoppedDown, PR_FALSE);
|
||||
// We're resetting ... don't send OnChange
|
||||
mChangesNotNotified = PR_FALSE;
|
||||
if (IsInDropDownMode() == PR_TRUE) {
|
||||
ComboboxUpdateSelection(PR_TRUE, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// helper
|
||||
//----------------------------------------------------------------------
|
||||
@ -2619,11 +2600,9 @@ nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent)
|
||||
}
|
||||
|
||||
if (kNothingSelected != selectedIndex) {
|
||||
if (!mChangesNotNotified) {
|
||||
ResetSelectedItem();
|
||||
}
|
||||
ComboboxFinish(selectedIndex);
|
||||
}
|
||||
ComboboxUpdateSelection(PR_TRUE, PR_TRUE);
|
||||
|
||||
mouseEvent->clickCount = 1;
|
||||
} else {
|
||||
// the click was out side of the select or its dropdown
|
||||
@ -2633,7 +2612,9 @@ nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent)
|
||||
REFLOW_DEBUG_MSG(">>>>>> Didn't find");
|
||||
CaptureMouseEvents(mPresContext, PR_FALSE);
|
||||
// Notify
|
||||
UpdateSelection();
|
||||
if (mChangesSinceDragStart) {
|
||||
UpdateSelection();
|
||||
}
|
||||
#if 0 // XXX - this is a partial fix for Bug 29990
|
||||
if (mSelectedIndex != mStartExtendedIndex) {
|
||||
mEndExtendedIndex = mSelectedIndex;
|
||||
@ -2761,7 +2742,7 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
|
||||
if (!IsInDropDownMode()) {
|
||||
// Handle Like List
|
||||
CaptureMouseEvents(mPresContext, PR_TRUE);
|
||||
HandleListSelection(aMouseEvent, selectedIndex);
|
||||
mChangesSinceDragStart = HandleListSelection(aMouseEvent, selectedIndex);
|
||||
}
|
||||
} else {
|
||||
// NOTE: the combo box is responsible for dropping it down
|
||||
@ -2792,7 +2773,6 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
|
||||
if (isDroppedDown) {
|
||||
CaptureMouseEvents(mPresContext, PR_FALSE);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2848,7 +2828,9 @@ nsListControlFrame::DragMove(nsIDOMEvent* aMouseEvent)
|
||||
mouseEvent->GetCtrlKey(&isControl);
|
||||
#endif
|
||||
// Turn SHIFT on when you are dragging, unless control is on.
|
||||
PerformSelection(selectedIndex, !isControl, isControl);
|
||||
PRBool wasChanged = PerformSelection(selectedIndex,
|
||||
!isControl, isControl);
|
||||
mChangesSinceDragStart = mChangesSinceDragStart || wasChanged;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
@ -3172,20 +3154,21 @@ nsListControlFrame::KeyPress(nsIDOMEvent* aKeyEvent)
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_RETURN: {
|
||||
if (mComboboxFrame != nsnull) {
|
||||
if (IsInDropDownMode() == PR_TRUE) {
|
||||
PRBool isDroppedDown;
|
||||
mComboboxFrame->IsDroppedDown(&isDroppedDown);
|
||||
ComboboxUpdateSelection(isDroppedDown, PR_TRUE);
|
||||
} else {
|
||||
UpdateSelection();
|
||||
PRBool droppedDown = PR_FALSE;
|
||||
mComboboxFrame->IsDroppedDown(&droppedDown);
|
||||
if (droppedDown) {
|
||||
ComboboxFinish(mEndSelectionIndex);
|
||||
}
|
||||
return NS_OK;
|
||||
} else {
|
||||
newIndex = mEndSelectionIndex;
|
||||
}
|
||||
} break;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_ESCAPE: {
|
||||
if (IsInDropDownMode() == PR_TRUE) {
|
||||
ResetSelectedItem();
|
||||
}
|
||||
ComboboxFinish(mSelectedIndexWhenPoppedDown);
|
||||
}
|
||||
} break;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_PAGE_UP: {
|
||||
@ -3242,13 +3225,14 @@ nsListControlFrame::KeyPress(nsIDOMEvent* aKeyEvent)
|
||||
ToLowerCase(text);
|
||||
PRUnichar firstChar = text.CharAt(0);
|
||||
if (firstChar == (PRUnichar)code) {
|
||||
PerformSelection(selectedIndex, isShift, isControl);
|
||||
PRBool wasChanged = PerformSelection(selectedIndex,
|
||||
isShift, isControl);
|
||||
// If it's a combobox, redisplay the text
|
||||
if (mComboboxFrame && mIsAllFramesHere) {
|
||||
// dispatch event
|
||||
mComboboxFrame->UpdateSelection(PR_TRUE,
|
||||
PR_TRUE,
|
||||
selectedIndex);
|
||||
} else {
|
||||
mComboboxFrame->RedisplaySelectedText();
|
||||
}
|
||||
// Fire the event (unless it's a dropped down combobox)
|
||||
if (wasChanged) {
|
||||
UpdateSelection(); // dispatch event
|
||||
}
|
||||
break;
|
||||
@ -3274,11 +3258,13 @@ nsListControlFrame::KeyPress(nsIDOMEvent* aKeyEvent)
|
||||
mEndSelectionIndex = newIndex;
|
||||
ScrollToIndex(newIndex);
|
||||
} else {
|
||||
PerformSelection(newIndex, isShift, isControl);
|
||||
// Dispatch event
|
||||
PRBool wasChanged = PerformSelection(newIndex, isShift, isControl);
|
||||
// If combobox, redisplay selected text.
|
||||
if (mComboboxFrame && mIsAllFramesHere) {
|
||||
mComboboxFrame->UpdateSelection(PR_TRUE, PR_FALSE, newIndex);
|
||||
} else {
|
||||
mComboboxFrame->RedisplaySelectedText();
|
||||
}
|
||||
// Fire the event (unless it's a dropped down combobox)
|
||||
if (wasChanged) {
|
||||
UpdateSelection();
|
||||
}
|
||||
}
|
||||
|
@ -274,7 +274,6 @@ public:
|
||||
NS_IMETHOD AboutToDropDown();
|
||||
NS_IMETHOD AboutToRollup();
|
||||
NS_IMETHOD UpdateSelection();
|
||||
NS_IMETHOD ComboboxUpdateSelection(PRBool aForceUpdate, PRBool aSendEvent);
|
||||
NS_IMETHOD SetOverrideReflowOptimization(PRBool aValue) { mOverrideReflowOpt = aValue; return NS_OK; }
|
||||
NS_IMETHOD GetOptionsContainer(nsIPresContext* aPresContext, nsIFrame** aFrame);
|
||||
|
||||
@ -286,6 +285,7 @@ public:
|
||||
NS_IMETHOD OnOptionSelected(nsIPresContext* aPresContext,
|
||||
PRInt32 aIndex,
|
||||
PRBool aSelected);
|
||||
NS_IMETHOD OnOptionTextChanged(nsIDOMHTMLOptionElement* option);
|
||||
NS_IMETHOD GetDummyFrame(nsIFrame** aFrame);
|
||||
NS_IMETHOD SetDummyFrame(nsIFrame* aFrame);
|
||||
|
||||
@ -352,41 +352,46 @@ protected:
|
||||
PRBool IsContentSelected(nsIContent* aContent);
|
||||
PRBool IsContentSelectedByIndex(PRInt32 aIndex);
|
||||
void GetViewOffset(nsIViewManager* aManager, nsIView* aView, nsPoint& aPoint);
|
||||
PRBool IsInDropDownMode();
|
||||
PRBool IsOptionElement(nsIContent* aContent);
|
||||
void SingleSelection(PRInt32 aSelectedIndex, PRBool aDoToggle);
|
||||
void ExtendedSelection(PRInt32 aStartIndex,
|
||||
PRInt32 aEndIndex,
|
||||
PRBool aClearAll);
|
||||
void PerformSelection(PRInt32 aSelectedIndex,
|
||||
PRBool aIsShift,
|
||||
PRBool aIsControl);
|
||||
void ResetSelectedItem();
|
||||
PRBool CheckIfAllFramesHere();
|
||||
PRInt32 GetIndexFromContent(nsIContent *aContent);
|
||||
void HandleListSelection(nsIDOMEvent * aDOMEvent, PRInt32 selectedIndex);
|
||||
PRBool IsLeftButton(nsIDOMEvent* aMouseEvent);
|
||||
nsresult SetOptionsSelectedFromFrame(PRInt32 aStartIndex,
|
||||
PRInt32 aEndIndex,
|
||||
PRBool aValue,
|
||||
PRBool aClearAll);
|
||||
nsresult ToggleOptionSelectedFromFrame(PRInt32 aIndex);
|
||||
void GetScrollableView(nsIScrollableView*& aScrollableView);
|
||||
|
||||
// Dropped down stuff
|
||||
void SetComboboxItem(PRInt32 aIndex);
|
||||
void ComboboxFinish(PRInt32 aIndex);
|
||||
PRBool IsInDropDownMode();
|
||||
|
||||
// Selection
|
||||
PRBool SetOptionsSelectedFromFrame(PRInt32 aStartIndex,
|
||||
PRInt32 aEndIndex,
|
||||
PRBool aValue,
|
||||
PRBool aClearAll);
|
||||
PRBool ToggleOptionSelectedFromFrame(PRInt32 aIndex);
|
||||
PRBool SingleSelection(PRInt32 aSelectedIndex, PRBool aDoToggle);
|
||||
PRBool ExtendedSelection(PRInt32 aStartIndex,
|
||||
PRInt32 aEndIndex,
|
||||
PRBool aClearAll);
|
||||
PRBool PerformSelection(PRInt32 aSelectedIndex,
|
||||
PRBool aIsShift,
|
||||
PRBool aIsControl);
|
||||
PRBool HandleListSelection(nsIDOMEvent * aDOMEvent, PRInt32 selectedIndex);
|
||||
|
||||
// Timer Methods
|
||||
nsresult StartUpdateTimer(nsIPresContext * aPresContext);
|
||||
void StopUpdateTimer();
|
||||
void ItemsHaveBeenRemoved(nsIPresContext * aPresContext);
|
||||
|
||||
// onChange detection
|
||||
nsresult SelectionChanged();
|
||||
// fire onChange
|
||||
nsresult FireOnChange();
|
||||
|
||||
// Data Members
|
||||
nsFormFrame* mFormFrame;
|
||||
|
||||
PRInt32 mStartSelectionIndex;
|
||||
PRInt32 mEndSelectionIndex;
|
||||
PRBool mChangesNotNotified;
|
||||
PRPackedBool mChangesSinceDragStart;
|
||||
|
||||
PRInt32 mSelectedIndexWhenPoppedDown;
|
||||
nsIComboboxControlFrame *mComboboxFrame;
|
||||
|
@ -89,26 +89,15 @@ public:
|
||||
NS_IMETHOD SetDropDown(nsIFrame* aDropDownFrame) = 0;
|
||||
|
||||
/**
|
||||
* Notifies the Combobox the List was selected
|
||||
* Tells the combobox to roll up
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD ListWasSelected(nsIPresContext* aPresContext, PRBool aForceUpdate, PRBool aSendEvent) = 0;
|
||||
NS_IMETHOD RollupFromList(nsIPresContext* aPresContext) = 0;
|
||||
|
||||
/**
|
||||
* Asks the Combobox to update the display frame
|
||||
* aDoDispatchEvent - indicates whether an event should be dispatched to the DOM
|
||||
* aForceUpdate - indicates whether the indexx and the text value should both be
|
||||
* whether the index has changed or not.
|
||||
*
|
||||
* Redisplay the selected text (will do nothing if text has not changed)
|
||||
*/
|
||||
NS_IMETHOD UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex) = 0;
|
||||
|
||||
/**
|
||||
* Asks the Combobox to update the display frame when the selection has
|
||||
* changed
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD SelectionChanged() = 0;
|
||||
NS_IMETHOD RedisplaySelectedText() = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -46,6 +46,8 @@
|
||||
{ 0x96, 0xea, 0x0, 0x60, 0xb0, 0xfb, 0x99, 0x56 } }
|
||||
// {162A2AE3-5A79-11d3-96EA-0060B0FB9956}
|
||||
|
||||
class nsIDOMHTMLOptionElement;
|
||||
|
||||
/**
|
||||
* nsISelectControlFrame is the interface for combo boxes and listboxes
|
||||
*/
|
||||
@ -83,6 +85,13 @@ public:
|
||||
PRInt32 aIndex,
|
||||
PRBool aSelected) = 0;
|
||||
|
||||
/**
|
||||
* Notify the frame when an option's text changes
|
||||
* (We don't pass in the index because it would be expensive for
|
||||
* the option to figure that out)
|
||||
*/
|
||||
NS_IMETHOD OnOptionTextChanged(nsIDOMHTMLOptionElement* option) = 0;
|
||||
|
||||
/**
|
||||
* For the content model to tell if there's a dummy frame or not
|
||||
*/
|
||||
|
@ -291,7 +291,6 @@ nsComboboxControlFrame::nsComboboxControlFrame()
|
||||
mDisplayFrame = nsnull;
|
||||
mButtonFrame = nsnull;
|
||||
mDropdownFrame = nsnull;
|
||||
mSelectedIndex = -1;
|
||||
|
||||
mCacheSize.width = kSizeNotSet;
|
||||
mCacheSize.height = kSizeNotSet;
|
||||
@ -412,17 +411,15 @@ nsComboboxControlFrame::Init(nsIPresContext* aPresContext,
|
||||
void
|
||||
nsComboboxControlFrame::InitTextStr()
|
||||
{
|
||||
nsAutoString textToDisplay;
|
||||
PRInt32 selectedIndex;
|
||||
mListControlFrame->GetSelectedIndex(&selectedIndex);
|
||||
// Update the selected text string
|
||||
if (selectedIndex == -1) {
|
||||
mListControlFrame->GetOptionText(0, mTextStr);
|
||||
} else {
|
||||
mListControlFrame->GetOptionText(selectedIndex, mTextStr);
|
||||
if (selectedIndex != -1) {
|
||||
mListControlFrame->GetOptionText(selectedIndex, textToDisplay);
|
||||
}
|
||||
|
||||
// Update the display by setting the value attribute
|
||||
mDisplayContent->SetText(mTextStr.get(), mTextStr.Length(), PR_FALSE);
|
||||
mDisplayedIndex = selectedIndex;
|
||||
ActuallyDisplayText(textToDisplay, PR_FALSE);
|
||||
}
|
||||
|
||||
|
||||
@ -1848,22 +1845,6 @@ nsComboboxControlFrame::GetDropDown(nsIFrame** aDropDownFrame)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::ListWasSelected(nsIPresContext* aPresContext, PRBool aForceUpdate, PRBool aSendEvent) // Added "aForceUpdate" for Bug 42661
|
||||
{
|
||||
if (aPresContext == nsnull) {
|
||||
aPresContext = mPresContext;
|
||||
}
|
||||
ShowList(aPresContext, PR_FALSE);
|
||||
mListControlFrame->CaptureMouseEvents(aPresContext, PR_FALSE);
|
||||
|
||||
PRInt32 indx;
|
||||
mListControlFrame->GetSelectedIndex(&indx);
|
||||
|
||||
UpdateSelection(aSendEvent, aForceUpdate, indx); // Added "aForceUpdate" for Bug 42661
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
// Toggle dropdown list.
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1875,29 +1856,6 @@ nsComboboxControlFrame::ToggleList(nsIPresContext* aPresContext)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex)
|
||||
{
|
||||
if (mListControlFrame) {
|
||||
// Check to see if the selection changed
|
||||
if (mSelectedIndex != aNewIndex || aForceUpdate) {
|
||||
mListControlFrame->GetOptionText(aNewIndex, mTextStr);
|
||||
SelectionChanged();
|
||||
|
||||
// Fix for Bug 42661 (remove comment later)
|
||||
#ifdef DO_REFLOW_DEBUG
|
||||
char * str = ToNewCString(mTextStr);
|
||||
REFLOW_DEBUG_MSG2("UpdateSelection %s\n", str);
|
||||
delete [] str;
|
||||
#endif
|
||||
mSelectedIndex = aNewIndex;
|
||||
mListControlFrame->UpdateSelection();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::AbsolutelyPositionDropDown()
|
||||
{
|
||||
@ -1926,8 +1884,30 @@ nsComboboxControlFrame::GetAbsoluteRect(nsRect* aRect)
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::SelectionChanged()
|
||||
nsComboboxControlFrame::RedisplaySelectedText()
|
||||
{
|
||||
PRInt32 selectedIndex;
|
||||
mListControlFrame->GetSelectedIndex(&selectedIndex);
|
||||
|
||||
return RedisplayText(selectedIndex);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComboboxControlFrame::RedisplayText(PRInt32 aIndex)
|
||||
{
|
||||
// Get the text to display
|
||||
nsAutoString textToDisplay;
|
||||
if (aIndex != -1) {
|
||||
mListControlFrame->GetOptionText(aIndex, textToDisplay);
|
||||
}
|
||||
mDisplayedIndex = aIndex;
|
||||
|
||||
#ifdef DO_REFLOW_DEBUG
|
||||
char * str = ToNewCString(textToDisplay);
|
||||
REFLOW_DEBUG_MSG2("RedisplayText %s\n", str);
|
||||
delete [] str;
|
||||
#endif
|
||||
|
||||
// Send reflow command because the new text maybe larger
|
||||
nsresult rv = NS_OK;
|
||||
if (mDisplayContent) {
|
||||
@ -1941,16 +1921,13 @@ nsComboboxControlFrame::SelectionChanged()
|
||||
if (NS_FAILED(result) || value.Length() == 0) {
|
||||
shouldSetValue = PR_TRUE;
|
||||
} else {
|
||||
shouldSetValue = value != mTextStr;
|
||||
REFLOW_DEBUG_MSG3("**** CBX::SelectionChanged Old[%s] New[%s]\n", NS_LossyConvertUCS2toASCII(value).get(), NS_LossyConvertUCS2toASCII(mTextStr).get());
|
||||
shouldSetValue = value != textToDisplay;
|
||||
REFLOW_DEBUG_MSG3("**** CBX::RedisplayText Old[%s] New[%s]\n",
|
||||
NS_LossyConvertUCS2toASCII(value).get(),
|
||||
NS_LossyConvertUCS2toASCII(textToDisplay).get());
|
||||
}
|
||||
if (shouldSetValue) {
|
||||
if (mTextStr.Length() == 0) {
|
||||
nsAutoString space(NS_LITERAL_STRING(" "));
|
||||
rv = mDisplayContent->SetText(space.get(), space.Length(), PR_TRUE);
|
||||
} else {
|
||||
rv = mDisplayContent->SetText(mTextStr.get(), mTextStr.Length(), PR_TRUE);
|
||||
}
|
||||
rv = ActuallyDisplayText(textToDisplay, PR_TRUE);
|
||||
nsFrameState state;
|
||||
//mTextFrame->GetFrameState(&state);
|
||||
//state |= NS_FRAME_IS_DIRTY;
|
||||
@ -1970,11 +1947,26 @@ nsComboboxControlFrame::SelectionChanged()
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComboboxControlFrame::ActuallyDisplayText(nsAString& aText, PRBool aNotify)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (aText.IsEmpty()) {
|
||||
nsAutoString space(PRUnichar(' '));
|
||||
rv = mDisplayContent->SetText(space.get(), space.Length(), aNotify);
|
||||
} else {
|
||||
const nsAFlatString& flat = PromiseFlatString(aText);
|
||||
rv = mDisplayContent->SetText(flat.get(), flat.Length(), aNotify);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::GetIndexOfDisplayArea(PRInt32* aSelectedIndex)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSelectedIndex);
|
||||
*aSelectedIndex = mSelectedIndex;
|
||||
*aSelectedIndex = mDisplayedIndex;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2473,6 +2465,15 @@ nsComboboxControlFrame::Rollup()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::RollupFromList(nsIPresContext* aPresContext)
|
||||
{
|
||||
ShowList(aPresContext, PR_FALSE);
|
||||
mListControlFrame->CaptureMouseEvents(aPresContext, PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsComboboxControlFrame::Paint(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
@ -2579,13 +2580,36 @@ nsComboboxControlFrame::OnOptionSelected(nsIPresContext* aPresContext,
|
||||
PRInt32 aIndex,
|
||||
PRBool aSelected)
|
||||
{
|
||||
if (aSelected && !mDroppedDown) {
|
||||
mListControlFrame->GetOptionText(aIndex, mTextStr);
|
||||
SelectionChanged();
|
||||
if (aSelected) {
|
||||
if (!mDroppedDown) {
|
||||
RedisplayText(aIndex);
|
||||
} else {
|
||||
nsCOMPtr<nsISelectControlFrame> selectFrame
|
||||
= do_QueryInterface(mListControlFrame);
|
||||
if (selectFrame) {
|
||||
selectFrame->OnOptionSelected(aPresContext, aIndex, aSelected);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::OnOptionTextChanged(nsIDOMHTMLOptionElement* option)
|
||||
{
|
||||
RedisplaySelectedText();
|
||||
if (mDroppedDown) {
|
||||
nsCOMPtr<nsISelectControlFrame> selectFrame
|
||||
= do_QueryInterface(mListControlFrame);
|
||||
if (selectFrame) {
|
||||
selectFrame->OnOptionTextChanged(option);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::OnContentReset()
|
||||
{
|
||||
|
@ -169,10 +169,6 @@ public:
|
||||
nscoord aCharWidth) const;
|
||||
virtual nsresult RequiresWidget(PRBool &aRequiresWidget);
|
||||
|
||||
NS_IMETHOD SelectionChanged();// Called when the selection has changed.
|
||||
// If the the same item in the list is selected
|
||||
// it is NOT called.
|
||||
|
||||
// nsIFormMouseListener
|
||||
virtual void MouseClicked(nsIPresContext* aPresContext);
|
||||
|
||||
@ -181,11 +177,11 @@ public:
|
||||
NS_IMETHOD ShowDropDown(PRBool aDoDropDown);
|
||||
NS_IMETHOD GetDropDown(nsIFrame** aDropDownFrame);
|
||||
NS_IMETHOD SetDropDown(nsIFrame* aDropDownFrame);
|
||||
NS_IMETHOD ListWasSelected(nsIPresContext* aPresContext, PRBool aForceUpdate, PRBool aSendEvent);
|
||||
NS_IMETHOD UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex);
|
||||
NS_IMETHOD RollupFromList(nsIPresContext* aPresContext);
|
||||
NS_IMETHOD AbsolutelyPositionDropDown();
|
||||
NS_IMETHOD GetAbsoluteRect(nsRect* aRect);
|
||||
NS_IMETHOD GetIndexOfDisplayArea(PRInt32* aSelectedIndex);
|
||||
NS_IMETHOD RedisplaySelectedText();
|
||||
|
||||
// nsISelectControlFrame
|
||||
NS_IMETHOD AddOption(nsIPresContext* aPresContext, PRInt32 index);
|
||||
@ -195,6 +191,7 @@ public:
|
||||
NS_IMETHOD OnOptionSelected(nsIPresContext* aPresContext,
|
||||
PRInt32 aIndex,
|
||||
PRBool aSelected);
|
||||
NS_IMETHOD OnOptionTextChanged(nsIDOMHTMLOptionElement* option);
|
||||
NS_IMETHOD GetDummyFrame(nsIFrame** aFrame);
|
||||
NS_IMETHOD SetDummyFrame(nsIFrame* aFrame);
|
||||
|
||||
@ -223,6 +220,7 @@ public:
|
||||
NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState);
|
||||
|
||||
protected:
|
||||
|
||||
NS_IMETHOD CreateDisplayFrame(nsIPresContext* aPresContext);
|
||||
|
||||
#ifdef DO_NEW_REFLOW
|
||||
@ -253,6 +251,8 @@ protected:
|
||||
void ShowList(nsIPresContext* aPresContext, PRBool aShowList);
|
||||
void SetChildFrameSize(nsIFrame* aFrame, nscoord aWidth, nscoord aHeight);
|
||||
void InitTextStr();
|
||||
nsresult RedisplayText(PRInt32 aIndex);
|
||||
nsresult ActuallyDisplayText(nsAString& aText, PRBool aNotify);
|
||||
nsresult GetPrimaryComboFrame(nsIPresContext* aPresContext, nsIContent* aContent, nsIFrame** aFrame);
|
||||
NS_IMETHOD ToggleList(nsIPresContext* aPresContext);
|
||||
|
||||
@ -271,8 +271,6 @@ protected:
|
||||
nsFrameList mPopupFrames; // additional named child list
|
||||
nsIPresContext* mPresContext; // XXX: Remove the need to cache the pres context.
|
||||
nsFormFrame* mFormFrame; // Parent Form Frame
|
||||
nsString mTextStr; // Current Combo box selection
|
||||
PRInt32 mSelectedIndex; // current selected index
|
||||
nsCOMPtr<nsITextContent> mDisplayContent; // Anonymous content used to display the current selection
|
||||
PRPackedBool mDroppedDown; // Current state of the dropdown list, PR_TRUE is dropped down
|
||||
nsIFrame* mDisplayFrame; // frame to display selection
|
||||
@ -295,6 +293,8 @@ protected:
|
||||
|
||||
PRPackedBool mGoodToGo;
|
||||
|
||||
PRInt32 mDisplayedIndex;
|
||||
|
||||
// make someone to listen to the button. If its programmatically pressed by someone like Accessibility
|
||||
// then open or close the combo box.
|
||||
nsCOMPtr<nsIDOMMouseListener> mButtonListener;
|
||||
|
@ -1234,37 +1234,41 @@ nsListControlFrame::GetIndexFromContent(nsIContent *aContent)
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
void
|
||||
PRBool
|
||||
nsListControlFrame::ExtendedSelection(PRInt32 aStartIndex,
|
||||
PRInt32 aEndIndex,
|
||||
PRBool aClearAll)
|
||||
{
|
||||
SetOptionsSelectedFromFrame(aStartIndex, aEndIndex, PR_TRUE, aClearAll);
|
||||
return SetOptionsSelectedFromFrame(aStartIndex, aEndIndex,
|
||||
PR_TRUE, aClearAll);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
void
|
||||
PRBool
|
||||
nsListControlFrame::SingleSelection(PRInt32 aSelectedIndex, PRBool aDoToggle)
|
||||
{
|
||||
PRBool wasChanged = PR_FALSE;
|
||||
// Get Current selection
|
||||
if (aDoToggle) {
|
||||
ToggleOptionSelectedFromFrame(aSelectedIndex);
|
||||
wasChanged = ToggleOptionSelectedFromFrame(aSelectedIndex);
|
||||
} else {
|
||||
SetOptionsSelectedFromFrame(aSelectedIndex, aSelectedIndex,
|
||||
wasChanged = SetOptionsSelectedFromFrame(aSelectedIndex, aSelectedIndex,
|
||||
PR_TRUE, PR_TRUE);
|
||||
}
|
||||
ScrollToIndex(aSelectedIndex);
|
||||
mStartSelectionIndex = aSelectedIndex;
|
||||
mEndSelectionIndex = aSelectedIndex;
|
||||
mChangesNotNotified = PR_TRUE;
|
||||
return wasChanged;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
void
|
||||
PRBool
|
||||
nsListControlFrame::PerformSelection(PRInt32 aSelectedIndex,
|
||||
PRBool aIsShift,
|
||||
PRBool aIsControl)
|
||||
{
|
||||
PRBool wasChanged = PR_FALSE;
|
||||
|
||||
PRBool isMultiple;
|
||||
GetMultiple(&isMultiple);
|
||||
|
||||
@ -1286,7 +1290,7 @@ nsListControlFrame::PerformSelection(PRInt32 aSelectedIndex,
|
||||
endIndex = mStartSelectionIndex;
|
||||
}
|
||||
|
||||
ExtendedSelection(startIndex, endIndex, PR_TRUE);
|
||||
wasChanged = ExtendedSelection(startIndex, endIndex, PR_TRUE);
|
||||
ScrollToIndex(aSelectedIndex);
|
||||
|
||||
if (mStartSelectionIndex == kNothingSelected) {
|
||||
@ -1295,14 +1299,13 @@ nsListControlFrame::PerformSelection(PRInt32 aSelectedIndex,
|
||||
} else {
|
||||
mEndSelectionIndex = aSelectedIndex;
|
||||
}
|
||||
mChangesNotNotified = PR_TRUE;
|
||||
} else if (aIsControl) {
|
||||
SingleSelection(aSelectedIndex, PR_TRUE);
|
||||
wasChanged = SingleSelection(aSelectedIndex, PR_TRUE);
|
||||
} else {
|
||||
SingleSelection(aSelectedIndex, PR_FALSE);
|
||||
wasChanged = SingleSelection(aSelectedIndex, PR_FALSE);
|
||||
}
|
||||
} else {
|
||||
SingleSelection(aSelectedIndex, PR_FALSE);
|
||||
wasChanged = SingleSelection(aSelectedIndex, PR_FALSE);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_rodsX
|
||||
@ -1311,10 +1314,12 @@ nsListControlFrame::PerformSelection(PRInt32 aSelectedIndex,
|
||||
printf("mLastStartIndex: %d\n", mLastStartIndex);
|
||||
printf("mLastEndIndex: %d\n", mLastEndIndex);
|
||||
#endif
|
||||
|
||||
return wasChanged;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
void
|
||||
PRBool
|
||||
nsListControlFrame::HandleListSelection(nsIDOMEvent* aEvent,
|
||||
PRInt32 aSelectedIndex)
|
||||
{
|
||||
@ -1327,7 +1332,7 @@ nsListControlFrame::HandleListSelection(nsIDOMEvent* aEvent,
|
||||
mouseEvent->GetCtrlKey(&isControl);
|
||||
#endif
|
||||
mouseEvent->GetShiftKey(&isShift);
|
||||
PerformSelection(aSelectedIndex, isShift, isControl);
|
||||
return PerformSelection(aSelectedIndex, isShift, isControl);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
@ -1518,7 +1523,6 @@ nsListControlFrame::Init(nsIPresContext* aPresContext,
|
||||
|
||||
mStartSelectionIndex = kNothingSelected;
|
||||
mEndSelectionIndex = kNothingSelected;
|
||||
mChangesNotNotified = PR_FALSE;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1711,6 +1715,12 @@ nsListControlFrame::OnOptionSelected(nsIPresContext* aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsListControlFrame::OnOptionTextChanged(nsIDOMHTMLOptionElement* option)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
PRIntn
|
||||
@ -1777,13 +1787,8 @@ nsListControlFrame::ResetList(nsIPresContext* aPresContext, nsVoidArray * aInxLi
|
||||
|
||||
mStartSelectionIndex = kNothingSelected;
|
||||
mEndSelectionIndex = kNothingSelected;
|
||||
mChangesNotNotified = PR_FALSE;
|
||||
|
||||
if (mComboboxFrame != nsnull) {
|
||||
// don't dispatch event
|
||||
mComboboxFrame->UpdateSelection(PR_FALSE, PR_TRUE, indexToSelect);
|
||||
}
|
||||
|
||||
// Combobox will redisplay itself with the OnOptionSelected event
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
@ -2030,7 +2035,7 @@ nsListControlFrame::RemoveOption(nsIPresContext* aPresContext, PRInt32 aIndex)
|
||||
// Set the option selected in the DOM. This method is named
|
||||
// as it is because it indicates that the frame is the source
|
||||
// of this event rather than the receiver.
|
||||
nsresult
|
||||
PRBool
|
||||
nsListControlFrame::SetOptionsSelectedFromFrame(PRInt32 aStartIndex,
|
||||
PRInt32 aEndIndex,
|
||||
PRBool aValue,
|
||||
@ -2046,25 +2051,22 @@ nsListControlFrame::SetOptionsSelectedFromFrame(PRInt32 aStartIndex,
|
||||
PR_TRUE,
|
||||
&wasChanged);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "SetSelected failed");
|
||||
if (NS_SUCCEEDED(rv) && !mChangesNotNotified && wasChanged) {
|
||||
mChangesNotNotified = PR_TRUE;
|
||||
}
|
||||
return rv;
|
||||
return wasChanged;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PRBool
|
||||
nsListControlFrame::ToggleOptionSelectedFromFrame(PRInt32 aIndex)
|
||||
{
|
||||
nsCOMPtr<nsIDOMHTMLCollection> options(getter_AddRefs(GetOptions(mContent)));
|
||||
NS_ASSERTION(options, "No options");
|
||||
if (!options) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
nsCOMPtr<nsIDOMHTMLOptionElement> option(
|
||||
getter_AddRefs(GetOption(*options, aIndex)));
|
||||
NS_ASSERTION(option, "No option");
|
||||
if (!option) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool value = PR_FALSE;
|
||||
@ -2082,11 +2084,8 @@ nsListControlFrame::ToggleOptionSelectedFromFrame(PRInt32 aIndex)
|
||||
&wasChanged);
|
||||
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "SetSelected failed");
|
||||
if (wasChanged) {
|
||||
mChangesNotNotified = PR_TRUE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
return wasChanged;
|
||||
}
|
||||
|
||||
|
||||
@ -2094,7 +2093,7 @@ nsListControlFrame::ToggleOptionSelectedFromFrame(PRInt32 aIndex)
|
||||
NS_IMETHODIMP
|
||||
nsListControlFrame::UpdateSelection()
|
||||
{
|
||||
if (!mIsAllFramesHere || !mIsAllContentHere || !mChangesNotNotified) {
|
||||
if (!mIsAllFramesHere || !mIsAllContentHere) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult rv = NS_OK;
|
||||
@ -2104,23 +2103,30 @@ nsListControlFrame::UpdateSelection()
|
||||
mComboboxFrame->IsDroppedDown(&isDroppedDown);
|
||||
}
|
||||
if (!isDroppedDown) {
|
||||
rv = SelectionChanged(); // Dispatch event
|
||||
mChangesNotNotified = PR_FALSE;
|
||||
rv = FireOnChange(); // Dispatch event
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsListControlFrame::ComboboxUpdateSelection(PRBool aForceUpdate,
|
||||
PRBool aSendEvent)
|
||||
void
|
||||
nsListControlFrame::ComboboxFinish(PRInt32 aIndex)
|
||||
{
|
||||
if (mComboboxFrame) {
|
||||
mComboboxFrame->ListWasSelected(mPresContext, aForceUpdate, aSendEvent);
|
||||
}
|
||||
mChangesNotNotified = PR_FALSE;
|
||||
PerformSelection(aIndex, PR_FALSE, PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
PRInt32 displayIndex;
|
||||
mComboboxFrame->GetIndexOfDisplayArea(&displayIndex);
|
||||
|
||||
if (displayIndex != aIndex) {
|
||||
mComboboxFrame->RedisplaySelectedText();
|
||||
}
|
||||
|
||||
mComboboxFrame->RollupFromList(mPresContext);
|
||||
if (aIndex != mSelectedIndexWhenPoppedDown) {
|
||||
FireOnChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -2132,7 +2138,7 @@ nsListControlFrame::GetOptionsContainer(nsIPresContext* aPresContext,
|
||||
|
||||
// Send out an onchange notification.
|
||||
nsresult
|
||||
nsListControlFrame::SelectionChanged()
|
||||
nsListControlFrame::FireOnChange()
|
||||
{
|
||||
nsresult ret = NS_ERROR_FAILURE;
|
||||
|
||||
@ -2353,31 +2359,21 @@ nsListControlFrame::AboutToDropDown()
|
||||
NS_IMETHODIMP
|
||||
nsListControlFrame::AboutToRollup()
|
||||
{
|
||||
// XXX To have clicking outside the combobox ALWAYS reset the contents to the
|
||||
// state before it was dropped, remove the all the code in the "if" below and replace it
|
||||
// with just the call to ResetSelectedItem()
|
||||
// We've been updating the combobox with the keyboard up until now, but not
|
||||
// with the mouse. The problem is, even with mouse selection, we are
|
||||
// updating the <select>. So if the mouse goes over an option just before
|
||||
// he leaves the box and clicks, that's what the <select> will show.
|
||||
//
|
||||
//
|
||||
// When the dropdown is dropped down via a mouse click and the user moves the mouse
|
||||
// up and down without clicking, the currently selected item is being tracking inside
|
||||
// the dropdown, but the combobox is not being updated. When the user selects items
|
||||
// with the arrow keys, the combobox is being updated. So when the user clicks outside
|
||||
// the dropdown and it needs to roll up it has to decide whether to keep the current
|
||||
// selection or not. The GetIndexOfDisplayArea method is used to get the current index
|
||||
// in the combobox to compare it to the current index in the dropdown to see if the combox
|
||||
// has been updated and that way it knows whether to "cancel" the the current selection
|
||||
// residing in the dropdown. Or whether to leave the selection alone.
|
||||
// To deal with this we say "whatever is in the combobox is canonical."
|
||||
// - IF the combobox is different from the current selected index, we
|
||||
// reset the index.
|
||||
// - IF the combobox is different from the index when it was popped down,
|
||||
// we fire onChange() since it has changed.
|
||||
|
||||
if (IsInDropDownMode() == PR_TRUE) {
|
||||
PRInt32 index;
|
||||
mComboboxFrame->GetIndexOfDisplayArea(&index);
|
||||
// if the indexes do NOT match then the selection in the combobox
|
||||
// was never updated, and therefore we should reset the the selection back to
|
||||
// whatever it was before it was dropped down.
|
||||
if (index != mStartSelectionIndex) {
|
||||
ResetSelectedItem();
|
||||
} else {
|
||||
ComboboxUpdateSelection(PR_FALSE, PR_TRUE);
|
||||
}
|
||||
ComboboxFinish(index);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2500,21 +2496,6 @@ nsListControlFrame::IsOptionDisabled(PRInt32 anIndex, PRBool &aIsDisabled)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 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()
|
||||
{
|
||||
if (mIsAllFramesHere) {
|
||||
SingleSelection(mSelectedIndexWhenPoppedDown, PR_FALSE);
|
||||
// We're resetting ... don't send OnChange
|
||||
mChangesNotNotified = PR_FALSE;
|
||||
if (IsInDropDownMode() == PR_TRUE) {
|
||||
ComboboxUpdateSelection(PR_TRUE, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// helper
|
||||
//----------------------------------------------------------------------
|
||||
@ -2619,11 +2600,9 @@ nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent)
|
||||
}
|
||||
|
||||
if (kNothingSelected != selectedIndex) {
|
||||
if (!mChangesNotNotified) {
|
||||
ResetSelectedItem();
|
||||
}
|
||||
ComboboxFinish(selectedIndex);
|
||||
}
|
||||
ComboboxUpdateSelection(PR_TRUE, PR_TRUE);
|
||||
|
||||
mouseEvent->clickCount = 1;
|
||||
} else {
|
||||
// the click was out side of the select or its dropdown
|
||||
@ -2633,7 +2612,9 @@ nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent)
|
||||
REFLOW_DEBUG_MSG(">>>>>> Didn't find");
|
||||
CaptureMouseEvents(mPresContext, PR_FALSE);
|
||||
// Notify
|
||||
UpdateSelection();
|
||||
if (mChangesSinceDragStart) {
|
||||
UpdateSelection();
|
||||
}
|
||||
#if 0 // XXX - this is a partial fix for Bug 29990
|
||||
if (mSelectedIndex != mStartExtendedIndex) {
|
||||
mEndExtendedIndex = mSelectedIndex;
|
||||
@ -2761,7 +2742,7 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
|
||||
if (!IsInDropDownMode()) {
|
||||
// Handle Like List
|
||||
CaptureMouseEvents(mPresContext, PR_TRUE);
|
||||
HandleListSelection(aMouseEvent, selectedIndex);
|
||||
mChangesSinceDragStart = HandleListSelection(aMouseEvent, selectedIndex);
|
||||
}
|
||||
} else {
|
||||
// NOTE: the combo box is responsible for dropping it down
|
||||
@ -2792,7 +2773,6 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
|
||||
if (isDroppedDown) {
|
||||
CaptureMouseEvents(mPresContext, PR_FALSE);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2848,7 +2828,9 @@ nsListControlFrame::DragMove(nsIDOMEvent* aMouseEvent)
|
||||
mouseEvent->GetCtrlKey(&isControl);
|
||||
#endif
|
||||
// Turn SHIFT on when you are dragging, unless control is on.
|
||||
PerformSelection(selectedIndex, !isControl, isControl);
|
||||
PRBool wasChanged = PerformSelection(selectedIndex,
|
||||
!isControl, isControl);
|
||||
mChangesSinceDragStart = mChangesSinceDragStart || wasChanged;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
@ -3172,20 +3154,21 @@ nsListControlFrame::KeyPress(nsIDOMEvent* aKeyEvent)
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_RETURN: {
|
||||
if (mComboboxFrame != nsnull) {
|
||||
if (IsInDropDownMode() == PR_TRUE) {
|
||||
PRBool isDroppedDown;
|
||||
mComboboxFrame->IsDroppedDown(&isDroppedDown);
|
||||
ComboboxUpdateSelection(isDroppedDown, PR_TRUE);
|
||||
} else {
|
||||
UpdateSelection();
|
||||
PRBool droppedDown = PR_FALSE;
|
||||
mComboboxFrame->IsDroppedDown(&droppedDown);
|
||||
if (droppedDown) {
|
||||
ComboboxFinish(mEndSelectionIndex);
|
||||
}
|
||||
return NS_OK;
|
||||
} else {
|
||||
newIndex = mEndSelectionIndex;
|
||||
}
|
||||
} break;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_ESCAPE: {
|
||||
if (IsInDropDownMode() == PR_TRUE) {
|
||||
ResetSelectedItem();
|
||||
}
|
||||
ComboboxFinish(mSelectedIndexWhenPoppedDown);
|
||||
}
|
||||
} break;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_PAGE_UP: {
|
||||
@ -3242,13 +3225,14 @@ nsListControlFrame::KeyPress(nsIDOMEvent* aKeyEvent)
|
||||
ToLowerCase(text);
|
||||
PRUnichar firstChar = text.CharAt(0);
|
||||
if (firstChar == (PRUnichar)code) {
|
||||
PerformSelection(selectedIndex, isShift, isControl);
|
||||
PRBool wasChanged = PerformSelection(selectedIndex,
|
||||
isShift, isControl);
|
||||
// If it's a combobox, redisplay the text
|
||||
if (mComboboxFrame && mIsAllFramesHere) {
|
||||
// dispatch event
|
||||
mComboboxFrame->UpdateSelection(PR_TRUE,
|
||||
PR_TRUE,
|
||||
selectedIndex);
|
||||
} else {
|
||||
mComboboxFrame->RedisplaySelectedText();
|
||||
}
|
||||
// Fire the event (unless it's a dropped down combobox)
|
||||
if (wasChanged) {
|
||||
UpdateSelection(); // dispatch event
|
||||
}
|
||||
break;
|
||||
@ -3274,11 +3258,13 @@ nsListControlFrame::KeyPress(nsIDOMEvent* aKeyEvent)
|
||||
mEndSelectionIndex = newIndex;
|
||||
ScrollToIndex(newIndex);
|
||||
} else {
|
||||
PerformSelection(newIndex, isShift, isControl);
|
||||
// Dispatch event
|
||||
PRBool wasChanged = PerformSelection(newIndex, isShift, isControl);
|
||||
// If combobox, redisplay selected text.
|
||||
if (mComboboxFrame && mIsAllFramesHere) {
|
||||
mComboboxFrame->UpdateSelection(PR_TRUE, PR_FALSE, newIndex);
|
||||
} else {
|
||||
mComboboxFrame->RedisplaySelectedText();
|
||||
}
|
||||
// Fire the event (unless it's a dropped down combobox)
|
||||
if (wasChanged) {
|
||||
UpdateSelection();
|
||||
}
|
||||
}
|
||||
|
@ -274,7 +274,6 @@ public:
|
||||
NS_IMETHOD AboutToDropDown();
|
||||
NS_IMETHOD AboutToRollup();
|
||||
NS_IMETHOD UpdateSelection();
|
||||
NS_IMETHOD ComboboxUpdateSelection(PRBool aForceUpdate, PRBool aSendEvent);
|
||||
NS_IMETHOD SetOverrideReflowOptimization(PRBool aValue) { mOverrideReflowOpt = aValue; return NS_OK; }
|
||||
NS_IMETHOD GetOptionsContainer(nsIPresContext* aPresContext, nsIFrame** aFrame);
|
||||
|
||||
@ -286,6 +285,7 @@ public:
|
||||
NS_IMETHOD OnOptionSelected(nsIPresContext* aPresContext,
|
||||
PRInt32 aIndex,
|
||||
PRBool aSelected);
|
||||
NS_IMETHOD OnOptionTextChanged(nsIDOMHTMLOptionElement* option);
|
||||
NS_IMETHOD GetDummyFrame(nsIFrame** aFrame);
|
||||
NS_IMETHOD SetDummyFrame(nsIFrame* aFrame);
|
||||
|
||||
@ -352,41 +352,46 @@ protected:
|
||||
PRBool IsContentSelected(nsIContent* aContent);
|
||||
PRBool IsContentSelectedByIndex(PRInt32 aIndex);
|
||||
void GetViewOffset(nsIViewManager* aManager, nsIView* aView, nsPoint& aPoint);
|
||||
PRBool IsInDropDownMode();
|
||||
PRBool IsOptionElement(nsIContent* aContent);
|
||||
void SingleSelection(PRInt32 aSelectedIndex, PRBool aDoToggle);
|
||||
void ExtendedSelection(PRInt32 aStartIndex,
|
||||
PRInt32 aEndIndex,
|
||||
PRBool aClearAll);
|
||||
void PerformSelection(PRInt32 aSelectedIndex,
|
||||
PRBool aIsShift,
|
||||
PRBool aIsControl);
|
||||
void ResetSelectedItem();
|
||||
PRBool CheckIfAllFramesHere();
|
||||
PRInt32 GetIndexFromContent(nsIContent *aContent);
|
||||
void HandleListSelection(nsIDOMEvent * aDOMEvent, PRInt32 selectedIndex);
|
||||
PRBool IsLeftButton(nsIDOMEvent* aMouseEvent);
|
||||
nsresult SetOptionsSelectedFromFrame(PRInt32 aStartIndex,
|
||||
PRInt32 aEndIndex,
|
||||
PRBool aValue,
|
||||
PRBool aClearAll);
|
||||
nsresult ToggleOptionSelectedFromFrame(PRInt32 aIndex);
|
||||
void GetScrollableView(nsIScrollableView*& aScrollableView);
|
||||
|
||||
// Dropped down stuff
|
||||
void SetComboboxItem(PRInt32 aIndex);
|
||||
void ComboboxFinish(PRInt32 aIndex);
|
||||
PRBool IsInDropDownMode();
|
||||
|
||||
// Selection
|
||||
PRBool SetOptionsSelectedFromFrame(PRInt32 aStartIndex,
|
||||
PRInt32 aEndIndex,
|
||||
PRBool aValue,
|
||||
PRBool aClearAll);
|
||||
PRBool ToggleOptionSelectedFromFrame(PRInt32 aIndex);
|
||||
PRBool SingleSelection(PRInt32 aSelectedIndex, PRBool aDoToggle);
|
||||
PRBool ExtendedSelection(PRInt32 aStartIndex,
|
||||
PRInt32 aEndIndex,
|
||||
PRBool aClearAll);
|
||||
PRBool PerformSelection(PRInt32 aSelectedIndex,
|
||||
PRBool aIsShift,
|
||||
PRBool aIsControl);
|
||||
PRBool HandleListSelection(nsIDOMEvent * aDOMEvent, PRInt32 selectedIndex);
|
||||
|
||||
// Timer Methods
|
||||
nsresult StartUpdateTimer(nsIPresContext * aPresContext);
|
||||
void StopUpdateTimer();
|
||||
void ItemsHaveBeenRemoved(nsIPresContext * aPresContext);
|
||||
|
||||
// onChange detection
|
||||
nsresult SelectionChanged();
|
||||
// fire onChange
|
||||
nsresult FireOnChange();
|
||||
|
||||
// Data Members
|
||||
nsFormFrame* mFormFrame;
|
||||
|
||||
PRInt32 mStartSelectionIndex;
|
||||
PRInt32 mEndSelectionIndex;
|
||||
PRBool mChangesNotNotified;
|
||||
PRPackedBool mChangesSinceDragStart;
|
||||
|
||||
PRInt32 mSelectedIndexWhenPoppedDown;
|
||||
nsIComboboxControlFrame *mComboboxFrame;
|
||||
|
Loading…
x
Reference in New Issue
Block a user