diff --git a/content/html/content/src/nsHTMLOptionElement.cpp b/content/html/content/src/nsHTMLOptionElement.cpp
index 40d9f7406d96..795ba6934f2a 100644
--- a/content/html/content/src/nsHTMLOptionElement.cpp
+++ b/content/html/content/src/nsHTMLOptionElement.cpp
@@ -21,6 +21,7 @@
*
* Contributor(s):
* Pierre Phaneuf
+ * Mats Palmgren
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@@ -110,18 +111,6 @@ public:
NS_IMETHOD SetSelectedInternal(PRBool aValue, PRBool aNotify);
// nsIContent
- nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
- const nsAString& aValue, PRBool aNotify)
- {
- return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
- }
- virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
- nsIAtom* aPrefix, const nsAString& aValue,
- PRBool aNotify);
- virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
- PRBool aNotify);
- virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
- virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
virtual PRInt32 IntrinsicState() const;
protected:
@@ -139,11 +128,6 @@ protected:
*/
void GetSelect(nsIDOMHTMLSelectElement **aSelectElement) const;
- /**
- * Notify the frame that the option text or value or label has changed.
- */
- void NotifyTextChanged();
-
PRPackedBool mIsInitialized;
PRPackedBool mIsSelected;
};
@@ -407,9 +391,6 @@ nsHTMLOptionElement::SetText(const nsAString& aText)
rv = domText->SetData(aText);
if (NS_SUCCEEDED(rv)) {
- // If we used an existing node, the notification will not happen (the
- // notification typically happens in AppendChildTo).
- NotifyTextChanged();
usedExistingTextNode = PR_TRUE;
}
@@ -430,70 +411,6 @@ nsHTMLOptionElement::SetText(const nsAString& aText)
return rv;
}
-void
-nsHTMLOptionElement::NotifyTextChanged()
-{
- // No need to flush here, if there's no frame yet we don't need to
- // force it to be created just to update the selection in it.
- nsIFormControlFrame* fcFrame = GetSelectFrame();
-
- if (fcFrame) {
- nsISelectControlFrame* selectFrame = nsnull;
-
- CallQueryInterface(fcFrame, &selectFrame);
-
- if (selectFrame) {
- selectFrame->OnOptionTextChanged(this);
- }
- }
-}
-
-nsresult
-nsHTMLOptionElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
- nsIAtom* aPrefix, const nsAString& aValue,
- PRBool aNotify)
-{
- nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
- aValue, aNotify);
- if (NS_SUCCEEDED(rv) && aNotify && aName == nsHTMLAtoms::label &&
- aNameSpaceID == kNameSpaceID_None) {
- // XXX Why does this only happen to the combobox? and what about
- // when the text gets set and label is blank?
- NotifyTextChanged();
- }
-
- return rv;
-}
-
-//
-// Override nsIContent children changing methods so we can detect when our text
-// is changing
-//
-nsresult
-nsHTMLOptionElement::InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
- PRBool aNotify)
-{
- nsresult rv = nsGenericHTMLElement::InsertChildAt(aKid, aIndex, aNotify);
- NotifyTextChanged();
- return rv;
-}
-
-nsresult
-nsHTMLOptionElement::AppendChildTo(nsIContent* aKid, PRBool aNotify)
-{
- nsresult rv = nsGenericHTMLElement::AppendChildTo(aKid, aNotify);
- NotifyTextChanged();
- return rv;
-}
-
-nsresult
-nsHTMLOptionElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
-{
- nsresult rv = nsGenericHTMLElement::RemoveChildAt(aIndex, aNotify);
- NotifyTextChanged();
- return rv;
-}
-
PRInt32
nsHTMLOptionElement::IntrinsicState() const
{
diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp
index afef51ab4b9a..394150c8d31f 100644
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -99,17 +99,13 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
class RedisplayTextEvent : public PLEvent
{
public:
- RedisplayTextEvent(nsComboboxControlFrame* aComboboxControlFrame,
- const nsAString& aTextToDisplay);
+ RedisplayTextEvent(nsComboboxControlFrame* aComboboxControlFrame);
void HandleEvent()
{
NS_STATIC_CAST(nsComboboxControlFrame*, owner) ->
- HandleRedisplayTextEvent(mTextToDisplay);
+ HandleRedisplayTextEvent();
}
-
-private:
- nsString mTextToDisplay;
};
PR_STATIC_CALLBACK(void*)
@@ -132,9 +128,7 @@ DestroyRedisplayTextPLEvent(PLEvent* aEvent)
delete event;
}
-RedisplayTextEvent::RedisplayTextEvent(nsComboboxControlFrame* aComboboxControlFrame,
- const nsAString& aTextToDisplay)
- : mTextToDisplay(aTextToDisplay)
+RedisplayTextEvent::RedisplayTextEvent(nsComboboxControlFrame* aComboboxControlFrame)
{
PL_InitEvent(this, aComboboxControlFrame,
::HandleRedisplayTextPLEvent,
@@ -453,23 +447,6 @@ nsComboboxControlFrame::Init(nsPresContext* aPresContext,
return nsAreaFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
}
-// Initialize the text string in the combobox using either the current
-// selection in the list box or the first item item in the list box.
-void
-nsComboboxControlFrame::InitTextStr()
-{
- nsAutoString textToDisplay;
- PRInt32 selectedIndex;
- mListControlFrame->GetSelectedIndex(&selectedIndex);
- if (selectedIndex != -1) {
- mListControlFrame->GetOptionText(selectedIndex, textToDisplay);
- }
-
- mDisplayedIndex = selectedIndex;
- ActuallyDisplayText(textToDisplay, PR_FALSE);
-}
-
-
//--------------------------------------------------------------
void
nsComboboxControlFrame::InitializeControl(nsPresContext* aPresContext)
@@ -1238,6 +1215,17 @@ nsComboboxControlFrame::Reflow(nsPresContext* aPresContext,
return nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
}
+ // Make sure the displayed text is the same as the selected option, bug 297389.
+ PRInt32 selectedIndex;
+ nsAutoString selectedOptionText;
+ mListControlFrame->GetSelectedIndex(&selectedIndex);
+ if (selectedIndex != -1) {
+ mListControlFrame->GetOptionText(selectedIndex, selectedOptionText);
+ }
+ if (mDisplayedOptionText != selectedOptionText) {
+ RedisplayText(selectedIndex);
+ }
+
// We should cache this instead getting it everytime
// the default size of the of scrollbar
// that will be the default width of the dropdown button
@@ -1783,29 +1771,27 @@ nsresult
nsComboboxControlFrame::RedisplayText(PRInt32 aIndex)
{
// Get the text to display
- nsAutoString textToDisplay;
if (aIndex != -1) {
- mListControlFrame->GetOptionText(aIndex, textToDisplay);
+ mListControlFrame->GetOptionText(aIndex, mDisplayedOptionText);
+ } else {
+ mDisplayedOptionText.Truncate();
}
mDisplayedIndex = aIndex;
-#ifdef DO_REFLOW_DEBUG
- char * str = ToNewCString(textToDisplay);
- REFLOW_DEBUG_MSG2("RedisplayText %s\n", str);
- delete [] str;
-#endif
+ REFLOW_DEBUG_MSG2("RedisplayText \"%s\"\n",
+ NS_LossyConvertUCS2toASCII(mDisplayedOptionText).get());
// Send reflow command because the new text maybe larger
nsresult rv = NS_OK;
if (mDisplayContent && mEventQueueService) {
- // Don't call ActuallyDisplayText(aText,PR_TRUE) directly here since that
+ // Don't call ActuallyDisplayText(PR_TRUE) directly here since that
// could cause recursive frame construction. See bug 283117 and the comment in
// HandleRedisplayTextEvent() below.
nsCOMPtr eventQueue;
rv = mEventQueueService->GetSpecialEventQueue(nsIEventQueueService::UI_THREAD_EVENT_QUEUE,
getter_AddRefs(eventQueue));
if (eventQueue) {
- RedisplayTextEvent* event = new RedisplayTextEvent(this, textToDisplay);
+ RedisplayTextEvent* event = new RedisplayTextEvent(this);
if (event) {
// Revoke outstanding events to avoid out-of-order events which could mean
// displaying the wrong text.
@@ -1830,7 +1816,7 @@ nsComboboxControlFrame::RedisplayText(PRInt32 aIndex)
}
void
-nsComboboxControlFrame::HandleRedisplayTextEvent(const nsAString& aText)
+nsComboboxControlFrame::HandleRedisplayTextEvent()
{
// First, make sure that the content model is up to date and we've
// constructed the frames for all our content in the right places.
@@ -1848,26 +1834,24 @@ nsComboboxControlFrame::HandleRedisplayTextEvent(const nsAString& aText)
mInRedisplayText = PR_TRUE;
mRedisplayTextEventPosted = PR_FALSE;
- ActuallyDisplayText(aText, PR_TRUE);
+ ActuallyDisplayText(PR_TRUE);
mDisplayFrame->AddStateBits(NS_FRAME_IS_DIRTY);
ReflowDirtyChild(GetPresContext()->PresShell(), mDisplayFrame);
mInRedisplayText = PR_FALSE;
}
-nsresult
-nsComboboxControlFrame::ActuallyDisplayText(const nsAString& aText, PRBool aNotify)
+void
+nsComboboxControlFrame::ActuallyDisplayText(PRBool aNotify)
{
- if (aText.IsEmpty()) {
+ if (mDisplayedOptionText.IsEmpty()) {
// Have to use a non-breaking space for line-height calculations
// to be right
static const PRUnichar space = 0xA0;
mDisplayContent->SetText(&space, 1, aNotify);
} else {
- mDisplayContent->SetText(aText, aNotify);
+ mDisplayContent->SetText(mDisplayedOptionText, aNotify);
}
-
- return NS_OK;
}
NS_IMETHODIMP
@@ -2112,7 +2096,9 @@ nsComboboxControlFrame::CreateAnonymousContent(nsPresContext* aPresContext,
if (labelContent) {
// set the value of the text node
mDisplayContent.swap(labelContent);
- mDisplayContent->SetText(NS_LITERAL_STRING("X"), PR_TRUE);
+ mDisplayedIndex = -1;
+ mDisplayedOptionText.Truncate();
+ ActuallyDisplayText(PR_FALSE);
nsCOMPtr doc = mContent->GetDocument();
@@ -2286,7 +2272,6 @@ nsComboboxControlFrame::SetInitialChildList(nsPresContext* aPresContext,
mPopupFrames.SetFrames(aChildList);
} else {
rv = nsAreaFrame::SetInitialChildList(aPresContext, aListName, aChildList);
- InitTextStr();
for (nsIFrame * child = aChildList; child;
child = child->GetNextSibling()) {
@@ -2499,22 +2484,6 @@ void nsComboboxControlFrame::FireValueChangeEvent()
}
}
-NS_IMETHODIMP
-nsComboboxControlFrame::OnOptionTextChanged(nsIDOMHTMLOptionElement* option)
-{
- RedisplaySelectedText();
- if (mDroppedDown) {
- nsCOMPtr selectFrame
- = do_QueryInterface(mListControlFrame);
- if (selectFrame) {
- selectFrame->OnOptionTextChanged(option);
- }
- }
-
- return NS_OK;
-}
-
-
NS_IMETHODIMP
nsComboboxControlFrame::OnContentReset()
{
diff --git a/layout/forms/nsComboboxControlFrame.h b/layout/forms/nsComboboxControlFrame.h
index e564311b5067..d1322f5842d3 100644
--- a/layout/forms/nsComboboxControlFrame.h
+++ b/layout/forms/nsComboboxControlFrame.h
@@ -183,7 +183,6 @@ public:
NS_IMETHOD OnOptionSelected(nsPresContext* aPresContext,
PRInt32 aIndex,
PRBool aSelected);
- NS_IMETHOD OnOptionTextChanged(nsIDOMHTMLOptionElement* option);
NS_IMETHOD GetDummyFrame(nsIFrame** aFrame);
NS_IMETHOD SetDummyFrame(nsIFrame* aFrame);
NS_IMETHOD OnSetSelectedIndex(PRInt32 aOldIndex, PRInt32 aNewIndex);
@@ -242,12 +241,11 @@ protected:
void ShowPopup(PRBool aShowPopup);
void ShowList(nsPresContext* aPresContext, PRBool aShowList);
void SetChildFrameSize(nsIFrame* aFrame, nscoord aWidth, nscoord aHeight);
- void InitTextStr();
void CheckFireOnChange();
void FireValueChangeEvent();
nsresult RedisplayText(PRInt32 aIndex);
- void HandleRedisplayTextEvent(const nsAString& aText);
- nsresult ActuallyDisplayText(const nsAString& aText, PRBool aNotify);
+ void HandleRedisplayTextEvent();
+ void ActuallyDisplayText(PRBool aNotify);
nsresult GetPrimaryComboFrame(nsPresContext* aPresContext, nsIContent* aContent, nsIFrame** aFrame);
NS_IMETHOD ToggleList(nsPresContext* aPresContext);
@@ -291,6 +289,7 @@ protected:
PRInt32 mRecentSelectedIndex;
PRInt32 mDisplayedIndex;
+ nsString mDisplayedOptionText;
// make someone to listen to the button. If its programmatically pressed by someone like Accessibility
// then open or close the combo box.
diff --git a/layout/forms/nsISelectControlFrame.h b/layout/forms/nsISelectControlFrame.h
index c122ae0526f7..e231c92062b0 100644
--- a/layout/forms/nsISelectControlFrame.h
+++ b/layout/forms/nsISelectControlFrame.h
@@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
+ * Mats Palmgren
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@@ -41,10 +42,10 @@
#include "nsISupports.h"
// IID for the nsISelectControlFrame class
-#define NS_ISELECTCONTROLFRAME_IID \
-{ 0x62a3bc8e, 0x1312, 0x42f3, \
- { 0x96, 0x7c, 0x37, 0x0f, 0x16, 0x9a, 0xd3, 0xbf } }
-// 62a3bc8e-1312-42f3-967c-370f169ad3bf
+// 264dc2f5-1cca-47dd-9ebc-699c430be00a
+#define NS_ISELECTCONTROLFRAME_IID \
+{ 0x264dc2f5, 0x1cca, 0x47dd, \
+ { 0x9e, 0xbc, 0x69, 0x9c, 0x43, 0x0b, 0xe0, 0x0a } }
class nsIDOMHTMLOptionElement;
@@ -86,13 +87,6 @@ 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
*/
diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp
index 9e2d8783fdfc..a0fd12df3348 100644
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -21,6 +21,7 @@
*
* Contributor(s):
* Pierre Phaneuf
+ * Mats Palmgren
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@@ -1727,13 +1728,6 @@ nsListControlFrame::OnOptionSelected(nsPresContext* aPresContext,
return NS_OK;
}
-NS_IMETHODIMP
-nsListControlFrame::OnOptionTextChanged(nsIDOMHTMLOptionElement* option)
-{
- return NS_OK;
-}
-
-
//---------------------------------------------------------
PRIntn
nsListControlFrame::GetSkipSides() const
diff --git a/layout/forms/nsListControlFrame.h b/layout/forms/nsListControlFrame.h
index ff6f68e6caf0..7c6625fbd02e 100644
--- a/layout/forms/nsListControlFrame.h
+++ b/layout/forms/nsListControlFrame.h
@@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
+ * Mats Palmgren
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@@ -182,7 +183,6 @@ public:
NS_IMETHOD OnOptionSelected(nsPresContext* aPresContext,
PRInt32 aIndex,
PRBool aSelected);
- NS_IMETHOD OnOptionTextChanged(nsIDOMHTMLOptionElement* option);
NS_IMETHOD GetDummyFrame(nsIFrame** aFrame);
NS_IMETHOD SetDummyFrame(nsIFrame* aFrame);
NS_IMETHOD OnSetSelectedIndex(PRInt32 aOldIndex, PRInt32 aNewIndex);