diff --git a/mozilla/content/html/content/src/nsHTMLAtoms.cpp b/mozilla/content/html/content/src/nsHTMLAtoms.cpp
index a49ce9e2461..9d29d08d1e7 100644
--- a/mozilla/content/html/content/src/nsHTMLAtoms.cpp
+++ b/mozilla/content/html/content/src/nsHTMLAtoms.cpp
@@ -75,9 +75,7 @@ nsIAtom* nsHTMLAtoms::colgroup;
nsIAtom* nsHTMLAtoms::cols;
nsIAtom* nsHTMLAtoms::colspan;
nsIAtom* nsHTMLAtoms::columnPseudo;
-nsIAtom* nsHTMLAtoms::comboText;
-nsIAtom* nsHTMLAtoms::comboTextSelected;
-nsIAtom* nsHTMLAtoms::comboTextSelectedFocus;
+nsIAtom* nsHTMLAtoms::combobox;
nsIAtom* nsHTMLAtoms::commentPseudo;
nsIAtom* nsHTMLAtoms::compact;
nsIAtom* nsHTMLAtoms::content;
@@ -93,11 +91,7 @@ nsIAtom* nsHTMLAtoms::dir;
nsIAtom* nsHTMLAtoms::disabled;
nsIAtom* nsHTMLAtoms::div;
nsIAtom* nsHTMLAtoms::dl;
-nsIAtom* nsHTMLAtoms::dropDownVisible;
-nsIAtom* nsHTMLAtoms::dropDownHidden;
-nsIAtom* nsHTMLAtoms::dropDownBtnOut;
-nsIAtom* nsHTMLAtoms::dropDownBtnPressed;
-nsIAtom* nsHTMLAtoms::dropDownList;
+nsIAtom* nsHTMLAtoms::dropDownListPseudo;
nsIAtom* nsHTMLAtoms::embed;
nsIAtom* nsHTMLAtoms::encoding;
nsIAtom* nsHTMLAtoms::enctype;
@@ -343,10 +337,8 @@ void nsHTMLAtoms::AddrefAtoms()
colgroup = NS_NewAtom("colgroup");
cols = NS_NewAtom("cols");
colspan = NS_NewAtom("colspan");
+ combobox = NS_NewAtom("combobox");
columnPseudo = NS_NewAtom(":body-column");
- comboText = NS_NewAtom(":-moz-combobox-text");
- comboTextSelected = NS_NewAtom(":-moz-combobox-textselected");
- comboTextSelectedFocus = NS_NewAtom(":-moz-combobox-textselectedfocus");
commentPseudo = NS_NewAtom(":-moz-comment");
compact = NS_NewAtom("compact");
content = NS_NewAtom("content");
@@ -360,11 +352,7 @@ void nsHTMLAtoms::AddrefAtoms()
div = NS_NewAtom("div");
disabled = NS_NewAtom("disabled");
dl = NS_NewAtom("dl");
- dropDownVisible = NS_NewAtom(":-moz-dropdown-visible");
- dropDownHidden = NS_NewAtom(":-moz-dropdown-hidden");
- dropDownBtnOut = NS_NewAtom(":-moz-dropdown-btn-out");
- dropDownBtnPressed = NS_NewAtom(":-moz-dropdown-btn-pressed");
- dropDownList = NS_NewAtom(":-moz-dropdown-list");
+ dropDownListPseudo = NS_NewAtom(":-moz-dropdown-list");
datetime = NS_NewAtom("datetime");
data = NS_NewAtom("data");
@@ -611,10 +599,8 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(colgroup);
NS_RELEASE(cols);
NS_RELEASE(colspan);
+ NS_RELEASE(combobox);
NS_RELEASE(columnPseudo);
- NS_RELEASE(comboText);
- NS_RELEASE(comboTextSelected);
- NS_RELEASE(comboTextSelectedFocus);
NS_RELEASE(commentPseudo);
NS_RELEASE(compact);
NS_RELEASE(content);
@@ -630,11 +616,7 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(disabled);
NS_RELEASE(div);
NS_RELEASE(dl);
- NS_RELEASE(dropDownVisible);
- NS_RELEASE(dropDownHidden);
- NS_RELEASE(dropDownBtnOut);
- NS_RELEASE(dropDownBtnPressed);
- NS_RELEASE(dropDownList);
+ NS_RELEASE(dropDownListPseudo);
NS_RELEASE(embed);
NS_RELEASE(encoding);
NS_RELEASE(face);
diff --git a/mozilla/content/html/content/src/nsHTMLAtoms.h b/mozilla/content/html/content/src/nsHTMLAtoms.h
index 9dff9cbb1e6..8c8e459e413 100644
--- a/mozilla/content/html/content/src/nsHTMLAtoms.h
+++ b/mozilla/content/html/content/src/nsHTMLAtoms.h
@@ -96,9 +96,7 @@ public:
static nsIAtom* cols;
static nsIAtom* colspan;
static nsIAtom* columnPseudo;
- static nsIAtom* comboText;
- static nsIAtom* comboTextSelected;
- static nsIAtom* comboTextSelectedFocus;
+ static nsIAtom* combobox;
static nsIAtom* commentPseudo;
static nsIAtom* compact;
static nsIAtom* content;
@@ -115,11 +113,7 @@ public:
static nsIAtom* disabled;
static nsIAtom* div;
static nsIAtom* dl;
- static nsIAtom* dropDownVisible;
- static nsIAtom* dropDownHidden;
- static nsIAtom* dropDownBtnOut;
- static nsIAtom* dropDownBtnPressed;
- static nsIAtom* dropDownList;
+ static nsIAtom* dropDownListPseudo;
static nsIAtom* embed;
static nsIAtom* encoding;
diff --git a/mozilla/content/shared/public/nsHTMLAtoms.h b/mozilla/content/shared/public/nsHTMLAtoms.h
index 9dff9cbb1e6..8c8e459e413 100644
--- a/mozilla/content/shared/public/nsHTMLAtoms.h
+++ b/mozilla/content/shared/public/nsHTMLAtoms.h
@@ -96,9 +96,7 @@ public:
static nsIAtom* cols;
static nsIAtom* colspan;
static nsIAtom* columnPseudo;
- static nsIAtom* comboText;
- static nsIAtom* comboTextSelected;
- static nsIAtom* comboTextSelectedFocus;
+ static nsIAtom* combobox;
static nsIAtom* commentPseudo;
static nsIAtom* compact;
static nsIAtom* content;
@@ -115,11 +113,7 @@ public:
static nsIAtom* disabled;
static nsIAtom* div;
static nsIAtom* dl;
- static nsIAtom* dropDownVisible;
- static nsIAtom* dropDownHidden;
- static nsIAtom* dropDownBtnOut;
- static nsIAtom* dropDownBtnPressed;
- static nsIAtom* dropDownList;
+ static nsIAtom* dropDownListPseudo;
static nsIAtom* embed;
static nsIAtom* encoding;
diff --git a/mozilla/content/shared/public/nsLayoutAtoms.h b/mozilla/content/shared/public/nsLayoutAtoms.h
index d949fce3f2f..81769d9c977 100644
--- a/mozilla/content/shared/public/nsLayoutAtoms.h
+++ b/mozilla/content/shared/public/nsLayoutAtoms.h
@@ -56,6 +56,7 @@ public:
static nsIAtom* colGroupList;
static nsIAtom* fixedList;
static nsIAtom* floaterList;
+ static nsIAtom* popupList;
// Alphabetical list of pseudo tag names for non-element content
static nsIAtom* commentTagName;
diff --git a/mozilla/content/shared/src/nsHTMLAtoms.cpp b/mozilla/content/shared/src/nsHTMLAtoms.cpp
index a49ce9e2461..9d29d08d1e7 100644
--- a/mozilla/content/shared/src/nsHTMLAtoms.cpp
+++ b/mozilla/content/shared/src/nsHTMLAtoms.cpp
@@ -75,9 +75,7 @@ nsIAtom* nsHTMLAtoms::colgroup;
nsIAtom* nsHTMLAtoms::cols;
nsIAtom* nsHTMLAtoms::colspan;
nsIAtom* nsHTMLAtoms::columnPseudo;
-nsIAtom* nsHTMLAtoms::comboText;
-nsIAtom* nsHTMLAtoms::comboTextSelected;
-nsIAtom* nsHTMLAtoms::comboTextSelectedFocus;
+nsIAtom* nsHTMLAtoms::combobox;
nsIAtom* nsHTMLAtoms::commentPseudo;
nsIAtom* nsHTMLAtoms::compact;
nsIAtom* nsHTMLAtoms::content;
@@ -93,11 +91,7 @@ nsIAtom* nsHTMLAtoms::dir;
nsIAtom* nsHTMLAtoms::disabled;
nsIAtom* nsHTMLAtoms::div;
nsIAtom* nsHTMLAtoms::dl;
-nsIAtom* nsHTMLAtoms::dropDownVisible;
-nsIAtom* nsHTMLAtoms::dropDownHidden;
-nsIAtom* nsHTMLAtoms::dropDownBtnOut;
-nsIAtom* nsHTMLAtoms::dropDownBtnPressed;
-nsIAtom* nsHTMLAtoms::dropDownList;
+nsIAtom* nsHTMLAtoms::dropDownListPseudo;
nsIAtom* nsHTMLAtoms::embed;
nsIAtom* nsHTMLAtoms::encoding;
nsIAtom* nsHTMLAtoms::enctype;
@@ -343,10 +337,8 @@ void nsHTMLAtoms::AddrefAtoms()
colgroup = NS_NewAtom("colgroup");
cols = NS_NewAtom("cols");
colspan = NS_NewAtom("colspan");
+ combobox = NS_NewAtom("combobox");
columnPseudo = NS_NewAtom(":body-column");
- comboText = NS_NewAtom(":-moz-combobox-text");
- comboTextSelected = NS_NewAtom(":-moz-combobox-textselected");
- comboTextSelectedFocus = NS_NewAtom(":-moz-combobox-textselectedfocus");
commentPseudo = NS_NewAtom(":-moz-comment");
compact = NS_NewAtom("compact");
content = NS_NewAtom("content");
@@ -360,11 +352,7 @@ void nsHTMLAtoms::AddrefAtoms()
div = NS_NewAtom("div");
disabled = NS_NewAtom("disabled");
dl = NS_NewAtom("dl");
- dropDownVisible = NS_NewAtom(":-moz-dropdown-visible");
- dropDownHidden = NS_NewAtom(":-moz-dropdown-hidden");
- dropDownBtnOut = NS_NewAtom(":-moz-dropdown-btn-out");
- dropDownBtnPressed = NS_NewAtom(":-moz-dropdown-btn-pressed");
- dropDownList = NS_NewAtom(":-moz-dropdown-list");
+ dropDownListPseudo = NS_NewAtom(":-moz-dropdown-list");
datetime = NS_NewAtom("datetime");
data = NS_NewAtom("data");
@@ -611,10 +599,8 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(colgroup);
NS_RELEASE(cols);
NS_RELEASE(colspan);
+ NS_RELEASE(combobox);
NS_RELEASE(columnPseudo);
- NS_RELEASE(comboText);
- NS_RELEASE(comboTextSelected);
- NS_RELEASE(comboTextSelectedFocus);
NS_RELEASE(commentPseudo);
NS_RELEASE(compact);
NS_RELEASE(content);
@@ -630,11 +616,7 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(disabled);
NS_RELEASE(div);
NS_RELEASE(dl);
- NS_RELEASE(dropDownVisible);
- NS_RELEASE(dropDownHidden);
- NS_RELEASE(dropDownBtnOut);
- NS_RELEASE(dropDownBtnPressed);
- NS_RELEASE(dropDownList);
+ NS_RELEASE(dropDownListPseudo);
NS_RELEASE(embed);
NS_RELEASE(encoding);
NS_RELEASE(face);
diff --git a/mozilla/content/shared/src/nsLayoutAtoms.cpp b/mozilla/content/shared/src/nsLayoutAtoms.cpp
index 27bf14d20c1..77e1f429362 100644
--- a/mozilla/content/shared/src/nsLayoutAtoms.cpp
+++ b/mozilla/content/shared/src/nsLayoutAtoms.cpp
@@ -42,6 +42,7 @@ nsIAtom* nsLayoutAtoms::bulletList;
nsIAtom* nsLayoutAtoms::colGroupList;
nsIAtom* nsLayoutAtoms::fixedList;
nsIAtom* nsLayoutAtoms::floaterList;
+nsIAtom* nsLayoutAtoms::popupList;
// pseudo tag names for non-element content
nsIAtom* nsLayoutAtoms::commentTagName;
@@ -96,6 +97,7 @@ void nsLayoutAtoms::AddrefAtoms()
colGroupList = NS_NewAtom("ColGroup-list");
fixedList = NS_NewAtom("Fixed-list");
floaterList = NS_NewAtom("Floater-list");
+ popupList = NS_NewAtom("Popup-list");
commentTagName = NS_NewAtom("__moz_comment");
textTagName = NS_NewAtom("__moz_text");
@@ -150,6 +152,7 @@ void nsLayoutAtoms::ReleaseAtoms()
NS_RELEASE(colGroupList);
NS_RELEASE(fixedList);
NS_RELEASE(floaterList);
+ NS_RELEASE(popupList);
NS_RELEASE(commentTagName);
NS_RELEASE(textTagName);
diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp
index 34d8bc46839..75a5ab705f7 100644
--- a/mozilla/layout/base/nsCSSFrameConstructor.cpp
+++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp
@@ -2397,140 +2397,88 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContex
if (eWidgetRendering_Gfx == mode) {
// Construct a frame-based listbox or combobox
- nsIDOMHTMLSelectElement* dselect = nsnull;
+ nsIDOMHTMLSelectElement* select = nsnull;
PRInt32 size = 1;
- nsresult result = aContent->QueryInterface(kIDOMHTMLSelectElementIID, (void**)&dselect);
- if (NS_OK == result) {
- result = dselect->GetSize(&size);
+ nsresult result = aContent->QueryInterface(kIDOMHTMLSelectElementIID, (void**)&select);
+ if (NS_SUCCEEDED(result)) {
+ result = select->GetSize(&size);
if ((1 == size) || (kNoSizeSpecified == size)) {
- // Construct a frame-based combo box
- nsIFrame * comboboxFrame;
- rv = NS_NewComboboxControlFrame(&comboboxFrame);
+ // Construct a frame-based combo box.
+ // The frame-based combo box is built out of tree parts. A display area, a button and
+ // a dropdown list. The display area and button are created through anonymous content.
+ // The drop-down list's frame is created explicitly. The combobox frame shares it's content
+ // with the drop-down list.
+ nsIFrame * comboboxFrame;
+ rv = NS_NewComboboxControlFrame(&comboboxFrame);
- nsIFrame* geometricParent = aParentFrame;
- if (aIsAbsolutelyPositioned) {
- geometricParent = aState.mAbsoluteItems.containingBlock;
- } else if (aIsFixedPositioned) {
- geometricParent = aState.mFixedItems.containingBlock;
+ // Determine geometric parent for the combobox frame
+ nsIFrame* geometricParent = aParentFrame;
+ if (aIsAbsolutelyPositioned) {
+ geometricParent = aState.mAbsoluteItems.containingBlock;
+ } else if (aIsFixedPositioned) {
+ geometricParent = aState.mFixedItems.containingBlock;
+ }
+ // Initialize the combobox frame
+ comboboxFrame->Init(*aPresContext, aContent, geometricParent, aStyleContext, nsnull);
+ nsIComboboxControlFrame* comboBox = nsnull;
+ if (NS_SUCCEEDED(comboboxFrame->QueryInterface(kIComboboxControlFrameIID, (void**)&comboBox))) {
+ // Create a listbox
+ nsIFrame * listFrame;
+ rv = NS_NewListControlFrame(&listFrame);
+
+ // Notify the listbox that it is being used as a dropdown list.
+ nsIListControlFrame * listControlFrame;
+ if (NS_SUCCEEDED(listFrame->QueryInterface(kIListControlFrameIID, (void**)&listControlFrame))) {
+ listControlFrame->SetComboboxFrame(comboboxFrame);
}
-
- comboboxFrame->Init(*aPresContext, aContent, geometricParent, aStyleContext, nsnull);
- nsIComboboxControlFrame* comboBox = nsnull;
- if (NS_OK == comboboxFrame->QueryInterface(kIComboboxControlFrameIID, (void**)&comboBox)) {
- nsIFrame * listFrame;
- rv = NS_NewListControlFrame(&listFrame);
-
- // Get the style context that has been set for the combo box so it can be passed used
- // to create the style context's for the drop down list.
- nsIStyleContext* comboStyleContext;
- comboboxFrame->GetStyleContext(&comboStyleContext);
-
- // This is important to do before it is initialized
- // it tells it that it is in "DropDown Mode"
- nsIListControlFrame * listControlFrame;
- if (NS_OK == listFrame->QueryInterface(kIListControlFrameIID, (void**)&listControlFrame)) {
- listControlFrame->SetComboboxFrame(comboboxFrame);
- }
-
- //XXX: TODO: Make sure that a failure to resolve the following
- //pseudo style will still work.
-
- // Set up the Pseudo Style contents
-
- // Dropdown list style
- nsCOMPtr listStyle;
- aPresContext->ResolvePseudoStyleContextFor
- (aContent, nsHTMLAtoms::dropDownList, comboStyleContext, PR_FALSE,
- getter_AddRefs(listStyle));
+ // Notify combobox that it should use the listbox as it's popup
+ comboBox->SetDropDown(listFrame);
- // Dropdown list visible style
- nsCOMPtr visiblePseudoStyle;
- aPresContext->ResolvePseudoStyleContextFor
- (aContent, nsHTMLAtoms::dropDownVisible, comboStyleContext, PR_FALSE,
- getter_AddRefs(visiblePseudoStyle));
-
- // Dropdown list hidden style
- nsCOMPtr hiddenPseudoStyle;
- aPresContext->ResolvePseudoStyleContextFor
- (aContent, nsHTMLAtoms::dropDownHidden, comboStyleContext, PR_FALSE,
- getter_AddRefs(hiddenPseudoStyle));
+ // Resolve psuedo element style for the dropdown list
+ nsCOMPtr listStyle;
+ rv = aPresContext->ResolvePseudoStyleContextFor(aContent,
+ nsHTMLAtoms::dropDownListPseudo,
+ aStyleContext,
+ PR_FALSE,
+ getter_AddRefs(listStyle));
- // Done creating drop-down list style contexts
- NS_RELEASE(comboStyleContext);
+ // Initialize the scroll frame positioned. Note that it is NOT initialized as
+ // absolutely positioned.
+ nsIFrame* newFrame = nsnull;
+ InitializeScrollFrame(aPresContext, aState, listFrame, aContent, comboboxFrame,
+ listStyle, newFrame, PR_FALSE, PR_FALSE, PR_TRUE);
- // Initialize the scroll frame as absolutely positioned.
- InitializeScrollFrame(aPresContext, aState, listFrame, aContent, comboboxFrame,
- listStyle, aNewFrame, PR_TRUE, PR_FALSE, PR_TRUE);
+ // Set flag so the events go to the listFrame not child frames.
+ // XXX: We should replace this with a real widget manager similar
+ // to how the nsFormControlFrame works. Re-directing events is a temporary Kludge.
+ nsIView *listView;
+ listFrame->GetView(&listView);
+ NS_ASSERTION(nsnull != listView,"ListFrame's view is nsnull");
+ listView->SetViewFlags(NS_VIEW_PUBLIC_FLAG_DONT_CHECK_CHILDREN);
-
- // Set flag so the events go to the listFrame not child frames.
- // XXX: We should replace this with a real widget manager similar
- // to how the nsFormControlFrame works.
- // Re-directing events is a temporary Kludge.
- nsIView *listView;
- listFrame->GetView(&listView);
- NS_ASSERTION(nsnull != listView,"ListFrame's view is nsnull");
- listView->SetViewFlags(NS_VIEW_PUBLIC_FLAG_DONT_CHECK_CHILDREN);
-
- // Set initial visibility to hidden for the drop-down list
- // XXX: This should not be necessary. Need to restructure the combo box as follows:
- // Derive nsComboboxFrame from nsAreaFrame. Attach the placeholder frame, a label frame and
- // a button frame. Override reresolve style context and reresolve the style on the ListBox.
- // The event state manager should then be asked to set active and non-active based on
- // The mouse click this would get rid of all of the ugly code here. The setting of the active
- // Should cause re-resolution of the AreaFrame which will re-sync it. KMM.
- listFrame->ReResolveStyleContext(aPresContext, hiddenPseudoStyle, NS_STYLE_HINT_NONE, nsnull, nsnull);
- listView->SetVisibility(nsViewVisibility_kHide);
-
-
- // Create a place holder frame for the dropdown list
- nsIFrame* placeholderFrame = nsnull;
- CreatePlaceholderFrameFor(aPresContext, aContent, aNewFrame, aStyleContext,
- aParentFrame, &placeholderFrame);
- aFrameItems.AddChild(placeholderFrame);
-
- // Add the absolutely positioned frame to its containing block's list
- // of child frames
- aState.mAbsoluteItems.AddChild(listFrame);
-
- listFrame = aNewFrame;
-
- // This needs to be done "after" the ListFrame has it's ChildList set
- // because the SetInitChildList intializes the ListBox selection state
- // and this method initializes the ComboBox's selection state
- comboBox->SetDropDown(placeholderFrame, listFrame);
-
-
- // Set up the Pseudo Style contents for combo box button pressed and
- // out.
- //XXX: TODO: Make this work even if resolving the pseudo style fails.
-
- nsCOMPtr outPseudoStyle;
- aPresContext->ResolvePseudoStyleContextFor
- (aContent, nsHTMLAtoms::dropDownBtnOut, aStyleContext, PR_FALSE,
- getter_AddRefs(outPseudoStyle));
-
- nsCOMPtr pressPseudoStyle;
- aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::dropDownBtnPressed,
- aStyleContext, PR_FALSE, getter_AddRefs(pressPseudoStyle));
-
- comboBox->SetDropDownStyleContexts(visiblePseudoStyle, hiddenPseudoStyle);
- comboBox->SetButtonStyleContexts(outPseudoStyle, pressPseudoStyle);
+ nsIFrame* frame = nsnull;
+ if (NS_SUCCEEDED(comboboxFrame->QueryInterface(kIFrameIID, (void**)&frame))) {
+ nsFrameItems childItems;
- nsIFrame* frame = nsnull;
- if (NS_OK == comboboxFrame->QueryInterface(kIFrameIID, (void**)&frame)) {
- nsFrameItems childItems;
- frame->SetInitialChildList(*aPresContext, nsnull,
- childItems.childList);
- }
- aProcessChildren = PR_FALSE;
- //XXX: TODO: Need to set an option on the view that was created for the dropdown list
- //to be a borderless top-level window.
-
- aNewFrame = comboboxFrame;
- aFrameHasBeenInitialized = PR_TRUE;
- }
+ // Create display and button frames from the combobox'es anonymous content
+ CreateAnonymousFrames(aPresContext, nsHTMLAtoms::combobox, aState, aContent, frame,
+ childItems);
+
+ frame->SetInitialChildList(*aPresContext, nsnull,
+ childItems.childList);
+ // Initialize the additional popup child list which contains the dropdown list frame.
+ nsFrameItems popupItems;
+ popupItems.AddChild(listFrame);
+ frame->SetInitialChildList(*aPresContext, nsLayoutAtoms::popupList,
+ popupItems.childList);
+ }
+ // Don't process, the children, They are already processed by the InitializeScrollFrame
+ // call above.
+ aProcessChildren = PR_FALSE;
+ aNewFrame = comboboxFrame;
+ aFrameHasBeenInitialized = PR_TRUE;
+ }
} else {
// Construct a frame-based list box
nsIFrame * listFrame;
@@ -2550,7 +2498,7 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContex
listView->SetViewFlags(NS_VIEW_PUBLIC_FLAG_DONT_CHECK_CHILDREN);
aFrameHasBeenInitialized = PR_TRUE;
}
- NS_RELEASE(dselect);
+ NS_RELEASE(select);
} else {
rv = NS_NewSelectControlFrame(&aNewFrame);
}
@@ -2739,6 +2687,7 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext
PR_TRUE, childItems);
}
+
// if there are any anonymous children create frames for them
CreateAnonymousFrames(aPresContext, aTag, aState, aContent, newFrame,
childItems);
@@ -2818,14 +2767,21 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresContext* aPresConte
// only these tags types can have anonymous content. We do this check for performance
// reasons. If we did a query interface on every tag it would be very inefficient.
if (aTag != nsHTMLAtoms::input &&
+ aTag != nsHTMLAtoms::combobox &&
aTag != nsXULAtoms::slider &&
aTag != nsXULAtoms::splitter &&
- aTag != nsXULAtoms::scrollbar) {
+ aTag != nsXULAtoms::scrollbar
+ ) {
return NS_OK;
}
-
+ // get the document
+ nsIDocument* doc = nsnull;
+ nsresult rv = aContent->GetDocument(doc);
+ if (NS_FAILED(rv) || !doc)
+ return rv;
+
nsCOMPtr creator(do_QueryInterface(aNewFrame));
if (!creator)
@@ -2849,6 +2805,8 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresContext* aPresConte
nsCOMPtr content(do_QueryInterface(node));
content->SetParent(aContent);
+ content->SetDocument(doc, PR_TRUE);
+
// create the frame and attach it to our frame
ConstructFrame(aPresContext, aState, content, aNewFrame, PR_FALSE, aChildItems);
}
diff --git a/mozilla/layout/base/nsCSSFrameConstructor.h b/mozilla/layout/base/nsCSSFrameConstructor.h
index 29b85b2444b..93584718afc 100644
--- a/mozilla/layout/base/nsCSSFrameConstructor.h
+++ b/mozilla/layout/base/nsCSSFrameConstructor.h
@@ -407,6 +407,7 @@ protected:
nsresult ConstructTextControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame);
+
nsresult ConstructSelectFrame(nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
diff --git a/mozilla/layout/base/nsLayoutAtoms.cpp b/mozilla/layout/base/nsLayoutAtoms.cpp
index 27bf14d20c1..77e1f429362 100644
--- a/mozilla/layout/base/nsLayoutAtoms.cpp
+++ b/mozilla/layout/base/nsLayoutAtoms.cpp
@@ -42,6 +42,7 @@ nsIAtom* nsLayoutAtoms::bulletList;
nsIAtom* nsLayoutAtoms::colGroupList;
nsIAtom* nsLayoutAtoms::fixedList;
nsIAtom* nsLayoutAtoms::floaterList;
+nsIAtom* nsLayoutAtoms::popupList;
// pseudo tag names for non-element content
nsIAtom* nsLayoutAtoms::commentTagName;
@@ -96,6 +97,7 @@ void nsLayoutAtoms::AddrefAtoms()
colGroupList = NS_NewAtom("ColGroup-list");
fixedList = NS_NewAtom("Fixed-list");
floaterList = NS_NewAtom("Floater-list");
+ popupList = NS_NewAtom("Popup-list");
commentTagName = NS_NewAtom("__moz_comment");
textTagName = NS_NewAtom("__moz_text");
@@ -150,6 +152,7 @@ void nsLayoutAtoms::ReleaseAtoms()
NS_RELEASE(colGroupList);
NS_RELEASE(fixedList);
NS_RELEASE(floaterList);
+ NS_RELEASE(popupList);
NS_RELEASE(commentTagName);
NS_RELEASE(textTagName);
diff --git a/mozilla/layout/base/nsLayoutAtoms.h b/mozilla/layout/base/nsLayoutAtoms.h
index d949fce3f2f..81769d9c977 100644
--- a/mozilla/layout/base/nsLayoutAtoms.h
+++ b/mozilla/layout/base/nsLayoutAtoms.h
@@ -56,6 +56,7 @@ public:
static nsIAtom* colGroupList;
static nsIAtom* fixedList;
static nsIAtom* floaterList;
+ static nsIAtom* popupList;
// Alphabetical list of pseudo tag names for non-element content
static nsIAtom* commentTagName;
diff --git a/mozilla/layout/base/public/nsLayoutAtoms.h b/mozilla/layout/base/public/nsLayoutAtoms.h
index d949fce3f2f..81769d9c977 100644
--- a/mozilla/layout/base/public/nsLayoutAtoms.h
+++ b/mozilla/layout/base/public/nsLayoutAtoms.h
@@ -56,6 +56,7 @@ public:
static nsIAtom* colGroupList;
static nsIAtom* fixedList;
static nsIAtom* floaterList;
+ static nsIAtom* popupList;
// Alphabetical list of pseudo tag names for non-element content
static nsIAtom* commentTagName;
diff --git a/mozilla/layout/base/src/nsLayoutAtoms.cpp b/mozilla/layout/base/src/nsLayoutAtoms.cpp
index 27bf14d20c1..77e1f429362 100644
--- a/mozilla/layout/base/src/nsLayoutAtoms.cpp
+++ b/mozilla/layout/base/src/nsLayoutAtoms.cpp
@@ -42,6 +42,7 @@ nsIAtom* nsLayoutAtoms::bulletList;
nsIAtom* nsLayoutAtoms::colGroupList;
nsIAtom* nsLayoutAtoms::fixedList;
nsIAtom* nsLayoutAtoms::floaterList;
+nsIAtom* nsLayoutAtoms::popupList;
// pseudo tag names for non-element content
nsIAtom* nsLayoutAtoms::commentTagName;
@@ -96,6 +97,7 @@ void nsLayoutAtoms::AddrefAtoms()
colGroupList = NS_NewAtom("ColGroup-list");
fixedList = NS_NewAtom("Fixed-list");
floaterList = NS_NewAtom("Floater-list");
+ popupList = NS_NewAtom("Popup-list");
commentTagName = NS_NewAtom("__moz_comment");
textTagName = NS_NewAtom("__moz_text");
@@ -150,6 +152,7 @@ void nsLayoutAtoms::ReleaseAtoms()
NS_RELEASE(colGroupList);
NS_RELEASE(fixedList);
NS_RELEASE(floaterList);
+ NS_RELEASE(popupList);
NS_RELEASE(commentTagName);
NS_RELEASE(textTagName);
diff --git a/mozilla/layout/forms/nsComboboxControlFrame.cpp b/mozilla/layout/forms/nsComboboxControlFrame.cpp
index ddb75962403..0202a7ef1aa 100644
--- a/mozilla/layout/forms/nsComboboxControlFrame.cpp
+++ b/mozilla/layout/forms/nsComboboxControlFrame.cpp
@@ -18,51 +18,32 @@
#include "nsCOMPtr.h"
#include "nsComboboxControlFrame.h"
#include "nsFormFrame.h"
-#include "nsButtonControlFrame.h"
-#include "nsTextControlFrame.h"
-#include "nsIContent.h"
-#include "prtypes.h"
-#include "nsIAtom.h"
-#include "nsIPresContext.h"
+#include "nsFormControlFrame.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLAtoms.h"
-#include "nsIFileWidget.h"
-#include "nsITextWidget.h"
-#include "nsWidgetsCID.h"
-#include "nsIComponentManager.h"
-#include "nsIView.h"
#include "nsHTMLParts.h"
-#include "nsIDOMHTMLInputElement.h"
#include "nsIFormControl.h"
#include "nsINameSpaceManager.h"
-#include "nsITextContent.h"
-
-// Used for Paint
-#include "nsCSSRendering.h"
-#include "nsIDeviceContext.h"
-
-#include "nsIPresShell.h"
-#include "nsIView.h"
-#include "nsIViewManager.h"
-#include "nsViewsCID.h"
+#include "nsIDOMEventReceiver.h"
+#include "nsLayoutAtoms.h"
#include "nsIDOMElement.h"
#include "nsListControlFrame.h"
#include "nsIListControlFrame.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMHTMLOptionElement.h"
+#include "nsIPresShell.h"
+#include "nsISupportsArray.h"
+#include "nsIDeviceContext.h"
+#include "nsIView.h"
-static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
-static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
-static NS_DEFINE_IID(kCFileWidgetCID, NS_FILEWIDGET_CID);
-static NS_DEFINE_IID(kIFileWidgetIID, NS_IFILEWIDGET_IID);
-static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID);
static NS_DEFINE_IID(kIComboboxControlFrameIID, NS_ICOMBOBOXCONTROLFRAME_IID);
-static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
-static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
static NS_DEFINE_IID(kIListControlFrameIID, NS_ILISTCONTROLFRAME_IID);
+static NS_DEFINE_IID(kIDOMMouseListenerIID, NS_IDOMMOUSELISTENER_IID);
+static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
+static NS_DEFINE_IID(kIAnonymousContentCreatorIID, NS_IANONYMOUS_CONTENT_CREATOR_IID);
// Drop down list event management.
// The combo box uses the following strategy for managing the
@@ -76,6 +57,11 @@ static NS_DEFINE_IID(kIListControlFrameIID, NS_ILISTCONTROLFRAME_IID);
// The ListWasSelected code will turn off mouse-capture for the drop-down list.
// The drop-down list does not explicitly set capture when it is in the drop-down mode.
+
+//XXX: This is temporary. It simulates psuedo states by using a attribute selector on
+
+const char * kMozDropdownActive = "-moz-dropdown-active";
+
nsresult
NS_NewComboboxControlFrame(nsIFrame** aNewFrame)
{
@@ -92,29 +78,30 @@ NS_NewComboboxControlFrame(nsIFrame** aNewFrame)
}
nsComboboxControlFrame::nsComboboxControlFrame()
- : nsHTMLContainerFrame()
+ : nsAreaFrame()
{
- mFormFrame = nsnull;
- mListFrame = nsnull;
+ mPresContext = nsnull;
+ mFormFrame = nsnull;
mListControlFrame = nsnull;
- mPlaceHolderFrame = nsnull;
- mVisibleStyleContext = nsnull;
- mHiddenStyleContext = nsnull;
- mCurrentStyleContext = nsnull;
- mBlockTextStyle = nsnull;
- mBlockTextSelectedStyle = nsnull;
- mBlockTextSelectedFocusStyle = nsnull;
- mFirstTime = PR_TRUE;
- mGotFocus = PR_FALSE;
+ mTextStr = "";
+ mDisplayContent = nsnull;
+ mButtonContent = nsnull;
+ mDroppedDown = PR_FALSE;
+ mDisplayFrame = nsnull;
+ mButtonFrame = nsnull;
+ mDropdownFrame = nsnull;
+
+ //Shrink the area around it's contents
+ SetFlags(NS_BLOCK_SHRINK_WRAP);
}
//--------------------------------------------------------------
nsComboboxControlFrame::~nsComboboxControlFrame()
{
- NS_IF_RELEASE(mVisibleStyleContext);
- NS_IF_RELEASE(mHiddenStyleContext);
- NS_IF_RELEASE(mBlockTextStyle);
mFormFrame = nsnull;
+ NS_IF_RELEASE(mPresContext);
+ NS_IF_RELEASE(mDisplayContent);
+ NS_IF_RELEASE(mButtonContent);
}
//--------------------------------------------------------------
@@ -132,9 +119,32 @@ nsComboboxControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
if (aIID.Equals(kIFormControlFrameIID)) {
*aInstancePtr = (void*) ((nsIFormControlFrame*) this);
return NS_OK;
+ } else if (aIID.Equals(kIDOMMouseListenerIID)) {
+ *aInstancePtr = (void*)(nsIDOMMouseListener*) this;
+ NS_ADDREF_THIS();
+ return NS_OK;
+ } else if (aIID.Equals(kIAnonymousContentCreatorIID)) {
+ *aInstancePtr = (void*)(nsIAnonymousContentCreator*) this;
+ NS_ADDREF_THIS();
+ return NS_OK;
}
- return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
+ return nsAreaFrame::QueryInterface(aIID, aInstancePtr);
+}
+
+
+NS_IMETHODIMP
+nsComboboxControlFrame::Init(nsIPresContext& aPresContext,
+ nsIContent* aContent,
+ nsIFrame* aParent,
+ nsIStyleContext* aContext,
+ nsIFrame* aPrevInFlow)
+{
+ // Need to hold on the pres context because it is used later in methods
+ // which don't have it passed in.
+ mPresContext = &aPresContext;
+ NS_ADDREF(mPresContext);
+ return nsAreaFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
}
//--------------------------------------------------------------
@@ -149,15 +159,22 @@ nsComboboxControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter)
// 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()
+void
+nsComboboxControlFrame::InitTextStr(PRBool aUpdate)
{
+ nsIFormControlFrame* fcFrame = nsnull;
+ nsIFrame* dropdownFrame = GetDropdownFrame();
+ nsresult result = dropdownFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
+
+ // Reset the list, so we can ask it for it's selected item.
+ fcFrame->Reset();
+
// Update the selected text string
mListControlFrame->GetSelectedItem(mTextStr);
if (mTextStr == "") {
// No selection so use the first item in the list box
- nsIFormControlFrame* fcFrame = nsnull;
- nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
+
if ((NS_OK == result) && (nsnull != fcFrame)) {
// Set listbox selection to first item in the list box
fcFrame->SetProperty(nsHTMLAtoms::selectedindex, "0");
@@ -165,21 +182,28 @@ void nsComboboxControlFrame::InitTextStr()
mListControlFrame->GetSelectedItem(mTextStr);
}
}
+
+ // Update the display by setting the value attribute
+ mDisplayContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, mTextStr, aUpdate);
}
//--------------------------------------------------------------
+// Reset the combo box back to it original state.
+
void
nsComboboxControlFrame::Reset()
{
- SetFocus(PR_TRUE, PR_TRUE);
+ // Reset the dropdown list to its original state
nsIFormControlFrame* fcFrame = nsnull;
- nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
+ nsIFrame* dropdownFrame = GetDropdownFrame();
+ nsresult result = dropdownFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
if ((NS_OK == result) && (nsnull != fcFrame)) {
fcFrame->Reset();
}
- InitTextStr();
+ // Update the combobox using the text string returned from the dropdown list
+ InitTextStr(PR_TRUE);
}
void
@@ -190,7 +214,6 @@ nsComboboxControlFrame::PostCreateWidget(nsIPresContext* aPresContext,
Reset();
}
-
//--------------------------------------------------------------
NS_IMETHODIMP
nsComboboxControlFrame::GetType(PRInt32* aType) const
@@ -224,7 +247,7 @@ nsComboboxControlFrame::GetFont(nsIPresContext* aPresContext,
nscoord
nsComboboxControlFrame::GetVerticalBorderWidth(float aPixToTwip) const
{
- return NSIntPixelsToTwips(3, aPixToTwip);
+ return 0;
}
@@ -232,7 +255,7 @@ nsComboboxControlFrame::GetVerticalBorderWidth(float aPixToTwip) const
nscoord
nsComboboxControlFrame::GetHorizontalBorderWidth(float aPixToTwip) const
{
- return GetVerticalBorderWidth(aPixToTwip);
+ return 0;
}
@@ -255,335 +278,421 @@ nsComboboxControlFrame::GetHorizontalInsidePadding(nsIPresContext& aPresContext,
}
-//--------------------------------------------------------------
+
void
nsComboboxControlFrame::SetFocus(PRBool aOn, PRBool aRepaint)
{
- //XXX: TODO Make set focus work
- //mContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::kClass, "SELECTED", PR_TRUE);
- mGotFocus = aOn;
- if (aRepaint) {
- nsFormControlHelper::ForceDrawFrame(this);
+ //XXX: TODO Implement focus for combobox.
+}
+
+// Toggle dropdown list.
+
+void
+nsComboboxControlFrame::ToggleList(nsIPresContext* aPresContext)
+{
+ if (PR_TRUE == mDroppedDown) {
+ ShowList(aPresContext, PR_FALSE);
+ } else {
+ ShowList(aPresContext, PR_TRUE);
}
}
-//--------------------------------------------------------------
+
+void
+nsComboboxControlFrame::ShowPopup(PRBool aShowPopup)
+{
+ //XXX: This is temporary. It simulates a psuedo dropdown states by using a attribute selector
+ // This will not be need if the event state supports active states for use with the dropdown list
+ // Currently, the event state manager will reset the active state to the content which has focus
+ // which causes the active state to be removed from the event state manager immediately after it
+ // it the select is set to the active state.
+
+ nsCOMPtr activeAtom ( dont_QueryInterface(NS_NewAtom(kMozDropdownActive)));
+ if (PR_TRUE == aShowPopup) {
+ mContent->SetAttribute(kNameSpaceID_None, activeAtom, "", PR_TRUE);
+ } else {
+ mContent->UnsetAttribute(kNameSpaceID_None, activeAtom, PR_TRUE);
+ }
+}
+
+// Show the dropdown list
+
+void
+nsComboboxControlFrame::ShowList(nsIPresContext* aPresContext, PRBool aShowList)
+{
+ if (PR_TRUE == aShowList) {
+ mListControlFrame->AboutToDropDown();
+ ShowPopup(PR_TRUE);
+ mDroppedDown = PR_TRUE;
+ // The listcontrol frame will call back to the nsComboboxControlFrame's ListWasSelected
+ // which will stop the capture.
+ mListControlFrame->CaptureMouseEvents(PR_TRUE);
+ } else {
+ ShowPopup(PR_FALSE);
+ mDroppedDown = PR_FALSE;
+ }
+}
+
+
+//-------------------------------------------------------------
// this is in response to the MouseClick from the containing browse button
// XXX: TODO still need to get filters from accept attribute
-void nsComboboxControlFrame::MouseClicked(nsIPresContext* aPresContext)
+void
+nsComboboxControlFrame::MouseClicked(nsIPresContext* aPresContext)
{
- if (nsnull != mListControlFrame) {
- //XXX: Make this work SetFocus(PR_FALSE, PR_TRUE);
- mCurrentStyleContext = (mCurrentStyleContext == mHiddenStyleContext ? mVisibleStyleContext : mHiddenStyleContext);
- if (mCurrentStyleContext == mVisibleStyleContext) {
- mListControlFrame->AboutToDropDown();
-
- nsIFormControlFrame* fcFrame = nsnull;
- nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
- if ((NS_OK == result) && (nsnull != fcFrame)) {
- //XXX: Make this work fcFrame->SetFocus(PR_TRUE, PR_FALSE);
- }
+ ToggleList(aPresContext);
+}
- } else {
- //XXX: Make this work SetFocus(PR_TRUE, PR_TRUE);
- }
- //XXX: This should not be necessary. Need to restructure the combo box as follows:
- // Derive nsComboboxFrame from nsAreaFrame. Attach the placeholder frame, a label frame and
- // a button frame. Override reresolve style context and reresolve the style on the ListBox.
- // The event state manager should then be asked to set active and non-active based on
- // The mouse click this would get rid of all of the ugly code here. The setting of the active
- // Should cause re-resolution of the AreaFrame which will re-sync it. KMM.
- mListFrame->ReResolveStyleContext(aPresContext, mCurrentStyleContext, NS_STYLE_HINT_NONE, nsnull, nsnull);
-
- // Resync view with frame.
- const nsStyleDisplay* disp = (const
- nsStyleDisplay*)mCurrentStyleContext->GetStyleData(eStyleStruct_Display);
- nsIView * view;
- mListFrame->GetView(&view);
- if (view) {
- view->SetVisibility(NS_STYLE_VISIBILITY_HIDDEN == disp->mVisible ?
- nsViewVisibility_kHide:nsViewVisibility_kShow);
- }
- nsFormControlHelper::ForceDrawFrame(mListFrame);
- //XXX: End of the ugly code.
-
+nsresult
+nsComboboxControlFrame::ReflowComboChildFrame(nsIFrame* aFrame,
+ nsIPresContext& aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ const nsHTMLReflowState& aReflowState,
+ nsReflowStatus& aStatus,
+ nscoord aAvailableWidth,
+ nscoord aAvailableHeight)
+{
+ // Constrain the child's width and height to aAvailableWidth and aAvailableHeight
+ nsSize availSize(aAvailableWidth, aAvailableHeight);
+ nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aFrame,
+ availSize);
+ kidReflowState.computedWidth = aAvailableWidth;
+ kidReflowState.computedHeight = aAvailableHeight;
+
+ // Reflow child
+ nsresult rv = ReflowChild(aFrame, aPresContext, aDesiredSize, kidReflowState, aStatus);
+
+ // Set the child's width and height to it's desired size
+ nsRect rect;
+ aFrame->GetRect(rect);
+ rect.width = aDesiredSize.width;
+ rect.height = aDesiredSize.height;
+ aFrame->SetRect(rect);
+ return rv;
+}
+
+// Suggest a size for the child frame.
+// Only frames which implement the nsIFormControlFrame interface and
+// honor the SetSuggestedSize method will be placed and sized correctly.
+
+void
+nsComboboxControlFrame::SetChildFrameSize(nsIFrame* aFrame, nscoord aWidth, nscoord aHeight)
+{
+ nsIFormControlFrame* fcFrame = nsnull;
+ nsresult result = aFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
+ if (NS_SUCCEEDED(result) && (nsnull != fcFrame)) {
+ fcFrame->SetSuggestedSize(aWidth, aHeight);
}
}
-//--------------------------------------------------------------
-NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresContext,
+nsresult
+nsComboboxControlFrame::GetPrimaryComboFrame(nsIPresContext& aPresContext, nsIContent* aContent, nsIFrame** aFrame)
+{
+ nsresult rv = NS_OK;
+ // Get the primary frame from the presentation shell.
+ nsCOMPtr presShell;
+ rv = aPresContext.GetShell(getter_AddRefs(presShell));
+ if (NS_SUCCEEDED(rv) && presShell) {
+ presShell->GetPrimaryFrameFor(aContent, aFrame);
+ }
+ return rv;
+}
+
+nsIFrame*
+nsComboboxControlFrame::GetButtonFrame(nsIPresContext& aPresContext)
+{
+ if (mButtonFrame == nsnull) {
+ NS_ASSERTION(mButtonContent != nsnull, "nsComboboxControlFrame mButtonContent is null");
+ GetPrimaryComboFrame(aPresContext, mButtonContent, &mButtonFrame);
+ }
+
+ return mButtonFrame;
+}
+
+nsIFrame*
+nsComboboxControlFrame::GetDisplayFrame(nsIPresContext& aPresContext)
+{
+ if (mDisplayFrame == nsnull) {
+ NS_ASSERTION(mDisplayContent != nsnull, "nsComboboxControlFrame mDisplayContent is null");
+ GetPrimaryComboFrame(aPresContext, mDisplayContent, &mDisplayFrame);
+ }
+
+ return mDisplayFrame;
+}
+
+nsIFrame*
+nsComboboxControlFrame::GetDropdownFrame()
+{
+ return mDropdownFrame;
+}
+
+
+nsresult
+nsComboboxControlFrame::GetScreenHeight(nsIPresContext& aPresContext,
+ nscoord& aHeight)
+{
+ aHeight = 0;
+ nsIDeviceContext* context;
+ aPresContext.GetDeviceContext( &context );
+ if ( nsnull != context )
+ {
+ PRInt32 height;
+ PRInt32 width;
+ context->GetDeviceSurfaceDimensions(width, height);
+ float devUnits;
+ context->GetDevUnitsToAppUnits(devUnits);
+ aHeight = NSToIntRound(float( height) / devUnits );
+ NS_RELEASE( context );
+ return NS_OK;
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+
+nsresult
+nsComboboxControlFrame::PositionDropdown(nsIPresContext& aPresContext,
+ nscoord aHeight,
+ nsRect aAbsoluteTwipsRect,
+ nsRect aAbsolutePixelRect)
+{
+ // Position the dropdown list. It is positioned below the display frame if there is enough
+ // room on the screen to display the entire list. Otherwise it is placed above the display
+ // frame.
+
+ // Note: As first glance, it appears that you could simply get the absolute bounding box for the
+ // dropdown list by first getting it's view, then getting the view's nsIWidget, then asking the nsIWidget
+ // for it's AbsoluteBounds. The problem with this approach, is that the dropdown lists y location can
+ // change based on whether the dropdown is placed below or above the display frame.
+ // The approach, taken here is to get use the absolute position of the display frame and use it's location
+ // to determine if the dropdown will go offscreen.
+
+ // Use the height calculated for the area frame so it includes both
+ // the display and button heights.
+ nsresult rv = NS_OK;
+ nsIFrame* dropdownFrame = GetDropdownFrame();
+ nscoord dropdownYOffset = aHeight;
+/* XXX: Enable this code to debug popping up above the display frame, rather than below it
+ nscoord screenHeightInPixels = 0;
+ if (NS_SUCCEEDED(GetScreenHeight(aPresContext, screenHeightInPixels))) {
+ nsRect absoluteRect;
+
+ // Get the height of the dropdown list in pixels.
+ nsRect dropdownRect;
+ dropdownFrame->GetRect(dropdownRect);
+ float t2p;
+ aPresContext.GetTwipsToPixels(&t2p);
+ nscoord absoluteDropDownHeight = NSTwipsToIntPixels(dropdownRect.height, t2p);
+
+ // Check to see if the drop-down list will go offscreen
+ if (NS_SUCCEEDED(rv) && ((aAbsolutePixelRect.y + aAbsolutePixelRect.height + absoluteDropDownHeight) > screenHeightInPixels)) {
+ // move the dropdown list up
+ dropdownYOffset = - (aAbsoluteTwipsRect.height);
+ }
+ }
+*/
+
+ nsRect dropdownRect;
+ dropdownFrame->GetRect(dropdownRect);
+ dropdownRect.x = 0;
+ dropdownRect.y = dropdownYOffset;
+ dropdownFrame->SetRect(dropdownRect);
+
+ return rv;
+}
+
+
+// Calculate a frame's position in screen coordinates
+nsresult
+nsComboboxControlFrame::GetAbsoluteFramePosition(nsIPresContext& aPresContext,
+ nsIFrame *aFrame,
+ nsRect& aAbsoluteTwipsRect,
+ nsRect& aAbsolutePixelRect)
+{
+ //XXX: This code needs to take the view's offset into account when calculating
+ //the absolute coordinate of the frame.
+ nsresult rv = NS_OK;
+
+ aFrame->GetRect(aAbsoluteTwipsRect);
+
+ // Get conversions between twips and pixels
+ float t2p;
+ float p2t;
+ aPresContext.GetTwipsToPixels(&t2p);
+ aPresContext.GetPixelsToTwips(&p2t);
+
+ // Add in frame's offset from it it's containing view
+ nsIView *containingView = nsnull;
+ nsPoint offset;
+ rv = aFrame->GetOffsetFromView(offset, &containingView);
+ if (NS_SUCCEEDED(rv) && (nsnull != containingView)) {
+ aAbsoluteTwipsRect.x += offset.x;
+ aAbsoluteTwipsRect.y += offset.y;
+ // Addin the containing view's offset form it's containing widget
+ nsIWidget* widget = nsnull;
+ nscoord widgetx = 0;
+ nscoord widgety = 0;
+ rv = containingView->GetOffsetFromWidget(&widgetx, &widgety, widget);
+ if (NS_SUCCEEDED(rv) && (nsnull != widget)) {
+ aAbsoluteTwipsRect.x += widgetx;
+ aAbsoluteTwipsRect.y += widgety;
+
+ // Add in the absolute offset of the widget.
+ nsRect absBounds;
+ widget->GetAbsoluteBounds(absBounds);
+
+ // Convert widget coordinates to twips
+ aAbsoluteTwipsRect.x += NSIntPixelsToTwips(absBounds.x, p2t);
+ aAbsoluteTwipsRect.y += NSIntPixelsToTwips(absBounds.y, p2t);
+ NS_RELEASE(widget);
+ }
+ }
+
+ // convert to pixel coordinates
+ if (NS_SUCCEEDED(rv)) {
+ aAbsolutePixelRect.x = NSTwipsToIntPixels(aAbsoluteTwipsRect.x, t2p);
+ aAbsolutePixelRect.y = NSTwipsToIntPixels(aAbsoluteTwipsRect.y, t2p);
+ aAbsolutePixelRect.width = NSTwipsToIntPixels(aAbsoluteTwipsRect.width, t2p);
+ aAbsolutePixelRect.height = NSTwipsToIntPixels(aAbsoluteTwipsRect.height, t2p);
+ }
+
+ return rv;
+}
+
+
+NS_IMETHODIMP
+nsComboboxControlFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
- // XXX Combo box should be changed to be implemented as a label and button frame.
- // This would eliminate all of this Reflow code. KMM
+ nsresult rv = NS_OK;
+ nsIFrame* buttonFrame = GetButtonFrame(aPresContext);
+ nsIFrame* displayFrame = GetDisplayFrame(aPresContext);
+ nsIFrame* dropdownFrame = GetDropdownFrame();
- // add ourself as an nsIFormControlFrame
+ // Don't try to do any special sizing and positioning unless all of the frames
+ // have been created.
+ if ((nsnull == displayFrame) ||
+ (nsnull == buttonFrame) ||
+ (nsnull == dropdownFrame))
+ {
+ // Since combobox frames are missing just do a normal area frame reflow
+ return nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
+ }
+
+ // size of each part of the combo box
+ nsRect displayRect;
+ nsRect buttonRect;
+ nsRect dropdownRect;
+
+
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
nsFormFrame::AddFormControlFrame(aPresContext, *this);
}
+ // Get the current sizes of the combo box child frames
+ displayFrame->GetRect(displayRect);
+ buttonFrame->GetRect(buttonRect);
+ dropdownFrame->GetRect(dropdownRect);
- if (mFirstTime) {
- ReResolveStyleContext(&aPresContext, mStyleContext, NS_STYLE_HINT_REFLOW, nsnull, nsnull); // XXX This temporary
- mListFrame->ReResolveStyleContext(&aPresContext, mCurrentStyleContext, NS_STYLE_HINT_REFLOW, nsnull, nsnull);
- mFirstTime = PR_FALSE;
- InitTextStr();
- }
+ nsHTMLReflowState firstPassState(aReflowState);
- PRInt32 numChildren = mFrames.GetLength();
-
- if (1 == numChildren) {
- aPresContext.ResolvePseudoStyleContextFor(mContent, nsHTMLAtoms::comboText,
- mStyleContext, PR_FALSE,
- &mBlockTextStyle);
-
- // XXX This code should move to Init(), someday when the frame construction
- // changes are all done and Init() is always getting called...
- /*PRBool disabled = */nsFormFrame::GetDisabled(this);
- }
-
- nsIDOMHTMLSelectElement* select = nsListControlFrame::GetSelect(mContent);
- if (!select) {
- return NS_OK;
- }
- nsIDOMHTMLCollection* options = nsListControlFrame::GetOptions(mContent, select);
- if (!options) {
- NS_RELEASE(select);
- return NS_OK;
- }
-
- // get the css size
- nsSize styleSize;
- nsFormControlFrame::GetStyleSize(aPresContext, aReflowState, styleSize);
-
- // get the size of the longest option
- PRInt32 maxWidth = 1;
- PRUint32 numOptions;
- options->GetLength(&numOptions);
- for (PRUint32 i = 0; i < numOptions; i++) {
- nsIDOMHTMLOptionElement* option = nsListControlFrame::GetOption(*options, i);
- if (option) {
- nsAutoString text;
- if (NS_CONTENT_ATTR_HAS_VALUE != option->GetText(text)) {
- continue;
+ // Only reflow the display and button if they are the target of
+ // the incremental reflow, unless they change size. If they do
+ // then everything needs to be reflowed.
+ if (eReflowReason_Incremental == firstPassState.reason) {
+ nsIFrame* targetFrame;
+ firstPassState.reflowCommand->GetTarget(targetFrame);
+ if ((targetFrame == buttonFrame) || (targetFrame == displayFrame)) {
+ nsRect oldDisplayRect = displayRect;
+ nsRect oldButtonRect = buttonRect;
+ rv = nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
+ displayFrame->GetRect(displayRect);
+ buttonFrame->GetRect(buttonRect);
+ if ((oldDisplayRect == displayRect) && (oldButtonRect == buttonRect)) {
+ // Reposition the popup.
+ nsRect absoluteTwips;
+ nsRect absolutePixels;
+ GetAbsoluteFramePosition(aPresContext, displayFrame, absoluteTwips, absolutePixels);
+ PositionDropdown(aPresContext, displayRect.height, absoluteTwips, absolutePixels);
+ return rv;
}
- nsSize textSize;
- // use the style for the select rather that the option, since widgets don't support it
- nsFormControlHelper::GetTextSize(aPresContext, this, text, textSize, aReflowState.rendContext);
- if (textSize.width > maxWidth) {
- maxWidth = textSize.width;
- }
- NS_RELEASE(option);
}
+ nsIReflowCommand::ReflowType type;
+ aReflowState.reflowCommand->GetType(type);
+ firstPassState.reason = eReflowReason_StyleChange;
+ firstPassState.reflowCommand = nsnull;
}
- PRInt32 rowHeight = 0;
- nsSize desiredSize;
- nsSize minSize;
- PRBool widthExplicit, heightExplicit;
- nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull, nsnull,
- maxWidth, PR_TRUE, nsHTMLAtoms::size, 1);
- // XXX fix CalculateSize to return PRUint32
- PRUint32 numRows =
- (PRUint32)nsFormControlHelper::CalculateSize(&aPresContext, aReflowState.rendContext, this,
- styleSize, textSpec, desiredSize, minSize,
- widthExplicit, heightExplicit, rowHeight);
- float sp2t;
- float p2t;
- aPresContext.GetPixelsToTwips(&p2t);
- aPresContext.GetScaledPixelsToTwips(&sp2t);
- nscoord onePixel = NSIntPixelsToTwips(1, sp2t);
- nscoord extra = desiredSize.height - (rowHeight * numRows);
- numRows = (numOptions > 20 ? 20 : numOptions);
- desiredSize.height = (numRows * rowHeight) + extra;
- aDesiredSize.descent = 0;
- nsMargin border;
- const nsStyleSpacing* mySpacing = (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
- mySpacing->CalcBorderFor(this, border);
+ //Set the desired size for the button and display frame
+ if (NS_UNCONSTRAINEDSIZE == firstPassState.computedWidth) {
+ // A width has not been specified for the select so size the display area to
+ // match the width of the longest item in the drop-down list. The dropdown
+ // list has already been reflowed and sized to shrink around its contents above.
- float scale;
- float sbWidth;
- float sbHeight;
- nsCOMPtr context;
- aPresContext.GetDeviceContext(getter_AddRefs(context));
- context->GetCanonicalPixelScale(scale);
- context->GetScrollBarDimensions(sbWidth, sbHeight);
- PRInt32 scrollbarScaledWidth = PRInt32(sbWidth * scale);
+ // Reflow the dropdown shrink-wrapped.
+ nsHTMLReflowMetrics dropdownDesiredSize(aDesiredSize);
+ ReflowComboChildFrame(dropdownFrame, aPresContext, dropdownDesiredSize, firstPassState, aStatus, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
+ dropdownFrame->GetRect(dropdownRect);
+ // Get maximum size and height of a option in the dropdown
- nsFont font(aPresContext.GetDefaultFixedFontDeprecated());
- SystemAttrStruct sis;
- sis.mFont = &font;
- context->GetSystemAttribute(eSystemAttr_Font_Tooltips, &sis);
+ nsSize size;
+ mListControlFrame->GetMaximumSize(size);
- //XXX: This 14 pixel hardcode value here is bad. The style system should control
- //everyting. KMM
- nscoord horKludgeAdjustment = NSIntPixelsToTwips(14, p2t);
- nscoord horAdjustment = scrollbarScaledWidth + border.left + border.right + horKludgeAdjustment;
+ // Set width of display to match width of the drop down
+ SetChildFrameSize(displayFrame, dropdownRect.width, size.height);
- aDesiredSize.width = desiredSize.width + horAdjustment;
+ // Size the button to be the same height as the displayFrame
+ SetChildFrameSize(buttonFrame, size.height, size.height);
- nscoord verKludgeAdjustment = onePixel;
- nscoord verAdjustment = border.top + border.bottom + verKludgeAdjustment;
+ // Reflow display + button
+ nsAreaFrame::Reflow(aPresContext, aDesiredSize, firstPassState, aStatus);
+ displayFrame->GetRect(displayRect);
- aDesiredSize.height = rowHeight + verAdjustment;
+ // Reflow the dropdown list to match the width of the display + button
+ ReflowComboChildFrame(dropdownFrame, aPresContext, dropdownDesiredSize, firstPassState, aStatus, aDesiredSize.width, NS_UNCONSTRAINEDSIZE);
+ dropdownFrame->GetRect(dropdownRect);
- mButtonRect.SetRect(aDesiredSize.width-scrollbarScaledWidth-border.right, border.top,
- scrollbarScaledWidth, aDesiredSize.height - verAdjustment);
-
- if (nsnull != aDesiredSize.maxElementSize) {
- aDesiredSize.maxElementSize->width = minSize.width + verAdjustment;
- aDesiredSize.maxElementSize->height = minSize.height + horAdjustment;
- }
-
- nsRect frameRect;
- GetRect(frameRect);
- nsRect curRect;
- mPlaceHolderFrame->GetRect(curRect);
- curRect.x = 0;
-
- curRect.y = frameRect.y + aDesiredSize.height;
- mPlaceHolderFrame->SetRect(curRect);
- mListFrame->GetRect(frameRect);
-
- aDesiredSize.ascent = aDesiredSize.height;
- aDesiredSize.descent = 0;
- aStatus = NS_FRAME_COMPLETE;
-
- return NS_OK;
-}
-
-//------------------------------------------------------------------------------
-void
-nsComboboxControlFrame::PaintComboboxControl(nsIPresContext& aPresContext,
- nsIRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsFramePaintLayer aWhichLayer)
-{
- //XXX Combo box should be changed to be implemented as a label and button frame.
- //This would eliminate all of this rendering code. KMM
- const nsStyleDisplay* disp = (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
- if (!disp->mVisible) {
- return;
- }
- aRenderingContext.PushState();
-
- const nsStyleColor* myColor = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
- const nsStyleSpacing* mySpacing = (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
- const nsStyleFont* myFont = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
-
- nsIStyleContext * blkStyle;
- if (mGotFocus) {
- blkStyle = mTextStr.Length() > 0?mBlockTextSelectedFocusStyle:mBlockTextStyle;
- } else {
- blkStyle = mTextStr.Length() > 0?mBlockTextSelectedStyle:mBlockTextStyle;
- }
- const nsStyleColor* blkColor = (const nsStyleColor*)blkStyle->GetStyleData(eStyleStruct_Color);
- const nsStyleSpacing* blkSpacing = (const nsStyleSpacing*)blkStyle->GetStyleData(eStyleStruct_Spacing);
-// const nsStyleFont* blkFont = (const nsStyleFont*)blkStyle->GetStyleData(eStyleStruct_Font);
-
- nsRect rect(0, 0, mRect.width, mRect.height);
- nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,
- aDirtyRect, rect, *myColor, *mySpacing, 0, 0);
-
- nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
- aDirtyRect, rect, *mySpacing, mStyleContext, 0);
-
- nsHTMLContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
-
- const nsStyleSpacing* spacing =(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
- nsMargin border;
- spacing->CalcBorderFor(this, border);
-
- float p2t;
- aPresContext.GetScaledPixelsToTwips(&p2t);
- nscoord onePixel = NSIntPixelsToTwips(1, p2t);
-
- nsRect outside(0, 0, mRect.width, mRect.height);
- outside.Deflate(border);
-
- nsRect inside(outside);
- outside.Deflate(onePixel, onePixel);
-
- aRenderingContext.SetColor(blkColor->mBackgroundColor);
- aRenderingContext.FillRect(inside.x, inside.y, inside.width, inside.height);
-
- float appUnits;
- float devUnits;
- float scale;
- nsIDeviceContext * context;
- aRenderingContext.GetDeviceContext(context);
-
- context->GetCanonicalPixelScale(scale);
- context->GetAppUnitsToDevUnits(devUnits);
- context->GetDevUnitsToAppUnits(appUnits);
-
- float sbWidth;
- float sbHeight;
- context->GetScrollBarDimensions(sbWidth, sbHeight);
- PRInt32 scrollbarScaledWidth = PRInt32(sbWidth * scale);
- PRInt32 scrollbarScaledHeight = PRInt32(sbWidth * scale);
-
- nsFont font(aPresContext.GetDefaultFixedFontDeprecated());
- GetFont(&aPresContext, font);
-
- aRenderingContext.SetFont(myFont->mFont);
-
- inside.width -= scrollbarScaledWidth;
- PRBool clipEmpty;
- aRenderingContext.PushState();
- aRenderingContext.SetClipRect(inside, nsClipCombine_kReplace, clipEmpty);
-
- nscoord x = inside.x + (onePixel * 4);
- nscoord y = inside.y;
-
- aRenderingContext.SetColor(blkColor->mColor);
-
- aRenderingContext.DrawString(mTextStr, x, y);
- nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
- aDirtyRect, inside, *blkSpacing, blkStyle, 0);
-
- aRenderingContext.PopState(clipEmpty);
-
- inside.width -= scrollbarScaledWidth;
- inside.height -= scrollbarScaledHeight;
-
- const nsStyleSpacing* arrowSpacing = (const nsStyleSpacing*)mArrowStyle->GetStyleData(eStyleStruct_Spacing);
-
- nsRect srect(0,0,0,0);
- srect = mButtonRect;
- nsFormControlHelper::PaintArrow(nsFormControlHelper::eArrowDirection_Down, aRenderingContext,aPresContext,
- aDirtyRect, srect, onePixel, mArrowStyle, *arrowSpacing, this, mRect);
+ } else {
+ // A width has been specified for the select.
+ // Make the display frame's width + button frame width = the width specified.
+ nsHTMLReflowMetrics dropdownDesiredSize(aDesiredSize);
+ ReflowComboChildFrame(dropdownFrame, aPresContext, dropdownDesiredSize, firstPassState, aStatus, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
+ // Get unconstrained size of the dropdown list.
+ nsSize size;
+ mListControlFrame->GetMaximumSize(size);
- NS_RELEASE(context);
+ // Size the button to be the same height as the displayFrame
+ SetChildFrameSize(buttonFrame, size.height, size.height);
- PRBool status;
- aRenderingContext.PopState(status);
-}
+ // Compute display width
+ buttonFrame->GetRect(buttonRect);
+ nscoord displayWidth;
+ displayWidth = firstPassState.computedWidth - buttonRect.width;
-NS_METHOD
-nsComboboxControlFrame::Paint(nsIPresContext& aPresContext,
- nsIRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsFramePaintLayer aWhichLayer)
-{
- if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
- PaintComboboxControl(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
+ // Set the displayFrame to match the displayWidth computed above
+ SetChildFrameSize(displayFrame, displayWidth, size.height);
+
+ // Reflow again with the width of the display frame set.
+ nsAreaFrame::Reflow(aPresContext, aDesiredSize, firstPassState, aStatus);
+
+ // Reflow the dropdown list to match the width of the display + button
+ ReflowComboChildFrame(dropdownFrame, aPresContext, dropdownDesiredSize, firstPassState, aStatus, aDesiredSize.width, NS_UNCONSTRAINEDSIZE);
+
}
- return NS_OK;
-}
+
+ nsRect absoluteTwips;
+ nsRect absolutePixels;
+ GetAbsoluteFramePosition(aPresContext, displayFrame, absoluteTwips, absolutePixels);
+ PositionDropdown(aPresContext, aDesiredSize.height, absoluteTwips, absolutePixels);
-//--------------------------------------------------------------
-PRIntn
-nsComboboxControlFrame::GetSkipSides() const
-{
- return 0;
-}
+ return rv;
+}
//--------------------------------------------------------------
NS_IMETHODIMP
@@ -607,14 +716,12 @@ nsComboboxControlFrame::GetName(nsString* aResult)
return result;
}
-//--------------------------------------------------------------
PRInt32
nsComboboxControlFrame::GetMaxNumValues()
{
return 1;
}
-//--------------------------------------------------------------
PRBool
nsComboboxControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
@@ -641,27 +748,6 @@ nsComboboxControlFrame::GetFrameName(nsString& aResult) const
}
-void
-nsComboboxControlFrame::RefreshStyleContext(nsIPresContext* aPresContext,
- nsIAtom * aNewContentPseudo,
- nsIStyleContext*& aCurrentStyle,
- nsIContent * aContent,
- nsIStyleContext* aParentStyle)
-
-{
- nsIStyleContext* newStyleContext;
- aPresContext->ProbePseudoStyleContextFor(aContent,
- aNewContentPseudo,
- aParentStyle,
- PR_FALSE,
- &newStyleContext);
- if (newStyleContext != aCurrentStyle) {
- NS_IF_RELEASE(aCurrentStyle);
- aCurrentStyle = newStyleContext;
- } else {
- NS_IF_RELEASE(newStyleContext);
- }
-}
NS_IMETHODIMP
nsComboboxControlFrame::ReResolveStyleContext(nsIPresContext* aPresContext,
@@ -670,162 +756,83 @@ nsComboboxControlFrame::ReResolveStyleContext(nsIPresContext* aPresContext,
nsStyleChangeList* aChangeList,
PRInt32* aLocalChange)
{
+ PRInt32 ourChange = aParentChange;
+ nsresult rv = nsAreaFrame::ReResolveStyleContext(aPresContext, aParentContext, aParentChange, aChangeList, aLocalChange);
+
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
- // NOTE: using nsFrame's ReResolveStyleContext method to avoid
- // useless version in base classes.
- PRInt32 ourChange = aParentChange;
- nsresult rv = nsHTMLContainerFrame::ReResolveStyleContext(aPresContext, aParentContext,
- ourChange, aChangeList, &ourChange);
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- if (aLocalChange) {
+ if (aLocalChange) {
*aLocalChange = ourChange;
- }
+ }
- if (NS_COMFALSE != rv) {
- PRInt32 childChange;
- PRBool currentIsVisible = (mCurrentStyleContext == mVisibleStyleContext?PR_TRUE:PR_FALSE);
-
- RefreshStyleContext(aPresContext, nsHTMLAtoms::dropDownVisible, mVisibleStyleContext, mContent, mStyleContext);
-
- RefreshStyleContext(aPresContext, nsHTMLAtoms::dropDownHidden, mHiddenStyleContext, mContent, mStyleContext);
- mCurrentStyleContext = (currentIsVisible?mVisibleStyleContext:mHiddenStyleContext);
-
- mListFrame->ReResolveStyleContext(aPresContext,
- (nsnull != mCurrentStyleContext? mCurrentStyleContext : mStyleContext),
- ourChange, aChangeList, &childChange);
-
- // Button Style
- RefreshStyleContext(aPresContext, nsHTMLAtoms::dropDownBtnOut, mBtnOutStyleContext, mContent, mStyleContext);
- RefreshStyleContext(aPresContext, nsHTMLAtoms::dropDownBtnPressed, mBtnPressedStyleContext, mContent, mStyleContext);
-
- //Need to reset the mArrowStyle here, otherwise it might end up pointing
- //to memory that has been freed, by the RefreshStyleContext above.
- mArrowStyle = mBtnOutStyleContext;
-
- RefreshStyleContext(aPresContext, nsHTMLAtoms::comboText, mBlockTextStyle, mContent, mStyleContext);
- RefreshStyleContext(aPresContext, nsHTMLAtoms::comboTextSelected, mBlockTextSelectedStyle, mContent, mStyleContext);
- RefreshStyleContext(aPresContext, nsHTMLAtoms::comboTextSelectedFocus, mBlockTextSelectedFocusStyle, mContent, mStyleContext);
- }
-
- return rv;
+ if (NS_COMFALSE != rv) {
+ PRInt32 childChange;
+ // Update child list
+ nsIFrame* dropdownFrame = GetDropdownFrame();
+ dropdownFrame->ReResolveStyleContext(aPresContext, mStyleContext, ourChange, aChangeList, &childChange);
+ }
+ return rv;
}
-//----------------------------------------------------------------------
-NS_IMETHODIMP nsComboboxControlFrame::HandleEvent(nsIPresContext& aPresContext,
- nsGUIEvent* aEvent,
- nsEventStatus& aEventStatus)
+
+nsresult
+nsComboboxControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
{
- if (aEvent->message == NS_MOUSE_EXIT) {
- // If dropdown is visible and we have exited the combo box then leave the
- // list up and have the listbox capture all of the mouse events.
- if (mCurrentStyleContext == mVisibleStyleContext) {
- mListControlFrame->CaptureMouseEvents(PR_TRUE);
- }
- }
-
- if (nsEventStatus_eConsumeNoDefault == aEventStatus) {
- return NS_OK;
- }
-
- aEventStatus = nsEventStatus_eConsumeNoDefault;
-
- if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) {
- mArrowStyle = mBtnOutStyleContext;
- nsFormControlHelper::ForceDrawFrame(this);
- } else if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) {
- mArrowStyle = mBtnPressedStyleContext;
- nsFormControlHelper::ForceDrawFrame(this);
- MouseClicked(&aPresContext);
- }
+ ToggleList(mPresContext);
return NS_OK;
}
-//----------------------------------------------------------------------
-NS_IMETHODIMP
-nsComboboxControlFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
-{
- *aFrame = this;
- return NS_OK;
-}
-
-
//----------------------------------------------------------------------
// nsIComboboxControlFrame
//----------------------------------------------------------------------
NS_IMETHODIMP
-nsComboboxControlFrame::SetDropDown(nsIFrame* aPlaceHolderFrame, nsIFrame* aDropDownFrame)
+nsComboboxControlFrame::SetDropDown(nsIFrame* aDropDownFrame)
{
- mPlaceHolderFrame = aPlaceHolderFrame;
- mListFrame = aDropDownFrame;
-
- if (NS_OK != mListFrame->QueryInterface(kIListControlFrameIID, (void**)&mListControlFrame)) {
+ mDropdownFrame = aDropDownFrame;
+
+ if (NS_OK != mDropdownFrame->QueryInterface(kIListControlFrameIID, (void**)&mListControlFrame)) {
return NS_ERROR_FAILURE;
}
-
- // Ok, since we now know we have the ListFrame, and we are assuming at this point it has been initialized
- // Let's get the currently selected item, but we make the call using the Interface
- mListControlFrame->GetSelectedItem(mTextStr);
return NS_OK;
}
-//--------------------------------------------------------------
-NS_IMETHODIMP
-nsComboboxControlFrame::SetDropDownStyleContexts(nsIStyleContext * aVisible, nsIStyleContext * aHidden)
-{
- mVisibleStyleContext = aVisible;
- mHiddenStyleContext = aHidden;
- mCurrentStyleContext = mHiddenStyleContext;
-
- NS_ADDREF(mVisibleStyleContext);
- NS_ADDREF(mHiddenStyleContext);
- return NS_OK;
-}
-
-//--------------------------------------------------------------
-NS_IMETHODIMP
-nsComboboxControlFrame::SetButtonStyleContexts(nsIStyleContext * aOut, nsIStyleContext * aPressed)
-{
- mBtnOutStyleContext = aOut;
- mBtnPressedStyleContext = aPressed;
- mArrowStyle = aOut;
-
- NS_ADDREF(mBtnOutStyleContext);
- NS_ADDREF(mBtnPressedStyleContext);
- return NS_OK;
-}
-
void
nsComboboxControlFrame::SelectionChanged()
{
- // Generate a NS_ONCHANGE event.
+ if (nsnull != mDisplayContent) {
+ mDisplayContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, mTextStr, PR_TRUE);
+ }
- //XXX: Todo complete the implementation of selection changed
-// nsIViewManager *vm;
-// view->GetViewManager(vm);
-// nsGUIEvent event;
-// event.eventStructType = NS_GUI_EVENT;
-// event.widget = this; //XXX: How do I get a widget
-// NS_ADDREF(event.widget);
-// NS_CONTROL_CHANGE
-// InitEvent(event, aMsg);
-// vm->DispatchEvent(&event, result);
-// NS_RELEASE(event.widget);
-// NS_RELEASE(vm);
+ // Dispatch the NS_FORM_CHANGE event
+ nsEventStatus status = nsEventStatus_eIgnore;
+ nsGUIEvent event;
+ event.eventStructType = NS_GUI_EVENT;
+ event.widget = nsnull;
+ event.message = NS_FORM_CHANGE;
+ // Have the content handle the event.
+ mContent->HandleDOMEvent(*mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
+ // Now have the frame handle the event
+ nsIFrame* frame = nsnull;
+ nsIFrame* dropdownFrame = GetDropdownFrame();
+ nsresult result = dropdownFrame->QueryInterface(kIFrameIID, (void**)&frame);
+ if ((NS_SUCCEEDED(result)) && (nsnull != frame)) {
+ frame->HandleEvent(*mPresContext, &event, status);
+ }
+
}
-//--------------------------------------------------------------
+
NS_IMETHODIMP
nsComboboxControlFrame::ListWasSelected(nsIPresContext* aPresContext)
{
- mArrowStyle = mBtnOutStyleContext;
- MouseClicked(aPresContext);
+ ShowList(aPresContext, PR_FALSE);
+ mListControlFrame->CaptureMouseEvents(PR_FALSE);
nsString str;
if (nsnull != mListControlFrame) {
@@ -833,46 +840,184 @@ nsComboboxControlFrame::ListWasSelected(nsIPresContext* aPresContext)
// Check to see if the selection changed
if (PR_FALSE == str.Equals(mTextStr)) {
mTextStr = str;
+ //XXX:TODO look at the ordinal position of the selected content in the listbox to tell
+ // if the selection has changed, rather than looking at the text string.
+ // There may be more than one item in the dropdown list with the same label.
SelectionChanged();
}
- nsIFormControlFrame* fcFrame = nsnull;
- nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
- if ((NS_OK == result) && (nsnull != fcFrame)) {
- fcFrame->SetFocus(PR_FALSE, PR_FALSE);
- }
- SetFocus(PR_TRUE, PR_TRUE);
}
-
- mListControlFrame->CaptureMouseEvents(PR_FALSE);
return NS_OK;
}
-nsresult nsComboboxControlFrame::RequiresWidget(PRBool& aRequiresWidget)
+nsresult
+nsComboboxControlFrame::RequiresWidget(PRBool& aRequiresWidget)
{
aRequiresWidget = PR_FALSE;
return NS_OK;
}
-NS_IMETHODIMP nsComboboxControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
+NS_IMETHODIMP
+nsComboboxControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
{
nsIFormControlFrame* fcFrame = nsnull;
- nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
+ nsIFrame* dropdownFrame = GetDropdownFrame();
+ nsresult result = dropdownFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
if ((NS_SUCCEEDED(result)) && (nsnull != fcFrame)) {
return fcFrame->SetProperty(aName, aValue);
}
return result;
}
-NS_IMETHODIMP nsComboboxControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
+NS_IMETHODIMP
+nsComboboxControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
nsIFormControlFrame* fcFrame = nsnull;
- nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
+ nsIFrame* dropdownFrame = GetDropdownFrame();
+ nsresult result = dropdownFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
if ((NS_SUCCEEDED(result)) && (nsnull != fcFrame)) {
return fcFrame->GetProperty(aName, aValue);
}
return result;
}
+
+NS_IMETHODIMP
+nsComboboxControlFrame::CreateAnonymousContent(nsISupportsArray& aChildList)
+{
+ // The frames used to display the combo box and the button used to popup the dropdown list
+ // are created through anonymous content. The dropdown list is not created through anonymous
+ // content because it's frame is initialized specifically for the drop-down case and it is placed
+ // a special list referenced through NS_COMBO_FRAME_POPUP_LIST_INDEX to keep separate from the
+ // layout of the display and button.
+ //
+ // Note: The value attribute of the display content is set when an item is selected in the dropdown list.
+ // If the content specified below does not honor the value attribute than nothing will be displayed.
+ // In addition, if the frame created by content below for does not implement the nsIFormControlFrame
+ // interface and honor the SetSuggestedSize method the placement and size of the display area will not
+ // match what is normally desired for a combobox.
+
+
+ // For now the content that is created corresponds to two input buttons. It would be better to create the
+ // tag as something other than input, but then there isn't any way to create a button frame since it
+ // isn't possible to set the display type in CSS2 to create a button frame.
+
+ // create content used for display
+ nsIAtom* tag = NS_NewAtom("input");
+ NS_NewHTMLInputElement(&mDisplayContent, tag);
+ NS_ADDREF(mDisplayContent);
+ 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
+ //ids set to the same value which is illegal.
+ mDisplayContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, nsAutoString("-moz-display"), PR_FALSE);
+ aChildList.AppendElement(mDisplayContent);
+
+ // create button which drops the list down
+ tag = NS_NewAtom("input");
+ NS_NewHTMLInputElement(&mButtonContent, tag);
+ NS_ADDREF(mButtonContent);
+ mButtonContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, nsAutoString("button"), PR_FALSE);
+ aChildList.AppendElement(mButtonContent);
+
+ // get the reciever interface from the browser button's content node
+ nsCOMPtr reciever(do_QueryInterface(mButtonContent));
+
+ // we shouldn't have to unregister this listener because when
+ // our frame goes away all these content node go away as well
+ // because our frame is the only one who references them.
+ reciever->AddEventListenerByIID(this, kIDOMMouseListenerIID);
+
+ // get the reciever interface from the browser button's content node
+ nsCOMPtr displayReciever(do_QueryInterface(mDisplayContent));
+
+ // we shouldn't have to unregister this listener because when
+ // our frame goes away all these content node go away as well
+ // because our frame is the only one who references them.
+ displayReciever->AddEventListenerByIID(this, kIDOMMouseListenerIID);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsComboboxControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight)
+{
+ return NS_OK;
+}
+
+
+
+NS_IMETHODIMP
+nsComboboxControlFrame::DeleteFrame(nsIPresContext& aPresContext)
+{
+ // Cleanup frames in popup child list
+ mPopupFrames.DeleteFrames(aPresContext);
+ return nsAreaFrame::DeleteFrame(aPresContext);
+}
+
+
+NS_IMETHODIMP
+nsComboboxControlFrame::FirstChild(nsIAtom* aListName,
+ nsIFrame** aFirstChild) const
+{
+ if (nsLayoutAtoms::popupList == aListName) {
+ *aFirstChild = mPopupFrames.FirstChild();
+ } else {
+ nsAreaFrame::FirstChild(aListName, aFirstChild);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsComboboxControlFrame::SetInitialChildList(nsIPresContext& aPresContext,
+ nsIAtom* aListName,
+ nsIFrame* aChildList)
+{
+ nsresult rv = NS_OK;
+ if (nsLayoutAtoms::popupList == aListName) {
+ mPopupFrames.SetFrames(aChildList);
+ } else {
+ rv = nsAreaFrame::SetInitialChildList(aPresContext, aListName, aChildList);
+ InitTextStr(PR_FALSE);
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsComboboxControlFrame::GetAdditionalChildListName(PRInt32 aIndex,
+ nsIAtom** aListName) const
+{
+ // Maintain a seperate child list for the dropdown list (i.e. popup listbox)
+ // This is necessary because we don't want the listbox to be included in the layout
+ // of the combox's children because it would take up space, when it is suppose to
+ // be floating above the display.
+ NS_PRECONDITION(nsnull != aListName, "null OUT parameter pointer");
+ if (aIndex <= NS_AREA_FRAME_ABSOLUTE_LIST_INDEX) {
+ return nsAreaFrame::GetAdditionalChildListName(aIndex, aListName);
+ }
+
+ *aListName = nsnull;
+ if (NS_COMBO_FRAME_POPUP_LIST_INDEX == aIndex) {
+ *aListName = nsLayoutAtoms::popupList;
+ NS_ADDREF(*aListName);
+ }
+ return NS_OK;
+}
+
+PRIntn
+nsComboboxControlFrame::GetSkipSides() const
+{
+ // Don't skip any sides during border rendering
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/mozilla/layout/forms/nsComboboxControlFrame.h b/mozilla/layout/forms/nsComboboxControlFrame.h
index 18249aad5b9..5a411f98d7b 100644
--- a/mozilla/layout/forms/nsComboboxControlFrame.h
+++ b/mozilla/layout/forms/nsComboboxControlFrame.h
@@ -20,10 +20,12 @@
#define nsComboboxControlFrame_h___
-#include "nsHTMLContainerFrame.h"
+#include "nsAreaFrame.h"
#include "nsIFormControlFrame.h"
#include "nsIComboboxControlFrame.h"
-
+#include "nsIDOMMouseListener.h"
+#include "nsVoidArray.h"
+#include "nsIAnonymousContentCreator.h"
class nsButtonControlFrame;
class nsTextControlFrame;
@@ -33,19 +35,36 @@ class nsStyleContext;
class nsIHTMLContent;
class nsIListControlFrame;
-class nsComboboxControlFrame : public nsHTMLContainerFrame,
+/**
+ * Child list name indices
+ * @see #GetAdditionalChildListName()
+ */
+#define NS_COMBO_FRAME_POPUP_LIST_INDEX (NS_AREA_FRAME_ABSOLUTE_LIST_INDEX + 1)
+
+class nsComboboxControlFrame : public nsAreaFrame,
public nsIFormControlFrame,
- public nsIComboboxControlFrame
+ public nsIComboboxControlFrame,
+ public nsIDOMMouseListener,
+ public nsIAnonymousContentCreator
{
public:
nsComboboxControlFrame();
~nsComboboxControlFrame();
+ // nsISupports
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
+
+ // nsIAnonymousContentCreator
+ NS_IMETHOD CreateAnonymousContent(nsISupportsArray& aChildList);
+
+ // nsIFrame
+ NS_IMETHOD Init(nsIPresContext& aPresContext,
+ nsIContent* aContent,
+ nsIFrame* aParent,
+ nsIStyleContext* aContext,
+ nsIFrame* aPrevInFlow);
- // nsIFrame
-
NS_IMETHOD Reflow(nsIPresContext& aCX,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
@@ -57,45 +76,31 @@ public:
nsStyleChangeList* aChangeList,
PRInt32* aLocalChange);
- NS_IMETHOD Paint(nsIPresContext& aPresContext,
- nsIRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsFramePaintLayer aWhichLayer);
-
- NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
- nsGUIEvent* aEvent,
- nsEventStatus& aEventStatus);
-
NS_IMETHOD GetFrameName(nsString& aResult) const;
+ NS_IMETHOD DeleteFrame(nsIPresContext& aPresContext);
+ NS_IMETHOD FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) const;
+ NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext,
+ nsIAtom* aListName,
+ nsIFrame* aChildList);
+ NS_IMETHOD GetAdditionalChildListName(PRInt32 aIndex,
+ nsIAtom** aListName) const;
-
- virtual PRInt32 GetMaxNumValues();
-
- virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
- nsString* aValues, nsString* aNames);
-
- // nsIFormControLFrame
+ // nsIFormControlFrame
+ NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight);
+ NS_IMETHOD GetName(nsString* aName);
+ NS_IMETHOD GetType(PRInt32* aType) const;
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
void SetFocus(PRBool aOn, PRBool aRepaint);
-
virtual void PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight);
-
-
- //nsTextControlFrame* GetTextFrame() { return mTextFrame; }
-
- //void SetTextFrame(nsTextControlFrame* aFrame) { mTextFrame = aFrame; }
-
- //nsButtonControlFrame* GetBrowseFrame() { return mBrowseFrame; }
- //void SetBrowseFrame(nsButtonControlFrame* aFrame) { mBrowseFrame = aFrame; }
virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter);
virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; }
virtual void Reset();
- NS_IMETHOD GetName(nsString* aName);
- NS_IMETHOD GetType(PRInt32* aType) const;
-
+ virtual PRInt32 GetMaxNumValues();
+ virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
+ nsString* aValues, nsString* aNames);
NS_IMETHOD GetFont(nsIPresContext* aPresContext,
nsFont& aFont);
NS_IMETHOD GetFormContent(nsIContent*& aContent) const;
@@ -107,69 +112,73 @@ public:
float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const;
-
-
virtual nsresult RequiresWidget(PRBool &aRequiresWidget);
-
-
- NS_IMETHOD GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame);
-
- // A Static Helper Functions
-
- // This refreshes a particular pseudo style content when a "ReResolveStyleContent" happens
- static void RefreshStyleContext(nsIPresContext* aPresContext,
- nsIAtom * aNewContentPseudo,
- nsIStyleContext*& aCurrentStyle,
- nsIContent * aContent,
- nsIStyleContext* aParentStyle);
-
// nsIFormMouseListener
virtual void MouseClicked(nsIPresContext* aPresContext);
//nsIComboboxControlFrame
- NS_IMETHOD SetDropDown(nsIFrame* aPlaceHolderFrame, nsIFrame* aDropDownFrame);
- NS_IMETHOD SetDropDownStyleContexts(nsIStyleContext * aVisible, nsIStyleContext * aHidden);
- NS_IMETHOD SetButtonStyleContexts(nsIStyleContext * aOut, nsIStyleContext * aPressed);
+ NS_IMETHOD SetDropDown(nsIFrame* aDropDownFrame);
NS_IMETHOD ListWasSelected(nsIPresContext* aPresContext);
+ //nsIDOMEventListener
+ virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent);
+ virtual nsresult MouseUp(nsIDOMEvent* aMouseEvent) { return NS_OK; }
+ virtual nsresult MouseClick(nsIDOMEvent* aMouseEvent) { printf("mouse clock\n"); return NS_OK; };
+ virtual nsresult MouseDblClick(nsIDOMEvent* aMouseEvent) { return NS_OK; }
+ virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent) { return NS_OK; }
+ virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent) { return NS_OK; }
+ virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }
-protected:
- virtual void PaintComboboxControl(nsIPresContext& aPresContext,
- nsIRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsFramePaintLayer aWhichLayer);
+protected:
+
+ // nsHTMLContainerFrame
virtual PRIntn GetSkipSides() const;
- void InitTextStr();
+
+ // Utilities
+ nsresult ReflowComboChildFrame(nsIFrame* aFrame,
+ nsIPresContext& aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ const nsHTMLReflowState& aReflowState,
+ nsReflowStatus& aStatus,
+ nscoord aAvailableWidth,
+ nscoord aAvailableHeight);
+
+ nsresult GetScreenHeight(nsIPresContext& aPresContext, nscoord& aHeight);
+ nsresult PositionDropdown(nsIPresContext& aPresContext,
+ nscoord aHeight,
+ nsRect aAbsoluteTwipsRect,
+ nsRect aAbsolutePixelRect);
+ nsresult GetAbsoluteFramePosition(nsIPresContext& aPresContext,
+ nsIFrame *aFrame,
+ nsRect& aAbsoluteTwipsRect,
+ nsRect& aAbsolutePixelRect);
+ void ToggleList(nsIPresContext* aPresContext);
+ void ShowPopup(PRBool aShowPopup);
+ void ShowList(nsIPresContext* aPresContext, PRBool aShowList);
+ void SetChildFrameSize(nsIFrame* aFrame, nscoord aWidth, nscoord aHeight);
+ void InitTextStr(PRBool aUpdate);
+ nsresult GetPrimaryComboFrame(nsIPresContext& aPresContext, nsIContent* aContent, nsIFrame** aFrame);
+ nsIFrame* GetButtonFrame(nsIPresContext& aPresContext);
+ nsIFrame* GetDisplayFrame(nsIPresContext& aPresContext);
+ nsIFrame* GetDropdownFrame();
+
+ // Called when the selection has changed. If the the same item in the list is selected
+ // it is NOT called.
void SelectionChanged();
+ nsFrameList mPopupFrames; // additional named child list
+ nsIPresContext* mPresContext; // XXX: Remove the need to cache the pres context.
nsFormFrame* mFormFrame; // Parent Form Frame
- nsIFrame * mPlaceHolderFrame;
- nsIFrame * mListFrame; // Generic nsIFrame
- nsIListControlFrame * mListControlFrame; // Specific ListControl Interface
- nsRect mButtonRect; // The Arrow Button's Rect cached for Painting
-
- // DropDown List Visibility Styles
- nsIStyleContext * mVisibleStyleContext; // Style for the DropDown List to make it visible
- nsIStyleContext * mHiddenStyleContext; // Style for the DropDown List to make it hidden
- nsIStyleContext * mCurrentStyleContext; // The current Style state of the DropDown List
-
- // Arrow Button Styles
- nsIStyleContext * mBtnOutStyleContext; // Style when not pressed
- nsIStyleContext * mBtnPressedStyleContext; // Style When Pressed
- nsIStyleContext * mArrowStyle; // Arrows currrent style (for painting)
-
- // Combobox Text Styles
- nsIStyleContext * mBlockTextStyle; // Style when there is no selection and it doesn't have focus
- nsIStyleContext * mBlockTextSelectedStyle; // Style when selected and it doesn't have focus
- nsIStyleContext * mBlockTextSelectedFocusStyle; // Style when selected and it has focus
-
- PRBool mFirstTime;
-
- // State data members
- nsString mTextStr;
- PRBool mGotFocus;
+ nsString mTextStr; // Current Combo box selection
+ nsIHTMLContent* mDisplayContent; // Anonymous content used to display the current selection
+ nsIHTMLContent* mButtonContent; // Anonymous content used to popup the dropdown list
+ PRBool mDroppedDown; // Current state of the dropdown list, PR_TRUE is dropped down
+ nsIFrame* mDisplayFrame; // frame to display selection
+ nsIFrame* mButtonFrame; // button frame
+ nsIFrame* mDropdownFrame; // dropdown list frame
+ nsIListControlFrame * mListControlFrame; // ListControl Interface for the dropdown frame
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
diff --git a/mozilla/layout/forms/nsFileControlFrame.cpp b/mozilla/layout/forms/nsFileControlFrame.cpp
index b851e9005de..d21f30f0642 100644
--- a/mozilla/layout/forms/nsFileControlFrame.cpp
+++ b/mozilla/layout/forms/nsFileControlFrame.cpp
@@ -70,6 +70,8 @@ NS_NewFileControlFrame(nsIFrame** aNewFrame)
nsFileControlFrame::nsFileControlFrame():mTextFrame(nsnull), mFormFrame(nsnull)
{
+ //Shrink the area around it's contents
+ SetFlags(NS_BLOCK_SHRINK_WRAP);
}
NS_IMETHODIMP
diff --git a/mozilla/layout/forms/nsFileControlFrame.h b/mozilla/layout/forms/nsFileControlFrame.h
index ad04d5611a8..eef454d3327 100644
--- a/mozilla/layout/forms/nsFileControlFrame.h
+++ b/mozilla/layout/forms/nsFileControlFrame.h
@@ -50,7 +50,6 @@ public:
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
-
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD Reflow(nsIPresContext& aCX,
@@ -59,6 +58,7 @@ public:
nsReflowStatus& aStatus);
NS_IMETHOD GetFrameName(nsString& aResult) const;
+ NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight) { return NS_OK; };
virtual PRInt32 GetMaxNumValues();
diff --git a/mozilla/layout/forms/nsFormControlFrame.cpp b/mozilla/layout/forms/nsFormControlFrame.cpp
index 4e66e5f974a..7c6b6ac783b 100644
--- a/mozilla/layout/forms/nsFormControlFrame.cpp
+++ b/mozilla/layout/forms/nsFormControlFrame.cpp
@@ -67,6 +67,8 @@ nsFormControlFrame::nsFormControlFrame()
mDidInit = PR_FALSE;
mWidget = nsnull;
mFormFrame = nsnull;
+ mSuggestedWidth = NS_FORMSIZE_NOTSET;
+ mSuggestedHeight = NS_FORMSIZE_NOTSET;
}
nsFormControlFrame::~nsFormControlFrame()
@@ -735,3 +737,10 @@ nsresult nsFormControlFrame::RequiresWidget(PRBool & aRequiresWidget)
}
+NS_IMETHODIMP nsFormControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight)
+{
+ mSuggestedWidth = aWidth;
+ mSuggestedHeight = aHeight;
+ return NS_OK;
+}
+
diff --git a/mozilla/layout/forms/nsFormControlFrame.h b/mozilla/layout/forms/nsFormControlFrame.h
index dd21114c59e..b68bc0979b5 100644
--- a/mozilla/layout/forms/nsFormControlFrame.h
+++ b/mozilla/layout/forms/nsFormControlFrame.h
@@ -36,6 +36,8 @@ class nsFormFrame;
#define CSS_NOTSET -1
#define ATTR_NOTSET -1
+#define NS_FORMSIZE_NOTSET -1
+
/**
* nsFormControlFrame is the base class for frames of form controls. It
* provides a uniform way of creating widgets, resizing, and painting.
@@ -227,6 +229,8 @@ protected:
nsHTMLReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
+ NS_IMETHOD nsFormControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight);
+
//
//-------------------------------------------------------------------------------------
// Utility methods for managing checkboxes and radiobuttons
@@ -274,6 +278,8 @@ protected:
PRBool mDidInit;
nsPoint mLastClickPoint;
nsFormFrame* mFormFrame;
+ nscoord mSuggestedWidth;
+ nscoord mSuggestedHeight;
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
diff --git a/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp b/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp
index 4af6f406631..ba199cbceb2 100644
--- a/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp
+++ b/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp
@@ -592,6 +592,13 @@ nsHTMLButtonControlFrame::ReResolveStyleContext ( nsIPresContext* aPresContext,
} // ReResolveStyleContext
+NS_IMETHODIMP nsHTMLButtonControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight)
+{
+// mSuggestedWidth = aWidth;
+// mSuggestedHeight = aHeight;
+ return NS_OK;
+}
+
diff --git a/mozilla/layout/forms/nsHTMLButtonControlFrame.h b/mozilla/layout/forms/nsHTMLButtonControlFrame.h
index a51107f7f8c..e8c5a3c3884 100644
--- a/mozilla/layout/forms/nsHTMLButtonControlFrame.h
+++ b/mozilla/layout/forms/nsHTMLButtonControlFrame.h
@@ -131,6 +131,7 @@ public:
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
+ NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight);
protected:
NS_IMETHOD_(nsrefcnt) AddRef(void);
diff --git a/mozilla/layout/forms/nsIComboboxControlFrame.h b/mozilla/layout/forms/nsIComboboxControlFrame.h
index c021d02b13b..8c2cfb2b5e6 100644
--- a/mozilla/layout/forms/nsIComboboxControlFrame.h
+++ b/mozilla/layout/forms/nsIComboboxControlFrame.h
@@ -21,10 +21,12 @@
#include "nsISupports.h"
#include "nsFont.h"
+
class nsFormFrame;
class nsIPresContext;
class nsString;
class nsIContent;
+class nsVoidArray;
// IID for the nsIComboboxControlFrame class
@@ -45,19 +47,7 @@ public:
* Sets the Drop Down List
*
*/
- NS_IMETHOD SetDropDown(nsIFrame* aPlaceHolderFrame, nsIFrame* aDropDownFrame) = 0;
-
- /**
- * Sets the Pseudo Style Contexts for the DropDown
- *
- */
- NS_IMETHOD SetDropDownStyleContexts(nsIStyleContext * aVisible, nsIStyleContext * aHidden) = 0;
-
- /**
- * Sets the Pseudo Style Contexts for the Button
- *
- */
- NS_IMETHOD SetButtonStyleContexts(nsIStyleContext * aOut, nsIStyleContext * aPressed) = 0;
+ NS_IMETHOD SetDropDown(nsIFrame* aDropDownFrame) = 0;
/**
* Notifies the Combobox the List was selected
@@ -65,6 +55,7 @@ public:
*/
NS_IMETHOD ListWasSelected(nsIPresContext* aPresContext) = 0;
+
};
#endif
diff --git a/mozilla/layout/forms/nsIFormControlFrame.h b/mozilla/layout/forms/nsIFormControlFrame.h
index 82f30663c81..1f5de7a509e 100644
--- a/mozilla/layout/forms/nsIFormControlFrame.h
+++ b/mozilla/layout/forms/nsIFormControlFrame.h
@@ -67,6 +67,25 @@ public:
nscoord aInnerWidth,
nscoord aCharWidth) const = 0;
+
+ /**
+ * Set the suggested size for the form element.
+ * This is used to control the size of the element during reflow if it hasn't had it's size
+ * explicitly set.
+ * @param aWidth width of the form element
+ * @param aHeight height of the form element
+ * @returns NS_OK
+ */
+
+ NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight) = 0;
+
+ /**
+ * Determine if the control uses a native widget for rendering
+ * @param aRequiresWidget is set to PR_TRUE if it has a native widget, PR_FALSE otherwise.
+ * @returns NS_OK
+ */
+
+
/**
* Determine if the control uses a native widget for rendering
* @param aRequiresWidget is set to PR_TRUE if it has a native widget, PR_FALSE otherwise.
diff --git a/mozilla/layout/forms/nsIListControlFrame.h b/mozilla/layout/forms/nsIListControlFrame.h
index 908a34bd68d..f17224a6a5a 100644
--- a/mozilla/layout/forms/nsIListControlFrame.h
+++ b/mozilla/layout/forms/nsIListControlFrame.h
@@ -63,6 +63,12 @@ public:
*/
NS_IMETHOD CaptureMouseEvents(PRBool aGrabMouseEvents) = 0;
+ /**
+ * Returns the maximum width and height of an item in the listbox
+ */
+
+ NS_IMETHOD GetMaximumSize(nsSize &aSize) = 0;
+
};
diff --git a/mozilla/layout/forms/nsImageControlFrame.cpp b/mozilla/layout/forms/nsImageControlFrame.cpp
index b659bf1837c..5847fee0c5c 100644
--- a/mozilla/layout/forms/nsImageControlFrame.cpp
+++ b/mozilla/layout/forms/nsImageControlFrame.cpp
@@ -117,6 +117,7 @@ public:
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
+ NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight);
protected:
void GetTranslatedRect(nsRect& aRect); // XXX this implementation is a copy of nsHTMLButtonControlFrame
@@ -452,3 +453,10 @@ NS_IMETHODIMP nsImageControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
return NS_OK;
}
+
+NS_IMETHODIMP nsImageControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight)
+{
+// mSuggestedWidth = aWidth;
+// mSuggestedHeight = aHeight;
+ return NS_OK;
+}
\ No newline at end of file
diff --git a/mozilla/layout/forms/nsListControlFrame.cpp b/mozilla/layout/forms/nsListControlFrame.cpp
index 8f121a517df..8fc1c86149e 100644
--- a/mozilla/layout/forms/nsListControlFrame.cpp
+++ b/mozilla/layout/forms/nsListControlFrame.cpp
@@ -37,7 +37,7 @@
#include "nsIReflowCommand.h"
// Constants
-const nscoord kMaxDropDownRows = 20; // This matches the setting for 4.x browsers
+const nscoord kMaxDropDownRows = 20; // This matches the setting for 4.x browsers
const PRInt32 kNothingSelected = -1;
const PRInt32 kMaxZ= 0x7fffffff; //XXX: Shouldn't there be a define somewhere for MaxInt for PRInt32
@@ -54,7 +54,6 @@ static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
-//----------------------------------------------------------------------
nsresult
NS_NewListControlFrame(nsIFrame** aNewFrame)
@@ -71,7 +70,7 @@ NS_NewListControlFrame(nsIFrame** aNewFrame)
return NS_OK;
}
-//----------------------------------------------------------------------
+
nsListControlFrame::nsListControlFrame()
{
mHitFrame = nsnull;
@@ -83,20 +82,20 @@ nsListControlFrame::nsListControlFrame()
mDisplayed = PR_FALSE;
mButtonDown = PR_FALSE;
mLastFrame = nsnull;
+ mMaxWidth = 0;
+ mMaxHeight = 0;
+ mIsCapturingMouseEvents = PR_FALSE;
}
-//----------------------------------------------------------------------
nsListControlFrame::~nsListControlFrame()
{
mComboboxFrame = nsnull;
mFormFrame = nsnull;
}
-//----------------------------------------------------------------------
NS_IMPL_ADDREF(nsListControlFrame)
NS_IMPL_RELEASE(nsListControlFrame)
-//----------------------------------------------------------------------
NS_IMETHODIMP
nsListControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
@@ -108,7 +107,6 @@ nsListControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return NS_OK;
}
if (aIID.Equals(kIListControlFrameIID)) {
- NS_ADDREF_THIS(); // Increase reference count for caller
*aInstancePtr = (void *)((nsIListControlFrame*)this);
return NS_OK;
}
@@ -116,7 +114,7 @@ nsListControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return nsScrollFrame::QueryInterface(aIID, aInstancePtr);
}
-//----------------------------------------------------------------------
+
NS_IMETHODIMP
nsListControlFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
{
@@ -147,7 +145,7 @@ nsListControlFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
}
-//----------------------------------------------------------------------
+
nsresult
nsListControlFrame::GetFrameForPointUsing(const nsPoint& aPoint,
nsIAtom* aList,
@@ -194,7 +192,7 @@ nsListControlFrame::GetFrameForPointUsing(const nsPoint& aPoint,
scrollableView->GetScrollPosition(offsetx, offsety);
tmp.x += offsetx;
tmp.y += offsety;
- // Note: scrollableView is not ref counted so it's interface is not NS_RELEASE'd
+ // Note: scrollableView is not ref counted
}
}
@@ -238,14 +236,13 @@ nsListControlFrame::GetFrameForPointUsing(const nsPoint& aPoint,
}
*aFrame = this;
return NS_ERROR_FAILURE;
-
+
}
-//----------------------------------------------------------------------
// Reflow is overriden to constrain the listbox height to the number of rows and columns
// specified.
-//
+
NS_IMETHODIMP
nsListControlFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@@ -284,10 +281,9 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
nsSize scrolledAreaSize(0,0);
nsHTMLReflowMetrics scrolledAreaDesiredSize(&scrolledAreaSize);
+
if (eReflowReason_Incremental == firstPassState.reason) {
- //XXX: Why do we have to change the reflow type in this
- //case? If we don't an assert in the nsScrollFrame::Reflow prevents
- //execution from continuing. Is the assertion in nsScrollFrame bogus?
+ // When incremental, Reflow everything
nsIFrame* targetFrame;
firstPassState.reflowCommand->GetTarget(targetFrame);
if (this == targetFrame) {
@@ -308,6 +304,8 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
nscoord scrolledAreaWidth = scrolledAreaDesiredSize.maxElementSize->width;
nscoord scrolledAreaHeight = scrolledAreaDesiredSize.height;
+ mMaxWidth = scrolledAreaWidth;
+ mMaxHeight = scrolledAreaDesiredSize.maxElementSize->height;
// The first reflow produces a box with the scrollbar width and borders
// added in so we need to subtract them out.
@@ -342,20 +340,12 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
nscoord visibleWidth = 0;
if (IsInDropDownMode() == PR_TRUE) {
- // Always set the width to be
- // XXX: TODO The width of the list should be passed in so it can
- // be set to the same as the text box + dropdown arrow.
- visibleWidth = scrolledAreaWidth;
- if (nsnull != mComboboxFrame) {
- nsRect comboRect;
- nsIFrame *comboFrame = nsnull;
- if (NS_SUCCEEDED(mComboboxFrame->QueryInterface(kIFrameIID, (void **)&comboFrame))) {
- comboFrame->GetRect(comboRect);
- visibleWidth = comboRect.width;
- visibleWidth -= (border.left + border.right);
- }
- }
-
+ // Calculate visible width for dropdown
+ if (NS_UNCONSTRAINEDSIZE == aReflowState.computedWidth) {
+ visibleWidth = scrolledAreaWidth;
+ } else {
+ visibleWidth = aReflowState.computedWidth - (border.left + border.right);
+ }
} else {
if (NS_UNCONSTRAINEDSIZE == aReflowState.computedWidth) {
visibleWidth = scrolledAreaWidth;
@@ -364,11 +354,11 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
}
}
- // Determine if a scrollbar will be needed, If so we need to add
- // enough the width to allow for the scrollbar.
- // The scrollbar will be needed under two conditions:
- // (size * heightOfaRow) < scrolledAreaHeight or
- // the height set through Style < scrolledAreaHeight.
+ // Determine if a scrollbar will be needed, If so we need to add
+ // enough the width to allow for the scrollbar.
+ // The scrollbar will be needed under two conditions:
+ // (size * heightOfaRow) < scrolledAreaHeight or
+ // the height set through Style < scrolledAreaHeight.
// Calculate the height of a single row in the listbox or dropdown list
// Note: It is calculated based on what layout returns for the maxElement
@@ -428,7 +418,6 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
return NS_OK;
}
-//--------------------------------------------------------------
NS_IMETHODIMP
nsListControlFrame::GetFormContent(nsIContent*& aContent) const
{
@@ -440,7 +429,7 @@ nsListControlFrame::GetFormContent(nsIContent*& aContent) const
return rv;
}
-//--------------------------------------------------------------
+
NS_IMETHODIMP
nsListControlFrame::GetFont(nsIPresContext* aPresContext,
nsFont& aFont)
@@ -450,7 +439,8 @@ nsListControlFrame::GetFont(nsIPresContext* aPresContext,
}
-PRBool nsListControlFrame::IsOptionElement(nsIContent* aContent)
+PRBool
+nsListControlFrame::IsOptionElement(nsIContent* aContent)
{
PRBool result = PR_FALSE;
@@ -466,7 +456,8 @@ PRBool nsListControlFrame::IsOptionElement(nsIContent* aContent)
}
-PRBool nsListControlFrame::IsOptionElementFrame(nsIFrame *aFrame)
+PRBool
+nsListControlFrame::IsOptionElementFrame(nsIFrame *aFrame)
{
nsIContent *content = nsnull;
aFrame->GetContent(&content);
@@ -482,7 +473,8 @@ PRBool nsListControlFrame::IsOptionElementFrame(nsIFrame *aFrame)
// Go up the frame tree looking for the first ancestor that has content
// which is selectable
-nsIFrame *nsListControlFrame::GetSelectableFrame(nsIFrame *aFrame)
+nsIFrame *
+nsListControlFrame::GetSelectableFrame(nsIFrame *aFrame)
{
nsIFrame* selectedFrame = aFrame;
@@ -494,7 +486,8 @@ nsIFrame *nsListControlFrame::GetSelectableFrame(nsIFrame *aFrame)
return(selectedFrame);
}
-void nsListControlFrame::ForceRedraw()
+void
+nsListControlFrame::ForceRedraw()
{
//XXX: Hack. This should not be needed. The problem is DisplaySelected
//and DisplayDeselected set and unset an attribute on generic HTML content
@@ -508,11 +501,12 @@ void nsListControlFrame::ForceRedraw()
// XXX: Here we introduce a new -moz-option-selected attribute so a attribute
// selecitor n the ua.css can change the style when the option is selected.
-void nsListControlFrame::DisplaySelected(nsIContent* aContent)
+void
+nsListControlFrame::DisplaySelected(nsIContent* aContent)
{
//XXX: This is temporary. It simulates psuedo states by using a attribute selector on
// -moz-option-selected in the ua.css style sheet. This will not be needed when
- // The event state manager is functional. KMM
+ // The event state manager supports selected states. KMM
nsCOMPtr selectedAtom ( dont_QueryInterface(NS_NewAtom(kMozSelected)));
if (PR_TRUE == mDisplayed) {
@@ -523,7 +517,8 @@ void nsListControlFrame::DisplaySelected(nsIContent* aContent)
}
}
-void nsListControlFrame::DisplayDeselected(nsIContent* aContent)
+void
+nsListControlFrame::DisplayDeselected(nsIContent* aContent)
{
//XXX: This is temporary. It simulates psuedo states by using a attribute selector on
// -moz-option-selected in the ua.css style sheet. This will not be needed when
@@ -540,8 +535,9 @@ void nsListControlFrame::DisplayDeselected(nsIContent* aContent)
}
-//----------------------------------------------------------------------
-PRInt32 nsListControlFrame::GetSelectedIndex(nsIFrame *aHitFrame)
+
+PRInt32
+nsListControlFrame::GetSelectedIndex(nsIFrame *aHitFrame)
{
PRInt32 index = kNothingSelected;
// Get the content of the frame that was selected
@@ -575,19 +571,20 @@ PRInt32 nsListControlFrame::GetSelectedIndex(nsIFrame *aHitFrame)
return index;
}
-//----------------------------------------------------------------------
-void nsListControlFrame::ClearSelection()
+
+void
+nsListControlFrame::ClearSelection()
{
PRUint32 length = GetNumberOfOptions();
- for (PRInt32 i = 0; i < (PRInt32)length; i++) {
- if (i != mSelectedIndex) {
- SetFrameSelected(i, PR_FALSE);
- }
- }
+ for (PRInt32 i = 0; i < (PRInt32)length; i++) {
+ if (i != mSelectedIndex) {
+ SetFrameSelected(i, PR_FALSE);
+ }
+ }
}
-//----------------------------------------------------------------------
-void nsListControlFrame::ExtendedSelection(PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aDoInvert, PRBool aSetValue)
+void
+nsListControlFrame::ExtendedSelection(PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aDoInvert, PRBool aSetValue)
{
PRInt32 startInx;
PRInt32 endInx;
@@ -621,7 +618,8 @@ void nsListControlFrame::ExtendedSelection(PRInt32 aStartIndex, PRInt32 aEndInde
}
}
-void nsListControlFrame::SingleSelection()
+void
+nsListControlFrame::SingleSelection()
{
if (nsnull != mHitFrame) {
// Store previous selection
@@ -644,7 +642,8 @@ void nsListControlFrame::SingleSelection()
}
}
-void nsListControlFrame::MultipleSelection(PRBool aIsShift, PRBool aIsControl)
+void
+nsListControlFrame::MultipleSelection(PRBool aIsShift, PRBool aIsControl)
{
if (nsnull != mHitFrame) {
mSelectedIndex = (PRInt32)GetSelectedIndex(mHitFrame);
@@ -696,15 +695,13 @@ void nsListControlFrame::MultipleSelection(PRBool aIsShift, PRBool aIsControl)
ClearSelection();
}
}
-
- //XXX Fix this mHitContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::kClass, (selected?kSelectedFocus:kNormal), PR_TRUE);
}
-
}
-void nsListControlFrame::HandleListSelection(nsIPresContext& aPresContext,
- nsGUIEvent* aEvent,
- nsEventStatus& aEventStatus)
+void
+nsListControlFrame::HandleListSelection(nsIPresContext& aPresContext,
+ nsGUIEvent* aEvent,
+ nsEventStatus& aEventStatus)
{
if (mMultipleSelections) {
MultipleSelection(((nsMouseEvent *)aEvent)->isShift, ((nsMouseEvent *)aEvent)->isControl);
@@ -713,7 +710,8 @@ void nsListControlFrame::HandleListSelection(nsIPresContext& aPresContext,
}
}
-PRBool nsListControlFrame::HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2)
+PRBool
+nsListControlFrame::HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2)
{
// Quick check, if the frames are equal they must have
// the same content
@@ -735,8 +733,8 @@ PRBool nsListControlFrame::HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2)
}
-//----------------------------------------------------------------------
-NS_IMETHODIMP nsListControlFrame::HandleLikeListEvent(nsIPresContext& aPresContext,
+nsresult
+nsListControlFrame::HandleLikeListEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
@@ -762,6 +760,7 @@ NS_IMETHODIMP nsListControlFrame::HandleLikeListEvent(nsIPresContext& aPresConte
NS_IMETHODIMP
nsListControlFrame :: CaptureMouseEvents(PRBool aGrabMouseEvents)
{
+
// get its view
nsIView* view = nsnull;
GetView(&view);
@@ -773,8 +772,10 @@ nsListControlFrame :: CaptureMouseEvents(PRBool aGrabMouseEvents)
if (viewMan) {
if (aGrabMouseEvents) {
viewMan->GrabMouseEvents(view,result);
+ mIsCapturingMouseEvents = PR_TRUE;
} else {
viewMan->GrabMouseEvents(nsnull,result);
+ mIsCapturingMouseEvents = PR_FALSE;
}
}
}
@@ -782,7 +783,8 @@ nsListControlFrame :: CaptureMouseEvents(PRBool aGrabMouseEvents)
return NS_OK;
}
-nsIView* nsListControlFrame::GetViewFor(nsIWidget* aWidget)
+nsIView*
+nsListControlFrame::GetViewFor(nsIWidget* aWidget)
{
nsIView* view = nsnull;
void* clientData;
@@ -799,7 +801,8 @@ nsIView* nsListControlFrame::GetViewFor(nsIWidget* aWidget)
// Determine if a view is an ancestor of another view.
-PRBool nsListControlFrame::IsAncestor(nsIView* aAncestor, nsIView* aChild)
+PRBool
+nsListControlFrame::IsAncestor(nsIView* aAncestor, nsIView* aChild)
{
nsIView* view = aChild;
while (nsnull != view) {
@@ -814,10 +817,11 @@ PRBool nsListControlFrame::IsAncestor(nsIView* aAncestor, nsIView* aChild)
return(PR_FALSE);
}
-//----------------------------------------------------------------------
-NS_IMETHODIMP nsListControlFrame::HandleLikeDropDownListEvent(nsIPresContext& aPresContext,
- nsGUIEvent* aEvent,
- nsEventStatus& aEventStatus)
+
+nsresult
+nsListControlFrame::HandleLikeDropDownListEvent(nsIPresContext& aPresContext,
+ nsGUIEvent* aEvent,
+ nsEventStatus& aEventStatus)
{
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) {
if (nsnull == mHitFrame) {
@@ -883,12 +887,14 @@ NS_IMETHODIMP nsListControlFrame::HandleLikeDropDownListEvent(nsIPresContext& aP
return NS_OK;
}
-//----------------------------------------------------------------------
-NS_IMETHODIMP nsListControlFrame::HandleEvent(nsIPresContext& aPresContext,
+
+NS_IMETHODIMP
+nsListControlFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
-/* const char * desc[] = {"NS_MOUSE_MOVE",
+/*
+ const char * desc[] = {"NS_MOUSE_MOVE",
"NS_MOUSE_LEFT_BUTTON_UP",
"NS_MOUSE_LEFT_BUTTON_DOWN",
"","","","","","","",
@@ -910,8 +916,8 @@ NS_IMETHODIMP nsListControlFrame::HandleEvent(nsIPresContext& aPresContext,
printf("Mouse in ListFrame %s [%d]\n", desc[inx], aEvent->message);
} else {
printf("Mouse in ListFrame [%d]\n", aEvent->message);
- }*/
-
+ }
+*/
if (nsEventStatus_eConsumeNoDefault == aEventStatus) {
return NS_OK;
}
@@ -930,7 +936,7 @@ NS_IMETHODIMP nsListControlFrame::HandleEvent(nsIPresContext& aPresContext,
return NS_OK;
}
-//----------------------------------------------------------------------
+
NS_IMETHODIMP
nsListControlFrame::SetInitialChildList(nsIPresContext& aPresContext,
nsIAtom* aListName,
@@ -945,7 +951,7 @@ nsListControlFrame::SetInitialChildList(nsIPresContext& aPresContext,
return nsScrollFrame::SetInitialChildList(aPresContext, aListName, aChildList);
}
-//----------------------------------------------------------------------
+
NS_IMETHODIMP
nsListControlFrame::Init(nsIPresContext& aPresContext,
nsIContent* aContent,
@@ -977,7 +983,7 @@ nsListControlFrame::Init(nsIPresContext& aPresContext,
return result;
}
-//----------------------------------------------------------------------
+
nscoord
nsListControlFrame::GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const
@@ -985,7 +991,7 @@ nsListControlFrame::GetVerticalInsidePadding(float aPixToTwip,
return NSIntPixelsToTwips(0, aPixToTwip);
}
-//----------------------------------------------------------------------
+
nscoord
nsListControlFrame::GetHorizontalInsidePadding(nsIPresContext& aPresContext,
float aPixToTwip,
@@ -996,7 +1002,6 @@ nsListControlFrame::GetHorizontalInsidePadding(nsIPresContext& aPresContext,
}
-//----------------------------------------------------------------------
NS_IMETHODIMP
nsListControlFrame::GetMultiple(PRBool* aMultiple, nsIDOMHTMLSelectElement* aSelect)
{
@@ -1013,7 +1018,7 @@ nsListControlFrame::GetMultiple(PRBool* aMultiple, nsIDOMHTMLSelectElement* aSel
}
}
-//----------------------------------------------------------------------
+
nsIDOMHTMLSelectElement*
nsListControlFrame::GetSelect(nsIContent * aContent)
{
@@ -1026,7 +1031,7 @@ nsListControlFrame::GetSelect(nsIContent * aContent)
}
}
-//----------------------------------------------------------------------
+
NS_IMETHODIMP
nsListControlFrame::AboutToDropDown()
{
@@ -1034,7 +1039,6 @@ nsListControlFrame::AboutToDropDown()
return(SyncViewWithFrame());
}
-
nsIContent*
nsListControlFrame::GetOptionAsContent(nsIDOMHTMLCollection* aCollection,PRUint32 aIndex)
{
@@ -1101,7 +1105,6 @@ nsListControlFrame::SetFrameSelected(PRUint32 aIndex, PRBool aSelected)
NS_IF_RELEASE(content);
}
-//----------------------------------------------------------------------
void
nsListControlFrame::InitializeFromContent()
{
@@ -1127,7 +1130,7 @@ nsListControlFrame::InitializeFromContent()
}
-//----------------------------------------------------------------------
+
nsIDOMHTMLCollection*
nsListControlFrame::GetOptions(nsIContent * aContent, nsIDOMHTMLSelectElement* aSelect)
{
@@ -1147,7 +1150,6 @@ nsListControlFrame::GetOptions(nsIContent * aContent, nsIDOMHTMLSelectElement* a
}
}
-//----------------------------------------------------------------------
nsIDOMHTMLOptionElement*
nsListControlFrame::GetOption(nsIDOMHTMLCollection& aCollection, PRUint32 aIndex)
{
@@ -1163,7 +1165,7 @@ nsListControlFrame::GetOption(nsIDOMHTMLCollection& aCollection, PRUint32 aIndex
return nsnull;
}
-//----------------------------------------------------------------------
+
PRBool
nsListControlFrame::GetOptionValue(nsIDOMHTMLCollection& aCollection, PRUint32 aIndex, nsString& aValue)
{
@@ -1184,36 +1186,27 @@ nsListControlFrame::GetOptionValue(nsIDOMHTMLCollection& aCollection, PRUint32 a
return status;
}
-//----------------------------------------------------------------------
-NS_IMETHODIMP
+nsresult
nsListControlFrame::Deselect()
{
PRInt32 i;
PRInt32 max = GetNumberOfOptions();
for (i=0;i
libs:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
$(MAKE_INSTALL) ua.css $(DIST)\bin\res
+ $(MAKE_INSTALL) arrow.gif $(DIST)\bin\res
clobber::
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
rm -f $(DIST)\bin\res\ua.css
+ rm -f $(DIST)\bin\res\arrow.gif
diff --git a/mozilla/layout/html/document/src/ua.css b/mozilla/layout/html/document/src/ua.css
index 83377947f49..bee93ddf577 100644
--- a/mozilla/layout/html/document/src/ua.css
+++ b/mozilla/layout/html/document/src/ua.css
@@ -429,6 +429,18 @@ input[type=hidden] {
border: none;
visibility: hidden;
}
+
+
+input[type=file] {
+ white-space: nowrap;
+ border:none;
+}
+
+/* browse button for file selector */
+input[type=file] input[type=button] {
+ height:inherit;
+}
+
input[type=radio] {
/* these margins are for NavQuirks, we need a Standard ua.css */
margin-left: 3px;
@@ -738,8 +750,8 @@ label {
/* Combo box style */
select, select[size="1"] {
vertical-align: bottom;
- border: 1px inset #c0c0c0;
- background-color:rgb(204, 204, 204);
+ border: none;
+ background-color:rgb(204, 204, 204);
color:black;
white-space:nowrap;
text-align: left;
@@ -751,10 +763,53 @@ select[size] {
border: 1px inset rgb(153, 153, 153);
}
-select:active {
- border : 1px solid black;
+select[size="1"] {
+ vertical-align: bottom;
+ border: none;
+ background-color:rgb(204, 204, 204);
+ color:black;
+ white-space:nowrap;
+ text-align: left;
}
+
+/* combobox button */
+select input[type=button] {
+ border: outset 1px rgb(204, 204, 204);
+ background-image:url("arrow.gif");
+ background-repeat:no-repeat;
+ background-position:center;
+ width:12px;
+ height:12px;
+ -moz-border-radius:0px;
+}
+
+/* combobox display area */
+select input#-moz-display {
+ border: inset 1px rgb(204, 204, 204);
+ background-color: white;
+ background-image: none;
+ -moz-border-radius:0px;
+ padding-left: 0px;
+ padding-right: 0px;
+ padding-top: 0px;
+ padding-bottom: 0px;
+}
+
+/* combbox display area - active */
+select input#-moz-display:active {
+ border: inset 1px rgb(204, 204, 204);
+ background-color:white;
+ background-image: none;
+ -moz-border-radius:0px;
+ padding-left: 0px;
+ padding-right: 0px;
+ padding-top: 0px;
+ padding-bottom: 0px;
+ background-color:white;
+}
+
+
option {
display:block;
padding-left:3px;
@@ -985,47 +1040,20 @@ sourcetext { /* XXX should not be in HTML namespace */
display: none;
}
-:-moz-dropdown-visible {
- visibility: visible;
-}
-
-:-moz-dropdown-hidden {
- visibility: hidden;
-}
-
-:-moz-dropdown-btn-out {
- border: 2px outset #c0c0c0;
- background-color: rgb(206, 207, 206);
-}
-
-:-moz-dropdown-btn-pressed {
-/* border: 2px inset #c0c0c0; */
- background-color: rgb(204, 204, 204);
- border: none;
-}
-
+/* combobox dropdown list */
:-moz-dropdown-list {
- position:absolute;
- background-color:rgb(204, 204, 204);
- border: 1px inset rgb(153, 153, 153);
+ background-color:inherit;
+ border: 1px inset rgb(153, 153, 153);
}
-
-:-moz-combobox-text {
- color: black;
- padding-left: 2px;
+/* combobox dropdown list hidden */
+select:-moz-dropdown-list {
+ visibility:hidden;
}
-:-moz-combobox-textselected {
- background-color: rgb(0,0,128);
- color: white;
- border: 1px solid rgb(0,0,128);
-}
-
-:-moz-combobox-textselectedfocus {
- background-color: rgb(0,0,128);
- color: white;
- border: 1px dotted white;
+/* combobox dropdown list visible */
+select[-moz-dropdown-active]:-moz-dropdown-list {
+ visibility: visible;
}
:-moz-anonymous-block {
diff --git a/mozilla/layout/html/forms/public/nsIComboboxControlFrame.h b/mozilla/layout/html/forms/public/nsIComboboxControlFrame.h
index c021d02b13b..8c2cfb2b5e6 100644
--- a/mozilla/layout/html/forms/public/nsIComboboxControlFrame.h
+++ b/mozilla/layout/html/forms/public/nsIComboboxControlFrame.h
@@ -21,10 +21,12 @@
#include "nsISupports.h"
#include "nsFont.h"
+
class nsFormFrame;
class nsIPresContext;
class nsString;
class nsIContent;
+class nsVoidArray;
// IID for the nsIComboboxControlFrame class
@@ -45,19 +47,7 @@ public:
* Sets the Drop Down List
*
*/
- NS_IMETHOD SetDropDown(nsIFrame* aPlaceHolderFrame, nsIFrame* aDropDownFrame) = 0;
-
- /**
- * Sets the Pseudo Style Contexts for the DropDown
- *
- */
- NS_IMETHOD SetDropDownStyleContexts(nsIStyleContext * aVisible, nsIStyleContext * aHidden) = 0;
-
- /**
- * Sets the Pseudo Style Contexts for the Button
- *
- */
- NS_IMETHOD SetButtonStyleContexts(nsIStyleContext * aOut, nsIStyleContext * aPressed) = 0;
+ NS_IMETHOD SetDropDown(nsIFrame* aDropDownFrame) = 0;
/**
* Notifies the Combobox the List was selected
@@ -65,6 +55,7 @@ public:
*/
NS_IMETHOD ListWasSelected(nsIPresContext* aPresContext) = 0;
+
};
#endif
diff --git a/mozilla/layout/html/forms/public/nsIFormControlFrame.h b/mozilla/layout/html/forms/public/nsIFormControlFrame.h
index 82f30663c81..1f5de7a509e 100644
--- a/mozilla/layout/html/forms/public/nsIFormControlFrame.h
+++ b/mozilla/layout/html/forms/public/nsIFormControlFrame.h
@@ -67,6 +67,25 @@ public:
nscoord aInnerWidth,
nscoord aCharWidth) const = 0;
+
+ /**
+ * Set the suggested size for the form element.
+ * This is used to control the size of the element during reflow if it hasn't had it's size
+ * explicitly set.
+ * @param aWidth width of the form element
+ * @param aHeight height of the form element
+ * @returns NS_OK
+ */
+
+ NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight) = 0;
+
+ /**
+ * Determine if the control uses a native widget for rendering
+ * @param aRequiresWidget is set to PR_TRUE if it has a native widget, PR_FALSE otherwise.
+ * @returns NS_OK
+ */
+
+
/**
* Determine if the control uses a native widget for rendering
* @param aRequiresWidget is set to PR_TRUE if it has a native widget, PR_FALSE otherwise.
diff --git a/mozilla/layout/html/forms/public/nsIListControlFrame.h b/mozilla/layout/html/forms/public/nsIListControlFrame.h
index 908a34bd68d..f17224a6a5a 100644
--- a/mozilla/layout/html/forms/public/nsIListControlFrame.h
+++ b/mozilla/layout/html/forms/public/nsIListControlFrame.h
@@ -63,6 +63,12 @@ public:
*/
NS_IMETHOD CaptureMouseEvents(PRBool aGrabMouseEvents) = 0;
+ /**
+ * Returns the maximum width and height of an item in the listbox
+ */
+
+ NS_IMETHOD GetMaximumSize(nsSize &aSize) = 0;
+
};
diff --git a/mozilla/layout/html/forms/src/nsButtonControlFrame.cpp b/mozilla/layout/html/forms/src/nsButtonControlFrame.cpp
index 9dca0fbb356..c5838e20f0a 100644
--- a/mozilla/layout/html/forms/src/nsButtonControlFrame.cpp
+++ b/mozilla/layout/html/forms/src/nsButtonControlFrame.cpp
@@ -263,6 +263,11 @@ nsButtonControlFrame::AttributeChanged(nsIPresContext* aPresContext,
else {
result = nsFormControlFrame::AttributeChanged(aPresContext, aChild, aAttribute, aHint);
}
+ } else {
+ if (nsHTMLAtoms::value == aAttribute) {
+ // redraw button with the changed value
+ Invalidate(mRect, PR_TRUE);
+ }
}
return result;
}
@@ -382,6 +387,28 @@ nsButtonControlFrame::Reflow(nsIPresContext& aPresContext,
nsFormFrame::AddFormControlFrame(aPresContext, *this);
}
+ if ((NS_FORMSIZE_NOTSET != mSuggestedWidth) && (
+ NS_FORMSIZE_NOTSET != mSuggestedHeight))
+ {
+ aDesiredSize.width = mSuggestedWidth;
+ aDesiredSize.height = mSuggestedHeight;
+ aDesiredSize.ascent = mSuggestedHeight;
+ aDesiredSize.descent = 0;
+ if (aDesiredSize.maxElementSize) {
+ aDesiredSize.maxElementSize->width = mSuggestedWidth;
+ aDesiredSize.maxElementSize->height = mSuggestedWidth;
+ }
+
+ if (nsnull != aDesiredSize.maxElementSize) {
+ aDesiredSize.maxElementSize->width = aDesiredSize.width;
+ aDesiredSize.maxElementSize->height = aDesiredSize.height;
+ }
+
+ aStatus = NS_FRAME_COMPLETE;
+ return NS_OK;
+
+ }
+
nsSize ignore;
GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, ignore);
@@ -421,6 +448,29 @@ nsButtonControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
PRInt32 type;
GetType(&type);
+
+#if 0
+ if ((NS_FORM_INPUT_HIDDEN != type) && ((NS_FORMSIZE_NOTSET != mSuggestedWidth) && (
+ NS_FORMSIZE_NOTSET != mSuggestedHeight)))
+ {
+ aDesiredLayoutSize.width = mSuggestedWidth;
+ aDesiredLayoutSize.height = mSuggestedHeight;
+ aDesiredLayoutSize.ascent = mSuggestedHeight;
+ aDesiredLayoutSize.descent = 0;
+ if (aDesiredLayoutSize.maxElementSize) {
+ aDesiredLayoutSize.maxElementSize->width = mSuggestedWidth;
+ aDesiredLayoutSize.maxElementSize->height = mSuggestedWidth;
+ }
+ aDesiredWidgetSize.width = aDesiredLayoutSize.width;
+ aDesiredWidgetSize.height= aDesiredLayoutSize.height;
+
+ return;
+ }
+#endif
+
+
+
+
if (NS_FORM_INPUT_HIDDEN == type) { // there is no physical rep
aDesiredLayoutSize.width = 0;
aDesiredLayoutSize.height = 0;
diff --git a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp
index ddb75962403..0202a7ef1aa 100644
--- a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp
+++ b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp
@@ -18,51 +18,32 @@
#include "nsCOMPtr.h"
#include "nsComboboxControlFrame.h"
#include "nsFormFrame.h"
-#include "nsButtonControlFrame.h"
-#include "nsTextControlFrame.h"
-#include "nsIContent.h"
-#include "prtypes.h"
-#include "nsIAtom.h"
-#include "nsIPresContext.h"
+#include "nsFormControlFrame.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLAtoms.h"
-#include "nsIFileWidget.h"
-#include "nsITextWidget.h"
-#include "nsWidgetsCID.h"
-#include "nsIComponentManager.h"
-#include "nsIView.h"
#include "nsHTMLParts.h"
-#include "nsIDOMHTMLInputElement.h"
#include "nsIFormControl.h"
#include "nsINameSpaceManager.h"
-#include "nsITextContent.h"
-
-// Used for Paint
-#include "nsCSSRendering.h"
-#include "nsIDeviceContext.h"
-
-#include "nsIPresShell.h"
-#include "nsIView.h"
-#include "nsIViewManager.h"
-#include "nsViewsCID.h"
+#include "nsIDOMEventReceiver.h"
+#include "nsLayoutAtoms.h"
#include "nsIDOMElement.h"
#include "nsListControlFrame.h"
#include "nsIListControlFrame.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMHTMLOptionElement.h"
+#include "nsIPresShell.h"
+#include "nsISupportsArray.h"
+#include "nsIDeviceContext.h"
+#include "nsIView.h"
-static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
-static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
-static NS_DEFINE_IID(kCFileWidgetCID, NS_FILEWIDGET_CID);
-static NS_DEFINE_IID(kIFileWidgetIID, NS_IFILEWIDGET_IID);
-static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID);
static NS_DEFINE_IID(kIComboboxControlFrameIID, NS_ICOMBOBOXCONTROLFRAME_IID);
-static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
-static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
static NS_DEFINE_IID(kIListControlFrameIID, NS_ILISTCONTROLFRAME_IID);
+static NS_DEFINE_IID(kIDOMMouseListenerIID, NS_IDOMMOUSELISTENER_IID);
+static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
+static NS_DEFINE_IID(kIAnonymousContentCreatorIID, NS_IANONYMOUS_CONTENT_CREATOR_IID);
// Drop down list event management.
// The combo box uses the following strategy for managing the
@@ -76,6 +57,11 @@ static NS_DEFINE_IID(kIListControlFrameIID, NS_ILISTCONTROLFRAME_IID);
// The ListWasSelected code will turn off mouse-capture for the drop-down list.
// The drop-down list does not explicitly set capture when it is in the drop-down mode.
+
+//XXX: This is temporary. It simulates psuedo states by using a attribute selector on
+
+const char * kMozDropdownActive = "-moz-dropdown-active";
+
nsresult
NS_NewComboboxControlFrame(nsIFrame** aNewFrame)
{
@@ -92,29 +78,30 @@ NS_NewComboboxControlFrame(nsIFrame** aNewFrame)
}
nsComboboxControlFrame::nsComboboxControlFrame()
- : nsHTMLContainerFrame()
+ : nsAreaFrame()
{
- mFormFrame = nsnull;
- mListFrame = nsnull;
+ mPresContext = nsnull;
+ mFormFrame = nsnull;
mListControlFrame = nsnull;
- mPlaceHolderFrame = nsnull;
- mVisibleStyleContext = nsnull;
- mHiddenStyleContext = nsnull;
- mCurrentStyleContext = nsnull;
- mBlockTextStyle = nsnull;
- mBlockTextSelectedStyle = nsnull;
- mBlockTextSelectedFocusStyle = nsnull;
- mFirstTime = PR_TRUE;
- mGotFocus = PR_FALSE;
+ mTextStr = "";
+ mDisplayContent = nsnull;
+ mButtonContent = nsnull;
+ mDroppedDown = PR_FALSE;
+ mDisplayFrame = nsnull;
+ mButtonFrame = nsnull;
+ mDropdownFrame = nsnull;
+
+ //Shrink the area around it's contents
+ SetFlags(NS_BLOCK_SHRINK_WRAP);
}
//--------------------------------------------------------------
nsComboboxControlFrame::~nsComboboxControlFrame()
{
- NS_IF_RELEASE(mVisibleStyleContext);
- NS_IF_RELEASE(mHiddenStyleContext);
- NS_IF_RELEASE(mBlockTextStyle);
mFormFrame = nsnull;
+ NS_IF_RELEASE(mPresContext);
+ NS_IF_RELEASE(mDisplayContent);
+ NS_IF_RELEASE(mButtonContent);
}
//--------------------------------------------------------------
@@ -132,9 +119,32 @@ nsComboboxControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
if (aIID.Equals(kIFormControlFrameIID)) {
*aInstancePtr = (void*) ((nsIFormControlFrame*) this);
return NS_OK;
+ } else if (aIID.Equals(kIDOMMouseListenerIID)) {
+ *aInstancePtr = (void*)(nsIDOMMouseListener*) this;
+ NS_ADDREF_THIS();
+ return NS_OK;
+ } else if (aIID.Equals(kIAnonymousContentCreatorIID)) {
+ *aInstancePtr = (void*)(nsIAnonymousContentCreator*) this;
+ NS_ADDREF_THIS();
+ return NS_OK;
}
- return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
+ return nsAreaFrame::QueryInterface(aIID, aInstancePtr);
+}
+
+
+NS_IMETHODIMP
+nsComboboxControlFrame::Init(nsIPresContext& aPresContext,
+ nsIContent* aContent,
+ nsIFrame* aParent,
+ nsIStyleContext* aContext,
+ nsIFrame* aPrevInFlow)
+{
+ // Need to hold on the pres context because it is used later in methods
+ // which don't have it passed in.
+ mPresContext = &aPresContext;
+ NS_ADDREF(mPresContext);
+ return nsAreaFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
}
//--------------------------------------------------------------
@@ -149,15 +159,22 @@ nsComboboxControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter)
// 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()
+void
+nsComboboxControlFrame::InitTextStr(PRBool aUpdate)
{
+ nsIFormControlFrame* fcFrame = nsnull;
+ nsIFrame* dropdownFrame = GetDropdownFrame();
+ nsresult result = dropdownFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
+
+ // Reset the list, so we can ask it for it's selected item.
+ fcFrame->Reset();
+
// Update the selected text string
mListControlFrame->GetSelectedItem(mTextStr);
if (mTextStr == "") {
// No selection so use the first item in the list box
- nsIFormControlFrame* fcFrame = nsnull;
- nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
+
if ((NS_OK == result) && (nsnull != fcFrame)) {
// Set listbox selection to first item in the list box
fcFrame->SetProperty(nsHTMLAtoms::selectedindex, "0");
@@ -165,21 +182,28 @@ void nsComboboxControlFrame::InitTextStr()
mListControlFrame->GetSelectedItem(mTextStr);
}
}
+
+ // Update the display by setting the value attribute
+ mDisplayContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, mTextStr, aUpdate);
}
//--------------------------------------------------------------
+// Reset the combo box back to it original state.
+
void
nsComboboxControlFrame::Reset()
{
- SetFocus(PR_TRUE, PR_TRUE);
+ // Reset the dropdown list to its original state
nsIFormControlFrame* fcFrame = nsnull;
- nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
+ nsIFrame* dropdownFrame = GetDropdownFrame();
+ nsresult result = dropdownFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
if ((NS_OK == result) && (nsnull != fcFrame)) {
fcFrame->Reset();
}
- InitTextStr();
+ // Update the combobox using the text string returned from the dropdown list
+ InitTextStr(PR_TRUE);
}
void
@@ -190,7 +214,6 @@ nsComboboxControlFrame::PostCreateWidget(nsIPresContext* aPresContext,
Reset();
}
-
//--------------------------------------------------------------
NS_IMETHODIMP
nsComboboxControlFrame::GetType(PRInt32* aType) const
@@ -224,7 +247,7 @@ nsComboboxControlFrame::GetFont(nsIPresContext* aPresContext,
nscoord
nsComboboxControlFrame::GetVerticalBorderWidth(float aPixToTwip) const
{
- return NSIntPixelsToTwips(3, aPixToTwip);
+ return 0;
}
@@ -232,7 +255,7 @@ nsComboboxControlFrame::GetVerticalBorderWidth(float aPixToTwip) const
nscoord
nsComboboxControlFrame::GetHorizontalBorderWidth(float aPixToTwip) const
{
- return GetVerticalBorderWidth(aPixToTwip);
+ return 0;
}
@@ -255,335 +278,421 @@ nsComboboxControlFrame::GetHorizontalInsidePadding(nsIPresContext& aPresContext,
}
-//--------------------------------------------------------------
+
void
nsComboboxControlFrame::SetFocus(PRBool aOn, PRBool aRepaint)
{
- //XXX: TODO Make set focus work
- //mContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::kClass, "SELECTED", PR_TRUE);
- mGotFocus = aOn;
- if (aRepaint) {
- nsFormControlHelper::ForceDrawFrame(this);
+ //XXX: TODO Implement focus for combobox.
+}
+
+// Toggle dropdown list.
+
+void
+nsComboboxControlFrame::ToggleList(nsIPresContext* aPresContext)
+{
+ if (PR_TRUE == mDroppedDown) {
+ ShowList(aPresContext, PR_FALSE);
+ } else {
+ ShowList(aPresContext, PR_TRUE);
}
}
-//--------------------------------------------------------------
+
+void
+nsComboboxControlFrame::ShowPopup(PRBool aShowPopup)
+{
+ //XXX: This is temporary. It simulates a psuedo dropdown states by using a attribute selector
+ // This will not be need if the event state supports active states for use with the dropdown list
+ // Currently, the event state manager will reset the active state to the content which has focus
+ // which causes the active state to be removed from the event state manager immediately after it
+ // it the select is set to the active state.
+
+ nsCOMPtr activeAtom ( dont_QueryInterface(NS_NewAtom(kMozDropdownActive)));
+ if (PR_TRUE == aShowPopup) {
+ mContent->SetAttribute(kNameSpaceID_None, activeAtom, "", PR_TRUE);
+ } else {
+ mContent->UnsetAttribute(kNameSpaceID_None, activeAtom, PR_TRUE);
+ }
+}
+
+// Show the dropdown list
+
+void
+nsComboboxControlFrame::ShowList(nsIPresContext* aPresContext, PRBool aShowList)
+{
+ if (PR_TRUE == aShowList) {
+ mListControlFrame->AboutToDropDown();
+ ShowPopup(PR_TRUE);
+ mDroppedDown = PR_TRUE;
+ // The listcontrol frame will call back to the nsComboboxControlFrame's ListWasSelected
+ // which will stop the capture.
+ mListControlFrame->CaptureMouseEvents(PR_TRUE);
+ } else {
+ ShowPopup(PR_FALSE);
+ mDroppedDown = PR_FALSE;
+ }
+}
+
+
+//-------------------------------------------------------------
// this is in response to the MouseClick from the containing browse button
// XXX: TODO still need to get filters from accept attribute
-void nsComboboxControlFrame::MouseClicked(nsIPresContext* aPresContext)
+void
+nsComboboxControlFrame::MouseClicked(nsIPresContext* aPresContext)
{
- if (nsnull != mListControlFrame) {
- //XXX: Make this work SetFocus(PR_FALSE, PR_TRUE);
- mCurrentStyleContext = (mCurrentStyleContext == mHiddenStyleContext ? mVisibleStyleContext : mHiddenStyleContext);
- if (mCurrentStyleContext == mVisibleStyleContext) {
- mListControlFrame->AboutToDropDown();
-
- nsIFormControlFrame* fcFrame = nsnull;
- nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
- if ((NS_OK == result) && (nsnull != fcFrame)) {
- //XXX: Make this work fcFrame->SetFocus(PR_TRUE, PR_FALSE);
- }
+ ToggleList(aPresContext);
+}
- } else {
- //XXX: Make this work SetFocus(PR_TRUE, PR_TRUE);
- }
- //XXX: This should not be necessary. Need to restructure the combo box as follows:
- // Derive nsComboboxFrame from nsAreaFrame. Attach the placeholder frame, a label frame and
- // a button frame. Override reresolve style context and reresolve the style on the ListBox.
- // The event state manager should then be asked to set active and non-active based on
- // The mouse click this would get rid of all of the ugly code here. The setting of the active
- // Should cause re-resolution of the AreaFrame which will re-sync it. KMM.
- mListFrame->ReResolveStyleContext(aPresContext, mCurrentStyleContext, NS_STYLE_HINT_NONE, nsnull, nsnull);
-
- // Resync view with frame.
- const nsStyleDisplay* disp = (const
- nsStyleDisplay*)mCurrentStyleContext->GetStyleData(eStyleStruct_Display);
- nsIView * view;
- mListFrame->GetView(&view);
- if (view) {
- view->SetVisibility(NS_STYLE_VISIBILITY_HIDDEN == disp->mVisible ?
- nsViewVisibility_kHide:nsViewVisibility_kShow);
- }
- nsFormControlHelper::ForceDrawFrame(mListFrame);
- //XXX: End of the ugly code.
-
+nsresult
+nsComboboxControlFrame::ReflowComboChildFrame(nsIFrame* aFrame,
+ nsIPresContext& aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ const nsHTMLReflowState& aReflowState,
+ nsReflowStatus& aStatus,
+ nscoord aAvailableWidth,
+ nscoord aAvailableHeight)
+{
+ // Constrain the child's width and height to aAvailableWidth and aAvailableHeight
+ nsSize availSize(aAvailableWidth, aAvailableHeight);
+ nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aFrame,
+ availSize);
+ kidReflowState.computedWidth = aAvailableWidth;
+ kidReflowState.computedHeight = aAvailableHeight;
+
+ // Reflow child
+ nsresult rv = ReflowChild(aFrame, aPresContext, aDesiredSize, kidReflowState, aStatus);
+
+ // Set the child's width and height to it's desired size
+ nsRect rect;
+ aFrame->GetRect(rect);
+ rect.width = aDesiredSize.width;
+ rect.height = aDesiredSize.height;
+ aFrame->SetRect(rect);
+ return rv;
+}
+
+// Suggest a size for the child frame.
+// Only frames which implement the nsIFormControlFrame interface and
+// honor the SetSuggestedSize method will be placed and sized correctly.
+
+void
+nsComboboxControlFrame::SetChildFrameSize(nsIFrame* aFrame, nscoord aWidth, nscoord aHeight)
+{
+ nsIFormControlFrame* fcFrame = nsnull;
+ nsresult result = aFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
+ if (NS_SUCCEEDED(result) && (nsnull != fcFrame)) {
+ fcFrame->SetSuggestedSize(aWidth, aHeight);
}
}
-//--------------------------------------------------------------
-NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresContext,
+nsresult
+nsComboboxControlFrame::GetPrimaryComboFrame(nsIPresContext& aPresContext, nsIContent* aContent, nsIFrame** aFrame)
+{
+ nsresult rv = NS_OK;
+ // Get the primary frame from the presentation shell.
+ nsCOMPtr presShell;
+ rv = aPresContext.GetShell(getter_AddRefs(presShell));
+ if (NS_SUCCEEDED(rv) && presShell) {
+ presShell->GetPrimaryFrameFor(aContent, aFrame);
+ }
+ return rv;
+}
+
+nsIFrame*
+nsComboboxControlFrame::GetButtonFrame(nsIPresContext& aPresContext)
+{
+ if (mButtonFrame == nsnull) {
+ NS_ASSERTION(mButtonContent != nsnull, "nsComboboxControlFrame mButtonContent is null");
+ GetPrimaryComboFrame(aPresContext, mButtonContent, &mButtonFrame);
+ }
+
+ return mButtonFrame;
+}
+
+nsIFrame*
+nsComboboxControlFrame::GetDisplayFrame(nsIPresContext& aPresContext)
+{
+ if (mDisplayFrame == nsnull) {
+ NS_ASSERTION(mDisplayContent != nsnull, "nsComboboxControlFrame mDisplayContent is null");
+ GetPrimaryComboFrame(aPresContext, mDisplayContent, &mDisplayFrame);
+ }
+
+ return mDisplayFrame;
+}
+
+nsIFrame*
+nsComboboxControlFrame::GetDropdownFrame()
+{
+ return mDropdownFrame;
+}
+
+
+nsresult
+nsComboboxControlFrame::GetScreenHeight(nsIPresContext& aPresContext,
+ nscoord& aHeight)
+{
+ aHeight = 0;
+ nsIDeviceContext* context;
+ aPresContext.GetDeviceContext( &context );
+ if ( nsnull != context )
+ {
+ PRInt32 height;
+ PRInt32 width;
+ context->GetDeviceSurfaceDimensions(width, height);
+ float devUnits;
+ context->GetDevUnitsToAppUnits(devUnits);
+ aHeight = NSToIntRound(float( height) / devUnits );
+ NS_RELEASE( context );
+ return NS_OK;
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+
+nsresult
+nsComboboxControlFrame::PositionDropdown(nsIPresContext& aPresContext,
+ nscoord aHeight,
+ nsRect aAbsoluteTwipsRect,
+ nsRect aAbsolutePixelRect)
+{
+ // Position the dropdown list. It is positioned below the display frame if there is enough
+ // room on the screen to display the entire list. Otherwise it is placed above the display
+ // frame.
+
+ // Note: As first glance, it appears that you could simply get the absolute bounding box for the
+ // dropdown list by first getting it's view, then getting the view's nsIWidget, then asking the nsIWidget
+ // for it's AbsoluteBounds. The problem with this approach, is that the dropdown lists y location can
+ // change based on whether the dropdown is placed below or above the display frame.
+ // The approach, taken here is to get use the absolute position of the display frame and use it's location
+ // to determine if the dropdown will go offscreen.
+
+ // Use the height calculated for the area frame so it includes both
+ // the display and button heights.
+ nsresult rv = NS_OK;
+ nsIFrame* dropdownFrame = GetDropdownFrame();
+ nscoord dropdownYOffset = aHeight;
+/* XXX: Enable this code to debug popping up above the display frame, rather than below it
+ nscoord screenHeightInPixels = 0;
+ if (NS_SUCCEEDED(GetScreenHeight(aPresContext, screenHeightInPixels))) {
+ nsRect absoluteRect;
+
+ // Get the height of the dropdown list in pixels.
+ nsRect dropdownRect;
+ dropdownFrame->GetRect(dropdownRect);
+ float t2p;
+ aPresContext.GetTwipsToPixels(&t2p);
+ nscoord absoluteDropDownHeight = NSTwipsToIntPixels(dropdownRect.height, t2p);
+
+ // Check to see if the drop-down list will go offscreen
+ if (NS_SUCCEEDED(rv) && ((aAbsolutePixelRect.y + aAbsolutePixelRect.height + absoluteDropDownHeight) > screenHeightInPixels)) {
+ // move the dropdown list up
+ dropdownYOffset = - (aAbsoluteTwipsRect.height);
+ }
+ }
+*/
+
+ nsRect dropdownRect;
+ dropdownFrame->GetRect(dropdownRect);
+ dropdownRect.x = 0;
+ dropdownRect.y = dropdownYOffset;
+ dropdownFrame->SetRect(dropdownRect);
+
+ return rv;
+}
+
+
+// Calculate a frame's position in screen coordinates
+nsresult
+nsComboboxControlFrame::GetAbsoluteFramePosition(nsIPresContext& aPresContext,
+ nsIFrame *aFrame,
+ nsRect& aAbsoluteTwipsRect,
+ nsRect& aAbsolutePixelRect)
+{
+ //XXX: This code needs to take the view's offset into account when calculating
+ //the absolute coordinate of the frame.
+ nsresult rv = NS_OK;
+
+ aFrame->GetRect(aAbsoluteTwipsRect);
+
+ // Get conversions between twips and pixels
+ float t2p;
+ float p2t;
+ aPresContext.GetTwipsToPixels(&t2p);
+ aPresContext.GetPixelsToTwips(&p2t);
+
+ // Add in frame's offset from it it's containing view
+ nsIView *containingView = nsnull;
+ nsPoint offset;
+ rv = aFrame->GetOffsetFromView(offset, &containingView);
+ if (NS_SUCCEEDED(rv) && (nsnull != containingView)) {
+ aAbsoluteTwipsRect.x += offset.x;
+ aAbsoluteTwipsRect.y += offset.y;
+ // Addin the containing view's offset form it's containing widget
+ nsIWidget* widget = nsnull;
+ nscoord widgetx = 0;
+ nscoord widgety = 0;
+ rv = containingView->GetOffsetFromWidget(&widgetx, &widgety, widget);
+ if (NS_SUCCEEDED(rv) && (nsnull != widget)) {
+ aAbsoluteTwipsRect.x += widgetx;
+ aAbsoluteTwipsRect.y += widgety;
+
+ // Add in the absolute offset of the widget.
+ nsRect absBounds;
+ widget->GetAbsoluteBounds(absBounds);
+
+ // Convert widget coordinates to twips
+ aAbsoluteTwipsRect.x += NSIntPixelsToTwips(absBounds.x, p2t);
+ aAbsoluteTwipsRect.y += NSIntPixelsToTwips(absBounds.y, p2t);
+ NS_RELEASE(widget);
+ }
+ }
+
+ // convert to pixel coordinates
+ if (NS_SUCCEEDED(rv)) {
+ aAbsolutePixelRect.x = NSTwipsToIntPixels(aAbsoluteTwipsRect.x, t2p);
+ aAbsolutePixelRect.y = NSTwipsToIntPixels(aAbsoluteTwipsRect.y, t2p);
+ aAbsolutePixelRect.width = NSTwipsToIntPixels(aAbsoluteTwipsRect.width, t2p);
+ aAbsolutePixelRect.height = NSTwipsToIntPixels(aAbsoluteTwipsRect.height, t2p);
+ }
+
+ return rv;
+}
+
+
+NS_IMETHODIMP
+nsComboboxControlFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
- // XXX Combo box should be changed to be implemented as a label and button frame.
- // This would eliminate all of this Reflow code. KMM
+ nsresult rv = NS_OK;
+ nsIFrame* buttonFrame = GetButtonFrame(aPresContext);
+ nsIFrame* displayFrame = GetDisplayFrame(aPresContext);
+ nsIFrame* dropdownFrame = GetDropdownFrame();
- // add ourself as an nsIFormControlFrame
+ // Don't try to do any special sizing and positioning unless all of the frames
+ // have been created.
+ if ((nsnull == displayFrame) ||
+ (nsnull == buttonFrame) ||
+ (nsnull == dropdownFrame))
+ {
+ // Since combobox frames are missing just do a normal area frame reflow
+ return nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
+ }
+
+ // size of each part of the combo box
+ nsRect displayRect;
+ nsRect buttonRect;
+ nsRect dropdownRect;
+
+
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
nsFormFrame::AddFormControlFrame(aPresContext, *this);
}
+ // Get the current sizes of the combo box child frames
+ displayFrame->GetRect(displayRect);
+ buttonFrame->GetRect(buttonRect);
+ dropdownFrame->GetRect(dropdownRect);
- if (mFirstTime) {
- ReResolveStyleContext(&aPresContext, mStyleContext, NS_STYLE_HINT_REFLOW, nsnull, nsnull); // XXX This temporary
- mListFrame->ReResolveStyleContext(&aPresContext, mCurrentStyleContext, NS_STYLE_HINT_REFLOW, nsnull, nsnull);
- mFirstTime = PR_FALSE;
- InitTextStr();
- }
+ nsHTMLReflowState firstPassState(aReflowState);
- PRInt32 numChildren = mFrames.GetLength();
-
- if (1 == numChildren) {
- aPresContext.ResolvePseudoStyleContextFor(mContent, nsHTMLAtoms::comboText,
- mStyleContext, PR_FALSE,
- &mBlockTextStyle);
-
- // XXX This code should move to Init(), someday when the frame construction
- // changes are all done and Init() is always getting called...
- /*PRBool disabled = */nsFormFrame::GetDisabled(this);
- }
-
- nsIDOMHTMLSelectElement* select = nsListControlFrame::GetSelect(mContent);
- if (!select) {
- return NS_OK;
- }
- nsIDOMHTMLCollection* options = nsListControlFrame::GetOptions(mContent, select);
- if (!options) {
- NS_RELEASE(select);
- return NS_OK;
- }
-
- // get the css size
- nsSize styleSize;
- nsFormControlFrame::GetStyleSize(aPresContext, aReflowState, styleSize);
-
- // get the size of the longest option
- PRInt32 maxWidth = 1;
- PRUint32 numOptions;
- options->GetLength(&numOptions);
- for (PRUint32 i = 0; i < numOptions; i++) {
- nsIDOMHTMLOptionElement* option = nsListControlFrame::GetOption(*options, i);
- if (option) {
- nsAutoString text;
- if (NS_CONTENT_ATTR_HAS_VALUE != option->GetText(text)) {
- continue;
+ // Only reflow the display and button if they are the target of
+ // the incremental reflow, unless they change size. If they do
+ // then everything needs to be reflowed.
+ if (eReflowReason_Incremental == firstPassState.reason) {
+ nsIFrame* targetFrame;
+ firstPassState.reflowCommand->GetTarget(targetFrame);
+ if ((targetFrame == buttonFrame) || (targetFrame == displayFrame)) {
+ nsRect oldDisplayRect = displayRect;
+ nsRect oldButtonRect = buttonRect;
+ rv = nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
+ displayFrame->GetRect(displayRect);
+ buttonFrame->GetRect(buttonRect);
+ if ((oldDisplayRect == displayRect) && (oldButtonRect == buttonRect)) {
+ // Reposition the popup.
+ nsRect absoluteTwips;
+ nsRect absolutePixels;
+ GetAbsoluteFramePosition(aPresContext, displayFrame, absoluteTwips, absolutePixels);
+ PositionDropdown(aPresContext, displayRect.height, absoluteTwips, absolutePixels);
+ return rv;
}
- nsSize textSize;
- // use the style for the select rather that the option, since widgets don't support it
- nsFormControlHelper::GetTextSize(aPresContext, this, text, textSize, aReflowState.rendContext);
- if (textSize.width > maxWidth) {
- maxWidth = textSize.width;
- }
- NS_RELEASE(option);
}
+ nsIReflowCommand::ReflowType type;
+ aReflowState.reflowCommand->GetType(type);
+ firstPassState.reason = eReflowReason_StyleChange;
+ firstPassState.reflowCommand = nsnull;
}
- PRInt32 rowHeight = 0;
- nsSize desiredSize;
- nsSize minSize;
- PRBool widthExplicit, heightExplicit;
- nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull, nsnull,
- maxWidth, PR_TRUE, nsHTMLAtoms::size, 1);
- // XXX fix CalculateSize to return PRUint32
- PRUint32 numRows =
- (PRUint32)nsFormControlHelper::CalculateSize(&aPresContext, aReflowState.rendContext, this,
- styleSize, textSpec, desiredSize, minSize,
- widthExplicit, heightExplicit, rowHeight);
- float sp2t;
- float p2t;
- aPresContext.GetPixelsToTwips(&p2t);
- aPresContext.GetScaledPixelsToTwips(&sp2t);
- nscoord onePixel = NSIntPixelsToTwips(1, sp2t);
- nscoord extra = desiredSize.height - (rowHeight * numRows);
- numRows = (numOptions > 20 ? 20 : numOptions);
- desiredSize.height = (numRows * rowHeight) + extra;
- aDesiredSize.descent = 0;
- nsMargin border;
- const nsStyleSpacing* mySpacing = (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
- mySpacing->CalcBorderFor(this, border);
+ //Set the desired size for the button and display frame
+ if (NS_UNCONSTRAINEDSIZE == firstPassState.computedWidth) {
+ // A width has not been specified for the select so size the display area to
+ // match the width of the longest item in the drop-down list. The dropdown
+ // list has already been reflowed and sized to shrink around its contents above.
- float scale;
- float sbWidth;
- float sbHeight;
- nsCOMPtr context;
- aPresContext.GetDeviceContext(getter_AddRefs(context));
- context->GetCanonicalPixelScale(scale);
- context->GetScrollBarDimensions(sbWidth, sbHeight);
- PRInt32 scrollbarScaledWidth = PRInt32(sbWidth * scale);
+ // Reflow the dropdown shrink-wrapped.
+ nsHTMLReflowMetrics dropdownDesiredSize(aDesiredSize);
+ ReflowComboChildFrame(dropdownFrame, aPresContext, dropdownDesiredSize, firstPassState, aStatus, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
+ dropdownFrame->GetRect(dropdownRect);
+ // Get maximum size and height of a option in the dropdown
- nsFont font(aPresContext.GetDefaultFixedFontDeprecated());
- SystemAttrStruct sis;
- sis.mFont = &font;
- context->GetSystemAttribute(eSystemAttr_Font_Tooltips, &sis);
+ nsSize size;
+ mListControlFrame->GetMaximumSize(size);
- //XXX: This 14 pixel hardcode value here is bad. The style system should control
- //everyting. KMM
- nscoord horKludgeAdjustment = NSIntPixelsToTwips(14, p2t);
- nscoord horAdjustment = scrollbarScaledWidth + border.left + border.right + horKludgeAdjustment;
+ // Set width of display to match width of the drop down
+ SetChildFrameSize(displayFrame, dropdownRect.width, size.height);
- aDesiredSize.width = desiredSize.width + horAdjustment;
+ // Size the button to be the same height as the displayFrame
+ SetChildFrameSize(buttonFrame, size.height, size.height);
- nscoord verKludgeAdjustment = onePixel;
- nscoord verAdjustment = border.top + border.bottom + verKludgeAdjustment;
+ // Reflow display + button
+ nsAreaFrame::Reflow(aPresContext, aDesiredSize, firstPassState, aStatus);
+ displayFrame->GetRect(displayRect);
- aDesiredSize.height = rowHeight + verAdjustment;
+ // Reflow the dropdown list to match the width of the display + button
+ ReflowComboChildFrame(dropdownFrame, aPresContext, dropdownDesiredSize, firstPassState, aStatus, aDesiredSize.width, NS_UNCONSTRAINEDSIZE);
+ dropdownFrame->GetRect(dropdownRect);
- mButtonRect.SetRect(aDesiredSize.width-scrollbarScaledWidth-border.right, border.top,
- scrollbarScaledWidth, aDesiredSize.height - verAdjustment);
-
- if (nsnull != aDesiredSize.maxElementSize) {
- aDesiredSize.maxElementSize->width = minSize.width + verAdjustment;
- aDesiredSize.maxElementSize->height = minSize.height + horAdjustment;
- }
-
- nsRect frameRect;
- GetRect(frameRect);
- nsRect curRect;
- mPlaceHolderFrame->GetRect(curRect);
- curRect.x = 0;
-
- curRect.y = frameRect.y + aDesiredSize.height;
- mPlaceHolderFrame->SetRect(curRect);
- mListFrame->GetRect(frameRect);
-
- aDesiredSize.ascent = aDesiredSize.height;
- aDesiredSize.descent = 0;
- aStatus = NS_FRAME_COMPLETE;
-
- return NS_OK;
-}
-
-//------------------------------------------------------------------------------
-void
-nsComboboxControlFrame::PaintComboboxControl(nsIPresContext& aPresContext,
- nsIRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsFramePaintLayer aWhichLayer)
-{
- //XXX Combo box should be changed to be implemented as a label and button frame.
- //This would eliminate all of this rendering code. KMM
- const nsStyleDisplay* disp = (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
- if (!disp->mVisible) {
- return;
- }
- aRenderingContext.PushState();
-
- const nsStyleColor* myColor = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
- const nsStyleSpacing* mySpacing = (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
- const nsStyleFont* myFont = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
-
- nsIStyleContext * blkStyle;
- if (mGotFocus) {
- blkStyle = mTextStr.Length() > 0?mBlockTextSelectedFocusStyle:mBlockTextStyle;
- } else {
- blkStyle = mTextStr.Length() > 0?mBlockTextSelectedStyle:mBlockTextStyle;
- }
- const nsStyleColor* blkColor = (const nsStyleColor*)blkStyle->GetStyleData(eStyleStruct_Color);
- const nsStyleSpacing* blkSpacing = (const nsStyleSpacing*)blkStyle->GetStyleData(eStyleStruct_Spacing);
-// const nsStyleFont* blkFont = (const nsStyleFont*)blkStyle->GetStyleData(eStyleStruct_Font);
-
- nsRect rect(0, 0, mRect.width, mRect.height);
- nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,
- aDirtyRect, rect, *myColor, *mySpacing, 0, 0);
-
- nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
- aDirtyRect, rect, *mySpacing, mStyleContext, 0);
-
- nsHTMLContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
-
- const nsStyleSpacing* spacing =(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
- nsMargin border;
- spacing->CalcBorderFor(this, border);
-
- float p2t;
- aPresContext.GetScaledPixelsToTwips(&p2t);
- nscoord onePixel = NSIntPixelsToTwips(1, p2t);
-
- nsRect outside(0, 0, mRect.width, mRect.height);
- outside.Deflate(border);
-
- nsRect inside(outside);
- outside.Deflate(onePixel, onePixel);
-
- aRenderingContext.SetColor(blkColor->mBackgroundColor);
- aRenderingContext.FillRect(inside.x, inside.y, inside.width, inside.height);
-
- float appUnits;
- float devUnits;
- float scale;
- nsIDeviceContext * context;
- aRenderingContext.GetDeviceContext(context);
-
- context->GetCanonicalPixelScale(scale);
- context->GetAppUnitsToDevUnits(devUnits);
- context->GetDevUnitsToAppUnits(appUnits);
-
- float sbWidth;
- float sbHeight;
- context->GetScrollBarDimensions(sbWidth, sbHeight);
- PRInt32 scrollbarScaledWidth = PRInt32(sbWidth * scale);
- PRInt32 scrollbarScaledHeight = PRInt32(sbWidth * scale);
-
- nsFont font(aPresContext.GetDefaultFixedFontDeprecated());
- GetFont(&aPresContext, font);
-
- aRenderingContext.SetFont(myFont->mFont);
-
- inside.width -= scrollbarScaledWidth;
- PRBool clipEmpty;
- aRenderingContext.PushState();
- aRenderingContext.SetClipRect(inside, nsClipCombine_kReplace, clipEmpty);
-
- nscoord x = inside.x + (onePixel * 4);
- nscoord y = inside.y;
-
- aRenderingContext.SetColor(blkColor->mColor);
-
- aRenderingContext.DrawString(mTextStr, x, y);
- nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
- aDirtyRect, inside, *blkSpacing, blkStyle, 0);
-
- aRenderingContext.PopState(clipEmpty);
-
- inside.width -= scrollbarScaledWidth;
- inside.height -= scrollbarScaledHeight;
-
- const nsStyleSpacing* arrowSpacing = (const nsStyleSpacing*)mArrowStyle->GetStyleData(eStyleStruct_Spacing);
-
- nsRect srect(0,0,0,0);
- srect = mButtonRect;
- nsFormControlHelper::PaintArrow(nsFormControlHelper::eArrowDirection_Down, aRenderingContext,aPresContext,
- aDirtyRect, srect, onePixel, mArrowStyle, *arrowSpacing, this, mRect);
+ } else {
+ // A width has been specified for the select.
+ // Make the display frame's width + button frame width = the width specified.
+ nsHTMLReflowMetrics dropdownDesiredSize(aDesiredSize);
+ ReflowComboChildFrame(dropdownFrame, aPresContext, dropdownDesiredSize, firstPassState, aStatus, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
+ // Get unconstrained size of the dropdown list.
+ nsSize size;
+ mListControlFrame->GetMaximumSize(size);
- NS_RELEASE(context);
+ // Size the button to be the same height as the displayFrame
+ SetChildFrameSize(buttonFrame, size.height, size.height);
- PRBool status;
- aRenderingContext.PopState(status);
-}
+ // Compute display width
+ buttonFrame->GetRect(buttonRect);
+ nscoord displayWidth;
+ displayWidth = firstPassState.computedWidth - buttonRect.width;
-NS_METHOD
-nsComboboxControlFrame::Paint(nsIPresContext& aPresContext,
- nsIRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsFramePaintLayer aWhichLayer)
-{
- if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
- PaintComboboxControl(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
+ // Set the displayFrame to match the displayWidth computed above
+ SetChildFrameSize(displayFrame, displayWidth, size.height);
+
+ // Reflow again with the width of the display frame set.
+ nsAreaFrame::Reflow(aPresContext, aDesiredSize, firstPassState, aStatus);
+
+ // Reflow the dropdown list to match the width of the display + button
+ ReflowComboChildFrame(dropdownFrame, aPresContext, dropdownDesiredSize, firstPassState, aStatus, aDesiredSize.width, NS_UNCONSTRAINEDSIZE);
+
}
- return NS_OK;
-}
+
+ nsRect absoluteTwips;
+ nsRect absolutePixels;
+ GetAbsoluteFramePosition(aPresContext, displayFrame, absoluteTwips, absolutePixels);
+ PositionDropdown(aPresContext, aDesiredSize.height, absoluteTwips, absolutePixels);
-//--------------------------------------------------------------
-PRIntn
-nsComboboxControlFrame::GetSkipSides() const
-{
- return 0;
-}
+ return rv;
+}
//--------------------------------------------------------------
NS_IMETHODIMP
@@ -607,14 +716,12 @@ nsComboboxControlFrame::GetName(nsString* aResult)
return result;
}
-//--------------------------------------------------------------
PRInt32
nsComboboxControlFrame::GetMaxNumValues()
{
return 1;
}
-//--------------------------------------------------------------
PRBool
nsComboboxControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
@@ -641,27 +748,6 @@ nsComboboxControlFrame::GetFrameName(nsString& aResult) const
}
-void
-nsComboboxControlFrame::RefreshStyleContext(nsIPresContext* aPresContext,
- nsIAtom * aNewContentPseudo,
- nsIStyleContext*& aCurrentStyle,
- nsIContent * aContent,
- nsIStyleContext* aParentStyle)
-
-{
- nsIStyleContext* newStyleContext;
- aPresContext->ProbePseudoStyleContextFor(aContent,
- aNewContentPseudo,
- aParentStyle,
- PR_FALSE,
- &newStyleContext);
- if (newStyleContext != aCurrentStyle) {
- NS_IF_RELEASE(aCurrentStyle);
- aCurrentStyle = newStyleContext;
- } else {
- NS_IF_RELEASE(newStyleContext);
- }
-}
NS_IMETHODIMP
nsComboboxControlFrame::ReResolveStyleContext(nsIPresContext* aPresContext,
@@ -670,162 +756,83 @@ nsComboboxControlFrame::ReResolveStyleContext(nsIPresContext* aPresContext,
nsStyleChangeList* aChangeList,
PRInt32* aLocalChange)
{
+ PRInt32 ourChange = aParentChange;
+ nsresult rv = nsAreaFrame::ReResolveStyleContext(aPresContext, aParentContext, aParentChange, aChangeList, aLocalChange);
+
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
- // NOTE: using nsFrame's ReResolveStyleContext method to avoid
- // useless version in base classes.
- PRInt32 ourChange = aParentChange;
- nsresult rv = nsHTMLContainerFrame::ReResolveStyleContext(aPresContext, aParentContext,
- ourChange, aChangeList, &ourChange);
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- if (aLocalChange) {
+ if (aLocalChange) {
*aLocalChange = ourChange;
- }
+ }
- if (NS_COMFALSE != rv) {
- PRInt32 childChange;
- PRBool currentIsVisible = (mCurrentStyleContext == mVisibleStyleContext?PR_TRUE:PR_FALSE);
-
- RefreshStyleContext(aPresContext, nsHTMLAtoms::dropDownVisible, mVisibleStyleContext, mContent, mStyleContext);
-
- RefreshStyleContext(aPresContext, nsHTMLAtoms::dropDownHidden, mHiddenStyleContext, mContent, mStyleContext);
- mCurrentStyleContext = (currentIsVisible?mVisibleStyleContext:mHiddenStyleContext);
-
- mListFrame->ReResolveStyleContext(aPresContext,
- (nsnull != mCurrentStyleContext? mCurrentStyleContext : mStyleContext),
- ourChange, aChangeList, &childChange);
-
- // Button Style
- RefreshStyleContext(aPresContext, nsHTMLAtoms::dropDownBtnOut, mBtnOutStyleContext, mContent, mStyleContext);
- RefreshStyleContext(aPresContext, nsHTMLAtoms::dropDownBtnPressed, mBtnPressedStyleContext, mContent, mStyleContext);
-
- //Need to reset the mArrowStyle here, otherwise it might end up pointing
- //to memory that has been freed, by the RefreshStyleContext above.
- mArrowStyle = mBtnOutStyleContext;
-
- RefreshStyleContext(aPresContext, nsHTMLAtoms::comboText, mBlockTextStyle, mContent, mStyleContext);
- RefreshStyleContext(aPresContext, nsHTMLAtoms::comboTextSelected, mBlockTextSelectedStyle, mContent, mStyleContext);
- RefreshStyleContext(aPresContext, nsHTMLAtoms::comboTextSelectedFocus, mBlockTextSelectedFocusStyle, mContent, mStyleContext);
- }
-
- return rv;
+ if (NS_COMFALSE != rv) {
+ PRInt32 childChange;
+ // Update child list
+ nsIFrame* dropdownFrame = GetDropdownFrame();
+ dropdownFrame->ReResolveStyleContext(aPresContext, mStyleContext, ourChange, aChangeList, &childChange);
+ }
+ return rv;
}
-//----------------------------------------------------------------------
-NS_IMETHODIMP nsComboboxControlFrame::HandleEvent(nsIPresContext& aPresContext,
- nsGUIEvent* aEvent,
- nsEventStatus& aEventStatus)
+
+nsresult
+nsComboboxControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
{
- if (aEvent->message == NS_MOUSE_EXIT) {
- // If dropdown is visible and we have exited the combo box then leave the
- // list up and have the listbox capture all of the mouse events.
- if (mCurrentStyleContext == mVisibleStyleContext) {
- mListControlFrame->CaptureMouseEvents(PR_TRUE);
- }
- }
-
- if (nsEventStatus_eConsumeNoDefault == aEventStatus) {
- return NS_OK;
- }
-
- aEventStatus = nsEventStatus_eConsumeNoDefault;
-
- if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) {
- mArrowStyle = mBtnOutStyleContext;
- nsFormControlHelper::ForceDrawFrame(this);
- } else if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) {
- mArrowStyle = mBtnPressedStyleContext;
- nsFormControlHelper::ForceDrawFrame(this);
- MouseClicked(&aPresContext);
- }
+ ToggleList(mPresContext);
return NS_OK;
}
-//----------------------------------------------------------------------
-NS_IMETHODIMP
-nsComboboxControlFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
-{
- *aFrame = this;
- return NS_OK;
-}
-
-
//----------------------------------------------------------------------
// nsIComboboxControlFrame
//----------------------------------------------------------------------
NS_IMETHODIMP
-nsComboboxControlFrame::SetDropDown(nsIFrame* aPlaceHolderFrame, nsIFrame* aDropDownFrame)
+nsComboboxControlFrame::SetDropDown(nsIFrame* aDropDownFrame)
{
- mPlaceHolderFrame = aPlaceHolderFrame;
- mListFrame = aDropDownFrame;
-
- if (NS_OK != mListFrame->QueryInterface(kIListControlFrameIID, (void**)&mListControlFrame)) {
+ mDropdownFrame = aDropDownFrame;
+
+ if (NS_OK != mDropdownFrame->QueryInterface(kIListControlFrameIID, (void**)&mListControlFrame)) {
return NS_ERROR_FAILURE;
}
-
- // Ok, since we now know we have the ListFrame, and we are assuming at this point it has been initialized
- // Let's get the currently selected item, but we make the call using the Interface
- mListControlFrame->GetSelectedItem(mTextStr);
return NS_OK;
}
-//--------------------------------------------------------------
-NS_IMETHODIMP
-nsComboboxControlFrame::SetDropDownStyleContexts(nsIStyleContext * aVisible, nsIStyleContext * aHidden)
-{
- mVisibleStyleContext = aVisible;
- mHiddenStyleContext = aHidden;
- mCurrentStyleContext = mHiddenStyleContext;
-
- NS_ADDREF(mVisibleStyleContext);
- NS_ADDREF(mHiddenStyleContext);
- return NS_OK;
-}
-
-//--------------------------------------------------------------
-NS_IMETHODIMP
-nsComboboxControlFrame::SetButtonStyleContexts(nsIStyleContext * aOut, nsIStyleContext * aPressed)
-{
- mBtnOutStyleContext = aOut;
- mBtnPressedStyleContext = aPressed;
- mArrowStyle = aOut;
-
- NS_ADDREF(mBtnOutStyleContext);
- NS_ADDREF(mBtnPressedStyleContext);
- return NS_OK;
-}
-
void
nsComboboxControlFrame::SelectionChanged()
{
- // Generate a NS_ONCHANGE event.
+ if (nsnull != mDisplayContent) {
+ mDisplayContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, mTextStr, PR_TRUE);
+ }
- //XXX: Todo complete the implementation of selection changed
-// nsIViewManager *vm;
-// view->GetViewManager(vm);
-// nsGUIEvent event;
-// event.eventStructType = NS_GUI_EVENT;
-// event.widget = this; //XXX: How do I get a widget
-// NS_ADDREF(event.widget);
-// NS_CONTROL_CHANGE
-// InitEvent(event, aMsg);
-// vm->DispatchEvent(&event, result);
-// NS_RELEASE(event.widget);
-// NS_RELEASE(vm);
+ // Dispatch the NS_FORM_CHANGE event
+ nsEventStatus status = nsEventStatus_eIgnore;
+ nsGUIEvent event;
+ event.eventStructType = NS_GUI_EVENT;
+ event.widget = nsnull;
+ event.message = NS_FORM_CHANGE;
+ // Have the content handle the event.
+ mContent->HandleDOMEvent(*mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
+ // Now have the frame handle the event
+ nsIFrame* frame = nsnull;
+ nsIFrame* dropdownFrame = GetDropdownFrame();
+ nsresult result = dropdownFrame->QueryInterface(kIFrameIID, (void**)&frame);
+ if ((NS_SUCCEEDED(result)) && (nsnull != frame)) {
+ frame->HandleEvent(*mPresContext, &event, status);
+ }
+
}
-//--------------------------------------------------------------
+
NS_IMETHODIMP
nsComboboxControlFrame::ListWasSelected(nsIPresContext* aPresContext)
{
- mArrowStyle = mBtnOutStyleContext;
- MouseClicked(aPresContext);
+ ShowList(aPresContext, PR_FALSE);
+ mListControlFrame->CaptureMouseEvents(PR_FALSE);
nsString str;
if (nsnull != mListControlFrame) {
@@ -833,46 +840,184 @@ nsComboboxControlFrame::ListWasSelected(nsIPresContext* aPresContext)
// Check to see if the selection changed
if (PR_FALSE == str.Equals(mTextStr)) {
mTextStr = str;
+ //XXX:TODO look at the ordinal position of the selected content in the listbox to tell
+ // if the selection has changed, rather than looking at the text string.
+ // There may be more than one item in the dropdown list with the same label.
SelectionChanged();
}
- nsIFormControlFrame* fcFrame = nsnull;
- nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
- if ((NS_OK == result) && (nsnull != fcFrame)) {
- fcFrame->SetFocus(PR_FALSE, PR_FALSE);
- }
- SetFocus(PR_TRUE, PR_TRUE);
}
-
- mListControlFrame->CaptureMouseEvents(PR_FALSE);
return NS_OK;
}
-nsresult nsComboboxControlFrame::RequiresWidget(PRBool& aRequiresWidget)
+nsresult
+nsComboboxControlFrame::RequiresWidget(PRBool& aRequiresWidget)
{
aRequiresWidget = PR_FALSE;
return NS_OK;
}
-NS_IMETHODIMP nsComboboxControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
+NS_IMETHODIMP
+nsComboboxControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
{
nsIFormControlFrame* fcFrame = nsnull;
- nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
+ nsIFrame* dropdownFrame = GetDropdownFrame();
+ nsresult result = dropdownFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
if ((NS_SUCCEEDED(result)) && (nsnull != fcFrame)) {
return fcFrame->SetProperty(aName, aValue);
}
return result;
}
-NS_IMETHODIMP nsComboboxControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
+NS_IMETHODIMP
+nsComboboxControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
nsIFormControlFrame* fcFrame = nsnull;
- nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
+ nsIFrame* dropdownFrame = GetDropdownFrame();
+ nsresult result = dropdownFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
if ((NS_SUCCEEDED(result)) && (nsnull != fcFrame)) {
return fcFrame->GetProperty(aName, aValue);
}
return result;
}
+
+NS_IMETHODIMP
+nsComboboxControlFrame::CreateAnonymousContent(nsISupportsArray& aChildList)
+{
+ // The frames used to display the combo box and the button used to popup the dropdown list
+ // are created through anonymous content. The dropdown list is not created through anonymous
+ // content because it's frame is initialized specifically for the drop-down case and it is placed
+ // a special list referenced through NS_COMBO_FRAME_POPUP_LIST_INDEX to keep separate from the
+ // layout of the display and button.
+ //
+ // Note: The value attribute of the display content is set when an item is selected in the dropdown list.
+ // If the content specified below does not honor the value attribute than nothing will be displayed.
+ // In addition, if the frame created by content below for does not implement the nsIFormControlFrame
+ // interface and honor the SetSuggestedSize method the placement and size of the display area will not
+ // match what is normally desired for a combobox.
+
+
+ // For now the content that is created corresponds to two input buttons. It would be better to create the
+ // tag as something other than input, but then there isn't any way to create a button frame since it
+ // isn't possible to set the display type in CSS2 to create a button frame.
+
+ // create content used for display
+ nsIAtom* tag = NS_NewAtom("input");
+ NS_NewHTMLInputElement(&mDisplayContent, tag);
+ NS_ADDREF(mDisplayContent);
+ 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
+ //ids set to the same value which is illegal.
+ mDisplayContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, nsAutoString("-moz-display"), PR_FALSE);
+ aChildList.AppendElement(mDisplayContent);
+
+ // create button which drops the list down
+ tag = NS_NewAtom("input");
+ NS_NewHTMLInputElement(&mButtonContent, tag);
+ NS_ADDREF(mButtonContent);
+ mButtonContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, nsAutoString("button"), PR_FALSE);
+ aChildList.AppendElement(mButtonContent);
+
+ // get the reciever interface from the browser button's content node
+ nsCOMPtr reciever(do_QueryInterface(mButtonContent));
+
+ // we shouldn't have to unregister this listener because when
+ // our frame goes away all these content node go away as well
+ // because our frame is the only one who references them.
+ reciever->AddEventListenerByIID(this, kIDOMMouseListenerIID);
+
+ // get the reciever interface from the browser button's content node
+ nsCOMPtr displayReciever(do_QueryInterface(mDisplayContent));
+
+ // we shouldn't have to unregister this listener because when
+ // our frame goes away all these content node go away as well
+ // because our frame is the only one who references them.
+ displayReciever->AddEventListenerByIID(this, kIDOMMouseListenerIID);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsComboboxControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight)
+{
+ return NS_OK;
+}
+
+
+
+NS_IMETHODIMP
+nsComboboxControlFrame::DeleteFrame(nsIPresContext& aPresContext)
+{
+ // Cleanup frames in popup child list
+ mPopupFrames.DeleteFrames(aPresContext);
+ return nsAreaFrame::DeleteFrame(aPresContext);
+}
+
+
+NS_IMETHODIMP
+nsComboboxControlFrame::FirstChild(nsIAtom* aListName,
+ nsIFrame** aFirstChild) const
+{
+ if (nsLayoutAtoms::popupList == aListName) {
+ *aFirstChild = mPopupFrames.FirstChild();
+ } else {
+ nsAreaFrame::FirstChild(aListName, aFirstChild);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsComboboxControlFrame::SetInitialChildList(nsIPresContext& aPresContext,
+ nsIAtom* aListName,
+ nsIFrame* aChildList)
+{
+ nsresult rv = NS_OK;
+ if (nsLayoutAtoms::popupList == aListName) {
+ mPopupFrames.SetFrames(aChildList);
+ } else {
+ rv = nsAreaFrame::SetInitialChildList(aPresContext, aListName, aChildList);
+ InitTextStr(PR_FALSE);
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsComboboxControlFrame::GetAdditionalChildListName(PRInt32 aIndex,
+ nsIAtom** aListName) const
+{
+ // Maintain a seperate child list for the dropdown list (i.e. popup listbox)
+ // This is necessary because we don't want the listbox to be included in the layout
+ // of the combox's children because it would take up space, when it is suppose to
+ // be floating above the display.
+ NS_PRECONDITION(nsnull != aListName, "null OUT parameter pointer");
+ if (aIndex <= NS_AREA_FRAME_ABSOLUTE_LIST_INDEX) {
+ return nsAreaFrame::GetAdditionalChildListName(aIndex, aListName);
+ }
+
+ *aListName = nsnull;
+ if (NS_COMBO_FRAME_POPUP_LIST_INDEX == aIndex) {
+ *aListName = nsLayoutAtoms::popupList;
+ NS_ADDREF(*aListName);
+ }
+ return NS_OK;
+}
+
+PRIntn
+nsComboboxControlFrame::GetSkipSides() const
+{
+ // Don't skip any sides during border rendering
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/mozilla/layout/html/forms/src/nsComboboxControlFrame.h b/mozilla/layout/html/forms/src/nsComboboxControlFrame.h
index 18249aad5b9..5a411f98d7b 100644
--- a/mozilla/layout/html/forms/src/nsComboboxControlFrame.h
+++ b/mozilla/layout/html/forms/src/nsComboboxControlFrame.h
@@ -20,10 +20,12 @@
#define nsComboboxControlFrame_h___
-#include "nsHTMLContainerFrame.h"
+#include "nsAreaFrame.h"
#include "nsIFormControlFrame.h"
#include "nsIComboboxControlFrame.h"
-
+#include "nsIDOMMouseListener.h"
+#include "nsVoidArray.h"
+#include "nsIAnonymousContentCreator.h"
class nsButtonControlFrame;
class nsTextControlFrame;
@@ -33,19 +35,36 @@ class nsStyleContext;
class nsIHTMLContent;
class nsIListControlFrame;
-class nsComboboxControlFrame : public nsHTMLContainerFrame,
+/**
+ * Child list name indices
+ * @see #GetAdditionalChildListName()
+ */
+#define NS_COMBO_FRAME_POPUP_LIST_INDEX (NS_AREA_FRAME_ABSOLUTE_LIST_INDEX + 1)
+
+class nsComboboxControlFrame : public nsAreaFrame,
public nsIFormControlFrame,
- public nsIComboboxControlFrame
+ public nsIComboboxControlFrame,
+ public nsIDOMMouseListener,
+ public nsIAnonymousContentCreator
{
public:
nsComboboxControlFrame();
~nsComboboxControlFrame();
+ // nsISupports
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
+
+ // nsIAnonymousContentCreator
+ NS_IMETHOD CreateAnonymousContent(nsISupportsArray& aChildList);
+
+ // nsIFrame
+ NS_IMETHOD Init(nsIPresContext& aPresContext,
+ nsIContent* aContent,
+ nsIFrame* aParent,
+ nsIStyleContext* aContext,
+ nsIFrame* aPrevInFlow);
- // nsIFrame
-
NS_IMETHOD Reflow(nsIPresContext& aCX,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
@@ -57,45 +76,31 @@ public:
nsStyleChangeList* aChangeList,
PRInt32* aLocalChange);
- NS_IMETHOD Paint(nsIPresContext& aPresContext,
- nsIRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsFramePaintLayer aWhichLayer);
-
- NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
- nsGUIEvent* aEvent,
- nsEventStatus& aEventStatus);
-
NS_IMETHOD GetFrameName(nsString& aResult) const;
+ NS_IMETHOD DeleteFrame(nsIPresContext& aPresContext);
+ NS_IMETHOD FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) const;
+ NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext,
+ nsIAtom* aListName,
+ nsIFrame* aChildList);
+ NS_IMETHOD GetAdditionalChildListName(PRInt32 aIndex,
+ nsIAtom** aListName) const;
-
- virtual PRInt32 GetMaxNumValues();
-
- virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
- nsString* aValues, nsString* aNames);
-
- // nsIFormControLFrame
+ // nsIFormControlFrame
+ NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight);
+ NS_IMETHOD GetName(nsString* aName);
+ NS_IMETHOD GetType(PRInt32* aType) const;
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
void SetFocus(PRBool aOn, PRBool aRepaint);
-
virtual void PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight);
-
-
- //nsTextControlFrame* GetTextFrame() { return mTextFrame; }
-
- //void SetTextFrame(nsTextControlFrame* aFrame) { mTextFrame = aFrame; }
-
- //nsButtonControlFrame* GetBrowseFrame() { return mBrowseFrame; }
- //void SetBrowseFrame(nsButtonControlFrame* aFrame) { mBrowseFrame = aFrame; }
virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter);
virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; }
virtual void Reset();
- NS_IMETHOD GetName(nsString* aName);
- NS_IMETHOD GetType(PRInt32* aType) const;
-
+ virtual PRInt32 GetMaxNumValues();
+ virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
+ nsString* aValues, nsString* aNames);
NS_IMETHOD GetFont(nsIPresContext* aPresContext,
nsFont& aFont);
NS_IMETHOD GetFormContent(nsIContent*& aContent) const;
@@ -107,69 +112,73 @@ public:
float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const;
-
-
virtual nsresult RequiresWidget(PRBool &aRequiresWidget);
-
-
- NS_IMETHOD GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame);
-
- // A Static Helper Functions
-
- // This refreshes a particular pseudo style content when a "ReResolveStyleContent" happens
- static void RefreshStyleContext(nsIPresContext* aPresContext,
- nsIAtom * aNewContentPseudo,
- nsIStyleContext*& aCurrentStyle,
- nsIContent * aContent,
- nsIStyleContext* aParentStyle);
-
// nsIFormMouseListener
virtual void MouseClicked(nsIPresContext* aPresContext);
//nsIComboboxControlFrame
- NS_IMETHOD SetDropDown(nsIFrame* aPlaceHolderFrame, nsIFrame* aDropDownFrame);
- NS_IMETHOD SetDropDownStyleContexts(nsIStyleContext * aVisible, nsIStyleContext * aHidden);
- NS_IMETHOD SetButtonStyleContexts(nsIStyleContext * aOut, nsIStyleContext * aPressed);
+ NS_IMETHOD SetDropDown(nsIFrame* aDropDownFrame);
NS_IMETHOD ListWasSelected(nsIPresContext* aPresContext);
+ //nsIDOMEventListener
+ virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent);
+ virtual nsresult MouseUp(nsIDOMEvent* aMouseEvent) { return NS_OK; }
+ virtual nsresult MouseClick(nsIDOMEvent* aMouseEvent) { printf("mouse clock\n"); return NS_OK; };
+ virtual nsresult MouseDblClick(nsIDOMEvent* aMouseEvent) { return NS_OK; }
+ virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent) { return NS_OK; }
+ virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent) { return NS_OK; }
+ virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }
-protected:
- virtual void PaintComboboxControl(nsIPresContext& aPresContext,
- nsIRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsFramePaintLayer aWhichLayer);
+protected:
+
+ // nsHTMLContainerFrame
virtual PRIntn GetSkipSides() const;
- void InitTextStr();
+
+ // Utilities
+ nsresult ReflowComboChildFrame(nsIFrame* aFrame,
+ nsIPresContext& aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ const nsHTMLReflowState& aReflowState,
+ nsReflowStatus& aStatus,
+ nscoord aAvailableWidth,
+ nscoord aAvailableHeight);
+
+ nsresult GetScreenHeight(nsIPresContext& aPresContext, nscoord& aHeight);
+ nsresult PositionDropdown(nsIPresContext& aPresContext,
+ nscoord aHeight,
+ nsRect aAbsoluteTwipsRect,
+ nsRect aAbsolutePixelRect);
+ nsresult GetAbsoluteFramePosition(nsIPresContext& aPresContext,
+ nsIFrame *aFrame,
+ nsRect& aAbsoluteTwipsRect,
+ nsRect& aAbsolutePixelRect);
+ void ToggleList(nsIPresContext* aPresContext);
+ void ShowPopup(PRBool aShowPopup);
+ void ShowList(nsIPresContext* aPresContext, PRBool aShowList);
+ void SetChildFrameSize(nsIFrame* aFrame, nscoord aWidth, nscoord aHeight);
+ void InitTextStr(PRBool aUpdate);
+ nsresult GetPrimaryComboFrame(nsIPresContext& aPresContext, nsIContent* aContent, nsIFrame** aFrame);
+ nsIFrame* GetButtonFrame(nsIPresContext& aPresContext);
+ nsIFrame* GetDisplayFrame(nsIPresContext& aPresContext);
+ nsIFrame* GetDropdownFrame();
+
+ // Called when the selection has changed. If the the same item in the list is selected
+ // it is NOT called.
void SelectionChanged();
+ nsFrameList mPopupFrames; // additional named child list
+ nsIPresContext* mPresContext; // XXX: Remove the need to cache the pres context.
nsFormFrame* mFormFrame; // Parent Form Frame
- nsIFrame * mPlaceHolderFrame;
- nsIFrame * mListFrame; // Generic nsIFrame
- nsIListControlFrame * mListControlFrame; // Specific ListControl Interface
- nsRect mButtonRect; // The Arrow Button's Rect cached for Painting
-
- // DropDown List Visibility Styles
- nsIStyleContext * mVisibleStyleContext; // Style for the DropDown List to make it visible
- nsIStyleContext * mHiddenStyleContext; // Style for the DropDown List to make it hidden
- nsIStyleContext * mCurrentStyleContext; // The current Style state of the DropDown List
-
- // Arrow Button Styles
- nsIStyleContext * mBtnOutStyleContext; // Style when not pressed
- nsIStyleContext * mBtnPressedStyleContext; // Style When Pressed
- nsIStyleContext * mArrowStyle; // Arrows currrent style (for painting)
-
- // Combobox Text Styles
- nsIStyleContext * mBlockTextStyle; // Style when there is no selection and it doesn't have focus
- nsIStyleContext * mBlockTextSelectedStyle; // Style when selected and it doesn't have focus
- nsIStyleContext * mBlockTextSelectedFocusStyle; // Style when selected and it has focus
-
- PRBool mFirstTime;
-
- // State data members
- nsString mTextStr;
- PRBool mGotFocus;
+ nsString mTextStr; // Current Combo box selection
+ nsIHTMLContent* mDisplayContent; // Anonymous content used to display the current selection
+ nsIHTMLContent* mButtonContent; // Anonymous content used to popup the dropdown list
+ PRBool mDroppedDown; // Current state of the dropdown list, PR_TRUE is dropped down
+ nsIFrame* mDisplayFrame; // frame to display selection
+ nsIFrame* mButtonFrame; // button frame
+ nsIFrame* mDropdownFrame; // dropdown list frame
+ nsIListControlFrame * mListControlFrame; // ListControl Interface for the dropdown frame
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp
index b851e9005de..d21f30f0642 100644
--- a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp
+++ b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp
@@ -70,6 +70,8 @@ NS_NewFileControlFrame(nsIFrame** aNewFrame)
nsFileControlFrame::nsFileControlFrame():mTextFrame(nsnull), mFormFrame(nsnull)
{
+ //Shrink the area around it's contents
+ SetFlags(NS_BLOCK_SHRINK_WRAP);
}
NS_IMETHODIMP
diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.h b/mozilla/layout/html/forms/src/nsFileControlFrame.h
index ad04d5611a8..eef454d3327 100644
--- a/mozilla/layout/html/forms/src/nsFileControlFrame.h
+++ b/mozilla/layout/html/forms/src/nsFileControlFrame.h
@@ -50,7 +50,6 @@ public:
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
-
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD Reflow(nsIPresContext& aCX,
@@ -59,6 +58,7 @@ public:
nsReflowStatus& aStatus);
NS_IMETHOD GetFrameName(nsString& aResult) const;
+ NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight) { return NS_OK; };
virtual PRInt32 GetMaxNumValues();
diff --git a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp
index 4e66e5f974a..7c6b6ac783b 100644
--- a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp
+++ b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp
@@ -67,6 +67,8 @@ nsFormControlFrame::nsFormControlFrame()
mDidInit = PR_FALSE;
mWidget = nsnull;
mFormFrame = nsnull;
+ mSuggestedWidth = NS_FORMSIZE_NOTSET;
+ mSuggestedHeight = NS_FORMSIZE_NOTSET;
}
nsFormControlFrame::~nsFormControlFrame()
@@ -735,3 +737,10 @@ nsresult nsFormControlFrame::RequiresWidget(PRBool & aRequiresWidget)
}
+NS_IMETHODIMP nsFormControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight)
+{
+ mSuggestedWidth = aWidth;
+ mSuggestedHeight = aHeight;
+ return NS_OK;
+}
+
diff --git a/mozilla/layout/html/forms/src/nsFormControlFrame.h b/mozilla/layout/html/forms/src/nsFormControlFrame.h
index dd21114c59e..b68bc0979b5 100644
--- a/mozilla/layout/html/forms/src/nsFormControlFrame.h
+++ b/mozilla/layout/html/forms/src/nsFormControlFrame.h
@@ -36,6 +36,8 @@ class nsFormFrame;
#define CSS_NOTSET -1
#define ATTR_NOTSET -1
+#define NS_FORMSIZE_NOTSET -1
+
/**
* nsFormControlFrame is the base class for frames of form controls. It
* provides a uniform way of creating widgets, resizing, and painting.
@@ -227,6 +229,8 @@ protected:
nsHTMLReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
+ NS_IMETHOD nsFormControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight);
+
//
//-------------------------------------------------------------------------------------
// Utility methods for managing checkboxes and radiobuttons
@@ -274,6 +278,8 @@ protected:
PRBool mDidInit;
nsPoint mLastClickPoint;
nsFormFrame* mFormFrame;
+ nscoord mSuggestedWidth;
+ nscoord mSuggestedHeight;
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
diff --git a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp
index 4af6f406631..ba199cbceb2 100644
--- a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp
+++ b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp
@@ -592,6 +592,13 @@ nsHTMLButtonControlFrame::ReResolveStyleContext ( nsIPresContext* aPresContext,
} // ReResolveStyleContext
+NS_IMETHODIMP nsHTMLButtonControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight)
+{
+// mSuggestedWidth = aWidth;
+// mSuggestedHeight = aHeight;
+ return NS_OK;
+}
+
diff --git a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.h b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.h
index a51107f7f8c..e8c5a3c3884 100644
--- a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.h
+++ b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.h
@@ -131,6 +131,7 @@ public:
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
+ NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight);
protected:
NS_IMETHOD_(nsrefcnt) AddRef(void);
diff --git a/mozilla/layout/html/forms/src/nsImageControlFrame.cpp b/mozilla/layout/html/forms/src/nsImageControlFrame.cpp
index b659bf1837c..5847fee0c5c 100644
--- a/mozilla/layout/html/forms/src/nsImageControlFrame.cpp
+++ b/mozilla/layout/html/forms/src/nsImageControlFrame.cpp
@@ -117,6 +117,7 @@ public:
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
+ NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight);
protected:
void GetTranslatedRect(nsRect& aRect); // XXX this implementation is a copy of nsHTMLButtonControlFrame
@@ -452,3 +453,10 @@ NS_IMETHODIMP nsImageControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
return NS_OK;
}
+
+NS_IMETHODIMP nsImageControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight)
+{
+// mSuggestedWidth = aWidth;
+// mSuggestedHeight = aHeight;
+ return NS_OK;
+}
\ No newline at end of file
diff --git a/mozilla/layout/html/forms/src/nsListControlFrame.cpp b/mozilla/layout/html/forms/src/nsListControlFrame.cpp
index 8f121a517df..8fc1c86149e 100644
--- a/mozilla/layout/html/forms/src/nsListControlFrame.cpp
+++ b/mozilla/layout/html/forms/src/nsListControlFrame.cpp
@@ -37,7 +37,7 @@
#include "nsIReflowCommand.h"
// Constants
-const nscoord kMaxDropDownRows = 20; // This matches the setting for 4.x browsers
+const nscoord kMaxDropDownRows = 20; // This matches the setting for 4.x browsers
const PRInt32 kNothingSelected = -1;
const PRInt32 kMaxZ= 0x7fffffff; //XXX: Shouldn't there be a define somewhere for MaxInt for PRInt32
@@ -54,7 +54,6 @@ static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
-//----------------------------------------------------------------------
nsresult
NS_NewListControlFrame(nsIFrame** aNewFrame)
@@ -71,7 +70,7 @@ NS_NewListControlFrame(nsIFrame** aNewFrame)
return NS_OK;
}
-//----------------------------------------------------------------------
+
nsListControlFrame::nsListControlFrame()
{
mHitFrame = nsnull;
@@ -83,20 +82,20 @@ nsListControlFrame::nsListControlFrame()
mDisplayed = PR_FALSE;
mButtonDown = PR_FALSE;
mLastFrame = nsnull;
+ mMaxWidth = 0;
+ mMaxHeight = 0;
+ mIsCapturingMouseEvents = PR_FALSE;
}
-//----------------------------------------------------------------------
nsListControlFrame::~nsListControlFrame()
{
mComboboxFrame = nsnull;
mFormFrame = nsnull;
}
-//----------------------------------------------------------------------
NS_IMPL_ADDREF(nsListControlFrame)
NS_IMPL_RELEASE(nsListControlFrame)
-//----------------------------------------------------------------------
NS_IMETHODIMP
nsListControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
@@ -108,7 +107,6 @@ nsListControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return NS_OK;
}
if (aIID.Equals(kIListControlFrameIID)) {
- NS_ADDREF_THIS(); // Increase reference count for caller
*aInstancePtr = (void *)((nsIListControlFrame*)this);
return NS_OK;
}
@@ -116,7 +114,7 @@ nsListControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return nsScrollFrame::QueryInterface(aIID, aInstancePtr);
}
-//----------------------------------------------------------------------
+
NS_IMETHODIMP
nsListControlFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
{
@@ -147,7 +145,7 @@ nsListControlFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
}
-//----------------------------------------------------------------------
+
nsresult
nsListControlFrame::GetFrameForPointUsing(const nsPoint& aPoint,
nsIAtom* aList,
@@ -194,7 +192,7 @@ nsListControlFrame::GetFrameForPointUsing(const nsPoint& aPoint,
scrollableView->GetScrollPosition(offsetx, offsety);
tmp.x += offsetx;
tmp.y += offsety;
- // Note: scrollableView is not ref counted so it's interface is not NS_RELEASE'd
+ // Note: scrollableView is not ref counted
}
}
@@ -238,14 +236,13 @@ nsListControlFrame::GetFrameForPointUsing(const nsPoint& aPoint,
}
*aFrame = this;
return NS_ERROR_FAILURE;
-
+
}
-//----------------------------------------------------------------------
// Reflow is overriden to constrain the listbox height to the number of rows and columns
// specified.
-//
+
NS_IMETHODIMP
nsListControlFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@@ -284,10 +281,9 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
nsSize scrolledAreaSize(0,0);
nsHTMLReflowMetrics scrolledAreaDesiredSize(&scrolledAreaSize);
+
if (eReflowReason_Incremental == firstPassState.reason) {
- //XXX: Why do we have to change the reflow type in this
- //case? If we don't an assert in the nsScrollFrame::Reflow prevents
- //execution from continuing. Is the assertion in nsScrollFrame bogus?
+ // When incremental, Reflow everything
nsIFrame* targetFrame;
firstPassState.reflowCommand->GetTarget(targetFrame);
if (this == targetFrame) {
@@ -308,6 +304,8 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
nscoord scrolledAreaWidth = scrolledAreaDesiredSize.maxElementSize->width;
nscoord scrolledAreaHeight = scrolledAreaDesiredSize.height;
+ mMaxWidth = scrolledAreaWidth;
+ mMaxHeight = scrolledAreaDesiredSize.maxElementSize->height;
// The first reflow produces a box with the scrollbar width and borders
// added in so we need to subtract them out.
@@ -342,20 +340,12 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
nscoord visibleWidth = 0;
if (IsInDropDownMode() == PR_TRUE) {
- // Always set the width to be
- // XXX: TODO The width of the list should be passed in so it can
- // be set to the same as the text box + dropdown arrow.
- visibleWidth = scrolledAreaWidth;
- if (nsnull != mComboboxFrame) {
- nsRect comboRect;
- nsIFrame *comboFrame = nsnull;
- if (NS_SUCCEEDED(mComboboxFrame->QueryInterface(kIFrameIID, (void **)&comboFrame))) {
- comboFrame->GetRect(comboRect);
- visibleWidth = comboRect.width;
- visibleWidth -= (border.left + border.right);
- }
- }
-
+ // Calculate visible width for dropdown
+ if (NS_UNCONSTRAINEDSIZE == aReflowState.computedWidth) {
+ visibleWidth = scrolledAreaWidth;
+ } else {
+ visibleWidth = aReflowState.computedWidth - (border.left + border.right);
+ }
} else {
if (NS_UNCONSTRAINEDSIZE == aReflowState.computedWidth) {
visibleWidth = scrolledAreaWidth;
@@ -364,11 +354,11 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
}
}
- // Determine if a scrollbar will be needed, If so we need to add
- // enough the width to allow for the scrollbar.
- // The scrollbar will be needed under two conditions:
- // (size * heightOfaRow) < scrolledAreaHeight or
- // the height set through Style < scrolledAreaHeight.
+ // Determine if a scrollbar will be needed, If so we need to add
+ // enough the width to allow for the scrollbar.
+ // The scrollbar will be needed under two conditions:
+ // (size * heightOfaRow) < scrolledAreaHeight or
+ // the height set through Style < scrolledAreaHeight.
// Calculate the height of a single row in the listbox or dropdown list
// Note: It is calculated based on what layout returns for the maxElement
@@ -428,7 +418,6 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
return NS_OK;
}
-//--------------------------------------------------------------
NS_IMETHODIMP
nsListControlFrame::GetFormContent(nsIContent*& aContent) const
{
@@ -440,7 +429,7 @@ nsListControlFrame::GetFormContent(nsIContent*& aContent) const
return rv;
}
-//--------------------------------------------------------------
+
NS_IMETHODIMP
nsListControlFrame::GetFont(nsIPresContext* aPresContext,
nsFont& aFont)
@@ -450,7 +439,8 @@ nsListControlFrame::GetFont(nsIPresContext* aPresContext,
}
-PRBool nsListControlFrame::IsOptionElement(nsIContent* aContent)
+PRBool
+nsListControlFrame::IsOptionElement(nsIContent* aContent)
{
PRBool result = PR_FALSE;
@@ -466,7 +456,8 @@ PRBool nsListControlFrame::IsOptionElement(nsIContent* aContent)
}
-PRBool nsListControlFrame::IsOptionElementFrame(nsIFrame *aFrame)
+PRBool
+nsListControlFrame::IsOptionElementFrame(nsIFrame *aFrame)
{
nsIContent *content = nsnull;
aFrame->GetContent(&content);
@@ -482,7 +473,8 @@ PRBool nsListControlFrame::IsOptionElementFrame(nsIFrame *aFrame)
// Go up the frame tree looking for the first ancestor that has content
// which is selectable
-nsIFrame *nsListControlFrame::GetSelectableFrame(nsIFrame *aFrame)
+nsIFrame *
+nsListControlFrame::GetSelectableFrame(nsIFrame *aFrame)
{
nsIFrame* selectedFrame = aFrame;
@@ -494,7 +486,8 @@ nsIFrame *nsListControlFrame::GetSelectableFrame(nsIFrame *aFrame)
return(selectedFrame);
}
-void nsListControlFrame::ForceRedraw()
+void
+nsListControlFrame::ForceRedraw()
{
//XXX: Hack. This should not be needed. The problem is DisplaySelected
//and DisplayDeselected set and unset an attribute on generic HTML content
@@ -508,11 +501,12 @@ void nsListControlFrame::ForceRedraw()
// XXX: Here we introduce a new -moz-option-selected attribute so a attribute
// selecitor n the ua.css can change the style when the option is selected.
-void nsListControlFrame::DisplaySelected(nsIContent* aContent)
+void
+nsListControlFrame::DisplaySelected(nsIContent* aContent)
{
//XXX: This is temporary. It simulates psuedo states by using a attribute selector on
// -moz-option-selected in the ua.css style sheet. This will not be needed when
- // The event state manager is functional. KMM
+ // The event state manager supports selected states. KMM
nsCOMPtr selectedAtom ( dont_QueryInterface(NS_NewAtom(kMozSelected)));
if (PR_TRUE == mDisplayed) {
@@ -523,7 +517,8 @@ void nsListControlFrame::DisplaySelected(nsIContent* aContent)
}
}
-void nsListControlFrame::DisplayDeselected(nsIContent* aContent)
+void
+nsListControlFrame::DisplayDeselected(nsIContent* aContent)
{
//XXX: This is temporary. It simulates psuedo states by using a attribute selector on
// -moz-option-selected in the ua.css style sheet. This will not be needed when
@@ -540,8 +535,9 @@ void nsListControlFrame::DisplayDeselected(nsIContent* aContent)
}
-//----------------------------------------------------------------------
-PRInt32 nsListControlFrame::GetSelectedIndex(nsIFrame *aHitFrame)
+
+PRInt32
+nsListControlFrame::GetSelectedIndex(nsIFrame *aHitFrame)
{
PRInt32 index = kNothingSelected;
// Get the content of the frame that was selected
@@ -575,19 +571,20 @@ PRInt32 nsListControlFrame::GetSelectedIndex(nsIFrame *aHitFrame)
return index;
}
-//----------------------------------------------------------------------
-void nsListControlFrame::ClearSelection()
+
+void
+nsListControlFrame::ClearSelection()
{
PRUint32 length = GetNumberOfOptions();
- for (PRInt32 i = 0; i < (PRInt32)length; i++) {
- if (i != mSelectedIndex) {
- SetFrameSelected(i, PR_FALSE);
- }
- }
+ for (PRInt32 i = 0; i < (PRInt32)length; i++) {
+ if (i != mSelectedIndex) {
+ SetFrameSelected(i, PR_FALSE);
+ }
+ }
}
-//----------------------------------------------------------------------
-void nsListControlFrame::ExtendedSelection(PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aDoInvert, PRBool aSetValue)
+void
+nsListControlFrame::ExtendedSelection(PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aDoInvert, PRBool aSetValue)
{
PRInt32 startInx;
PRInt32 endInx;
@@ -621,7 +618,8 @@ void nsListControlFrame::ExtendedSelection(PRInt32 aStartIndex, PRInt32 aEndInde
}
}
-void nsListControlFrame::SingleSelection()
+void
+nsListControlFrame::SingleSelection()
{
if (nsnull != mHitFrame) {
// Store previous selection
@@ -644,7 +642,8 @@ void nsListControlFrame::SingleSelection()
}
}
-void nsListControlFrame::MultipleSelection(PRBool aIsShift, PRBool aIsControl)
+void
+nsListControlFrame::MultipleSelection(PRBool aIsShift, PRBool aIsControl)
{
if (nsnull != mHitFrame) {
mSelectedIndex = (PRInt32)GetSelectedIndex(mHitFrame);
@@ -696,15 +695,13 @@ void nsListControlFrame::MultipleSelection(PRBool aIsShift, PRBool aIsControl)
ClearSelection();
}
}
-
- //XXX Fix this mHitContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::kClass, (selected?kSelectedFocus:kNormal), PR_TRUE);
}
-
}
-void nsListControlFrame::HandleListSelection(nsIPresContext& aPresContext,
- nsGUIEvent* aEvent,
- nsEventStatus& aEventStatus)
+void
+nsListControlFrame::HandleListSelection(nsIPresContext& aPresContext,
+ nsGUIEvent* aEvent,
+ nsEventStatus& aEventStatus)
{
if (mMultipleSelections) {
MultipleSelection(((nsMouseEvent *)aEvent)->isShift, ((nsMouseEvent *)aEvent)->isControl);
@@ -713,7 +710,8 @@ void nsListControlFrame::HandleListSelection(nsIPresContext& aPresContext,
}
}
-PRBool nsListControlFrame::HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2)
+PRBool
+nsListControlFrame::HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2)
{
// Quick check, if the frames are equal they must have
// the same content
@@ -735,8 +733,8 @@ PRBool nsListControlFrame::HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2)
}
-//----------------------------------------------------------------------
-NS_IMETHODIMP nsListControlFrame::HandleLikeListEvent(nsIPresContext& aPresContext,
+nsresult
+nsListControlFrame::HandleLikeListEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
@@ -762,6 +760,7 @@ NS_IMETHODIMP nsListControlFrame::HandleLikeListEvent(nsIPresContext& aPresConte
NS_IMETHODIMP
nsListControlFrame :: CaptureMouseEvents(PRBool aGrabMouseEvents)
{
+
// get its view
nsIView* view = nsnull;
GetView(&view);
@@ -773,8 +772,10 @@ nsListControlFrame :: CaptureMouseEvents(PRBool aGrabMouseEvents)
if (viewMan) {
if (aGrabMouseEvents) {
viewMan->GrabMouseEvents(view,result);
+ mIsCapturingMouseEvents = PR_TRUE;
} else {
viewMan->GrabMouseEvents(nsnull,result);
+ mIsCapturingMouseEvents = PR_FALSE;
}
}
}
@@ -782,7 +783,8 @@ nsListControlFrame :: CaptureMouseEvents(PRBool aGrabMouseEvents)
return NS_OK;
}
-nsIView* nsListControlFrame::GetViewFor(nsIWidget* aWidget)
+nsIView*
+nsListControlFrame::GetViewFor(nsIWidget* aWidget)
{
nsIView* view = nsnull;
void* clientData;
@@ -799,7 +801,8 @@ nsIView* nsListControlFrame::GetViewFor(nsIWidget* aWidget)
// Determine if a view is an ancestor of another view.
-PRBool nsListControlFrame::IsAncestor(nsIView* aAncestor, nsIView* aChild)
+PRBool
+nsListControlFrame::IsAncestor(nsIView* aAncestor, nsIView* aChild)
{
nsIView* view = aChild;
while (nsnull != view) {
@@ -814,10 +817,11 @@ PRBool nsListControlFrame::IsAncestor(nsIView* aAncestor, nsIView* aChild)
return(PR_FALSE);
}
-//----------------------------------------------------------------------
-NS_IMETHODIMP nsListControlFrame::HandleLikeDropDownListEvent(nsIPresContext& aPresContext,
- nsGUIEvent* aEvent,
- nsEventStatus& aEventStatus)
+
+nsresult
+nsListControlFrame::HandleLikeDropDownListEvent(nsIPresContext& aPresContext,
+ nsGUIEvent* aEvent,
+ nsEventStatus& aEventStatus)
{
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) {
if (nsnull == mHitFrame) {
@@ -883,12 +887,14 @@ NS_IMETHODIMP nsListControlFrame::HandleLikeDropDownListEvent(nsIPresContext& aP
return NS_OK;
}
-//----------------------------------------------------------------------
-NS_IMETHODIMP nsListControlFrame::HandleEvent(nsIPresContext& aPresContext,
+
+NS_IMETHODIMP
+nsListControlFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
-/* const char * desc[] = {"NS_MOUSE_MOVE",
+/*
+ const char * desc[] = {"NS_MOUSE_MOVE",
"NS_MOUSE_LEFT_BUTTON_UP",
"NS_MOUSE_LEFT_BUTTON_DOWN",
"","","","","","","",
@@ -910,8 +916,8 @@ NS_IMETHODIMP nsListControlFrame::HandleEvent(nsIPresContext& aPresContext,
printf("Mouse in ListFrame %s [%d]\n", desc[inx], aEvent->message);
} else {
printf("Mouse in ListFrame [%d]\n", aEvent->message);
- }*/
-
+ }
+*/
if (nsEventStatus_eConsumeNoDefault == aEventStatus) {
return NS_OK;
}
@@ -930,7 +936,7 @@ NS_IMETHODIMP nsListControlFrame::HandleEvent(nsIPresContext& aPresContext,
return NS_OK;
}
-//----------------------------------------------------------------------
+
NS_IMETHODIMP
nsListControlFrame::SetInitialChildList(nsIPresContext& aPresContext,
nsIAtom* aListName,
@@ -945,7 +951,7 @@ nsListControlFrame::SetInitialChildList(nsIPresContext& aPresContext,
return nsScrollFrame::SetInitialChildList(aPresContext, aListName, aChildList);
}
-//----------------------------------------------------------------------
+
NS_IMETHODIMP
nsListControlFrame::Init(nsIPresContext& aPresContext,
nsIContent* aContent,
@@ -977,7 +983,7 @@ nsListControlFrame::Init(nsIPresContext& aPresContext,
return result;
}
-//----------------------------------------------------------------------
+
nscoord
nsListControlFrame::GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const
@@ -985,7 +991,7 @@ nsListControlFrame::GetVerticalInsidePadding(float aPixToTwip,
return NSIntPixelsToTwips(0, aPixToTwip);
}
-//----------------------------------------------------------------------
+
nscoord
nsListControlFrame::GetHorizontalInsidePadding(nsIPresContext& aPresContext,
float aPixToTwip,
@@ -996,7 +1002,6 @@ nsListControlFrame::GetHorizontalInsidePadding(nsIPresContext& aPresContext,
}
-//----------------------------------------------------------------------
NS_IMETHODIMP
nsListControlFrame::GetMultiple(PRBool* aMultiple, nsIDOMHTMLSelectElement* aSelect)
{
@@ -1013,7 +1018,7 @@ nsListControlFrame::GetMultiple(PRBool* aMultiple, nsIDOMHTMLSelectElement* aSel
}
}
-//----------------------------------------------------------------------
+
nsIDOMHTMLSelectElement*
nsListControlFrame::GetSelect(nsIContent * aContent)
{
@@ -1026,7 +1031,7 @@ nsListControlFrame::GetSelect(nsIContent * aContent)
}
}
-//----------------------------------------------------------------------
+
NS_IMETHODIMP
nsListControlFrame::AboutToDropDown()
{
@@ -1034,7 +1039,6 @@ nsListControlFrame::AboutToDropDown()
return(SyncViewWithFrame());
}
-
nsIContent*
nsListControlFrame::GetOptionAsContent(nsIDOMHTMLCollection* aCollection,PRUint32 aIndex)
{
@@ -1101,7 +1105,6 @@ nsListControlFrame::SetFrameSelected(PRUint32 aIndex, PRBool aSelected)
NS_IF_RELEASE(content);
}
-//----------------------------------------------------------------------
void
nsListControlFrame::InitializeFromContent()
{
@@ -1127,7 +1130,7 @@ nsListControlFrame::InitializeFromContent()
}
-//----------------------------------------------------------------------
+
nsIDOMHTMLCollection*
nsListControlFrame::GetOptions(nsIContent * aContent, nsIDOMHTMLSelectElement* aSelect)
{
@@ -1147,7 +1150,6 @@ nsListControlFrame::GetOptions(nsIContent * aContent, nsIDOMHTMLSelectElement* a
}
}
-//----------------------------------------------------------------------
nsIDOMHTMLOptionElement*
nsListControlFrame::GetOption(nsIDOMHTMLCollection& aCollection, PRUint32 aIndex)
{
@@ -1163,7 +1165,7 @@ nsListControlFrame::GetOption(nsIDOMHTMLCollection& aCollection, PRUint32 aIndex
return nsnull;
}
-//----------------------------------------------------------------------
+
PRBool
nsListControlFrame::GetOptionValue(nsIDOMHTMLCollection& aCollection, PRUint32 aIndex, nsString& aValue)
{
@@ -1184,36 +1186,27 @@ nsListControlFrame::GetOptionValue(nsIDOMHTMLCollection& aCollection, PRUint32 a
return status;
}
-//----------------------------------------------------------------------
-NS_IMETHODIMP
+nsresult
nsListControlFrame::Deselect()
{
PRInt32 i;
PRInt32 max = GetNumberOfOptions();
for (i=0;iQueryInterface(kIDOMHTMLSelectElementIID, (void**)&dselect);
- if (NS_OK == result) {
- result = dselect->GetSize(&size);
+ nsresult result = aContent->QueryInterface(kIDOMHTMLSelectElementIID, (void**)&select);
+ if (NS_SUCCEEDED(result)) {
+ result = select->GetSize(&size);
if ((1 == size) || (kNoSizeSpecified == size)) {
- // Construct a frame-based combo box
- nsIFrame * comboboxFrame;
- rv = NS_NewComboboxControlFrame(&comboboxFrame);
+ // Construct a frame-based combo box.
+ // The frame-based combo box is built out of tree parts. A display area, a button and
+ // a dropdown list. The display area and button are created through anonymous content.
+ // The drop-down list's frame is created explicitly. The combobox frame shares it's content
+ // with the drop-down list.
+ nsIFrame * comboboxFrame;
+ rv = NS_NewComboboxControlFrame(&comboboxFrame);
- nsIFrame* geometricParent = aParentFrame;
- if (aIsAbsolutelyPositioned) {
- geometricParent = aState.mAbsoluteItems.containingBlock;
- } else if (aIsFixedPositioned) {
- geometricParent = aState.mFixedItems.containingBlock;
+ // Determine geometric parent for the combobox frame
+ nsIFrame* geometricParent = aParentFrame;
+ if (aIsAbsolutelyPositioned) {
+ geometricParent = aState.mAbsoluteItems.containingBlock;
+ } else if (aIsFixedPositioned) {
+ geometricParent = aState.mFixedItems.containingBlock;
+ }
+ // Initialize the combobox frame
+ comboboxFrame->Init(*aPresContext, aContent, geometricParent, aStyleContext, nsnull);
+ nsIComboboxControlFrame* comboBox = nsnull;
+ if (NS_SUCCEEDED(comboboxFrame->QueryInterface(kIComboboxControlFrameIID, (void**)&comboBox))) {
+ // Create a listbox
+ nsIFrame * listFrame;
+ rv = NS_NewListControlFrame(&listFrame);
+
+ // Notify the listbox that it is being used as a dropdown list.
+ nsIListControlFrame * listControlFrame;
+ if (NS_SUCCEEDED(listFrame->QueryInterface(kIListControlFrameIID, (void**)&listControlFrame))) {
+ listControlFrame->SetComboboxFrame(comboboxFrame);
}
-
- comboboxFrame->Init(*aPresContext, aContent, geometricParent, aStyleContext, nsnull);
- nsIComboboxControlFrame* comboBox = nsnull;
- if (NS_OK == comboboxFrame->QueryInterface(kIComboboxControlFrameIID, (void**)&comboBox)) {
- nsIFrame * listFrame;
- rv = NS_NewListControlFrame(&listFrame);
-
- // Get the style context that has been set for the combo box so it can be passed used
- // to create the style context's for the drop down list.
- nsIStyleContext* comboStyleContext;
- comboboxFrame->GetStyleContext(&comboStyleContext);
-
- // This is important to do before it is initialized
- // it tells it that it is in "DropDown Mode"
- nsIListControlFrame * listControlFrame;
- if (NS_OK == listFrame->QueryInterface(kIListControlFrameIID, (void**)&listControlFrame)) {
- listControlFrame->SetComboboxFrame(comboboxFrame);
- }
-
- //XXX: TODO: Make sure that a failure to resolve the following
- //pseudo style will still work.
-
- // Set up the Pseudo Style contents
-
- // Dropdown list style
- nsCOMPtr listStyle;
- aPresContext->ResolvePseudoStyleContextFor
- (aContent, nsHTMLAtoms::dropDownList, comboStyleContext, PR_FALSE,
- getter_AddRefs(listStyle));
+ // Notify combobox that it should use the listbox as it's popup
+ comboBox->SetDropDown(listFrame);
- // Dropdown list visible style
- nsCOMPtr visiblePseudoStyle;
- aPresContext->ResolvePseudoStyleContextFor
- (aContent, nsHTMLAtoms::dropDownVisible, comboStyleContext, PR_FALSE,
- getter_AddRefs(visiblePseudoStyle));
-
- // Dropdown list hidden style
- nsCOMPtr hiddenPseudoStyle;
- aPresContext->ResolvePseudoStyleContextFor
- (aContent, nsHTMLAtoms::dropDownHidden, comboStyleContext, PR_FALSE,
- getter_AddRefs(hiddenPseudoStyle));
+ // Resolve psuedo element style for the dropdown list
+ nsCOMPtr listStyle;
+ rv = aPresContext->ResolvePseudoStyleContextFor(aContent,
+ nsHTMLAtoms::dropDownListPseudo,
+ aStyleContext,
+ PR_FALSE,
+ getter_AddRefs(listStyle));
- // Done creating drop-down list style contexts
- NS_RELEASE(comboStyleContext);
+ // Initialize the scroll frame positioned. Note that it is NOT initialized as
+ // absolutely positioned.
+ nsIFrame* newFrame = nsnull;
+ InitializeScrollFrame(aPresContext, aState, listFrame, aContent, comboboxFrame,
+ listStyle, newFrame, PR_FALSE, PR_FALSE, PR_TRUE);
- // Initialize the scroll frame as absolutely positioned.
- InitializeScrollFrame(aPresContext, aState, listFrame, aContent, comboboxFrame,
- listStyle, aNewFrame, PR_TRUE, PR_FALSE, PR_TRUE);
+ // Set flag so the events go to the listFrame not child frames.
+ // XXX: We should replace this with a real widget manager similar
+ // to how the nsFormControlFrame works. Re-directing events is a temporary Kludge.
+ nsIView *listView;
+ listFrame->GetView(&listView);
+ NS_ASSERTION(nsnull != listView,"ListFrame's view is nsnull");
+ listView->SetViewFlags(NS_VIEW_PUBLIC_FLAG_DONT_CHECK_CHILDREN);
-
- // Set flag so the events go to the listFrame not child frames.
- // XXX: We should replace this with a real widget manager similar
- // to how the nsFormControlFrame works.
- // Re-directing events is a temporary Kludge.
- nsIView *listView;
- listFrame->GetView(&listView);
- NS_ASSERTION(nsnull != listView,"ListFrame's view is nsnull");
- listView->SetViewFlags(NS_VIEW_PUBLIC_FLAG_DONT_CHECK_CHILDREN);
-
- // Set initial visibility to hidden for the drop-down list
- // XXX: This should not be necessary. Need to restructure the combo box as follows:
- // Derive nsComboboxFrame from nsAreaFrame. Attach the placeholder frame, a label frame and
- // a button frame. Override reresolve style context and reresolve the style on the ListBox.
- // The event state manager should then be asked to set active and non-active based on
- // The mouse click this would get rid of all of the ugly code here. The setting of the active
- // Should cause re-resolution of the AreaFrame which will re-sync it. KMM.
- listFrame->ReResolveStyleContext(aPresContext, hiddenPseudoStyle, NS_STYLE_HINT_NONE, nsnull, nsnull);
- listView->SetVisibility(nsViewVisibility_kHide);
-
-
- // Create a place holder frame for the dropdown list
- nsIFrame* placeholderFrame = nsnull;
- CreatePlaceholderFrameFor(aPresContext, aContent, aNewFrame, aStyleContext,
- aParentFrame, &placeholderFrame);
- aFrameItems.AddChild(placeholderFrame);
-
- // Add the absolutely positioned frame to its containing block's list
- // of child frames
- aState.mAbsoluteItems.AddChild(listFrame);
-
- listFrame = aNewFrame;
-
- // This needs to be done "after" the ListFrame has it's ChildList set
- // because the SetInitChildList intializes the ListBox selection state
- // and this method initializes the ComboBox's selection state
- comboBox->SetDropDown(placeholderFrame, listFrame);
-
-
- // Set up the Pseudo Style contents for combo box button pressed and
- // out.
- //XXX: TODO: Make this work even if resolving the pseudo style fails.
-
- nsCOMPtr outPseudoStyle;
- aPresContext->ResolvePseudoStyleContextFor
- (aContent, nsHTMLAtoms::dropDownBtnOut, aStyleContext, PR_FALSE,
- getter_AddRefs(outPseudoStyle));
-
- nsCOMPtr pressPseudoStyle;
- aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::dropDownBtnPressed,
- aStyleContext, PR_FALSE, getter_AddRefs(pressPseudoStyle));
-
- comboBox->SetDropDownStyleContexts(visiblePseudoStyle, hiddenPseudoStyle);
- comboBox->SetButtonStyleContexts(outPseudoStyle, pressPseudoStyle);
+ nsIFrame* frame = nsnull;
+ if (NS_SUCCEEDED(comboboxFrame->QueryInterface(kIFrameIID, (void**)&frame))) {
+ nsFrameItems childItems;
- nsIFrame* frame = nsnull;
- if (NS_OK == comboboxFrame->QueryInterface(kIFrameIID, (void**)&frame)) {
- nsFrameItems childItems;
- frame->SetInitialChildList(*aPresContext, nsnull,
- childItems.childList);
- }
- aProcessChildren = PR_FALSE;
- //XXX: TODO: Need to set an option on the view that was created for the dropdown list
- //to be a borderless top-level window.
-
- aNewFrame = comboboxFrame;
- aFrameHasBeenInitialized = PR_TRUE;
- }
+ // Create display and button frames from the combobox'es anonymous content
+ CreateAnonymousFrames(aPresContext, nsHTMLAtoms::combobox, aState, aContent, frame,
+ childItems);
+
+ frame->SetInitialChildList(*aPresContext, nsnull,
+ childItems.childList);
+ // Initialize the additional popup child list which contains the dropdown list frame.
+ nsFrameItems popupItems;
+ popupItems.AddChild(listFrame);
+ frame->SetInitialChildList(*aPresContext, nsLayoutAtoms::popupList,
+ popupItems.childList);
+ }
+ // Don't process, the children, They are already processed by the InitializeScrollFrame
+ // call above.
+ aProcessChildren = PR_FALSE;
+ aNewFrame = comboboxFrame;
+ aFrameHasBeenInitialized = PR_TRUE;
+ }
} else {
// Construct a frame-based list box
nsIFrame * listFrame;
@@ -2550,7 +2498,7 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContex
listView->SetViewFlags(NS_VIEW_PUBLIC_FLAG_DONT_CHECK_CHILDREN);
aFrameHasBeenInitialized = PR_TRUE;
}
- NS_RELEASE(dselect);
+ NS_RELEASE(select);
} else {
rv = NS_NewSelectControlFrame(&aNewFrame);
}
@@ -2739,6 +2687,7 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext
PR_TRUE, childItems);
}
+
// if there are any anonymous children create frames for them
CreateAnonymousFrames(aPresContext, aTag, aState, aContent, newFrame,
childItems);
@@ -2818,14 +2767,21 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresContext* aPresConte
// only these tags types can have anonymous content. We do this check for performance
// reasons. If we did a query interface on every tag it would be very inefficient.
if (aTag != nsHTMLAtoms::input &&
+ aTag != nsHTMLAtoms::combobox &&
aTag != nsXULAtoms::slider &&
aTag != nsXULAtoms::splitter &&
- aTag != nsXULAtoms::scrollbar) {
+ aTag != nsXULAtoms::scrollbar
+ ) {
return NS_OK;
}
-
+ // get the document
+ nsIDocument* doc = nsnull;
+ nsresult rv = aContent->GetDocument(doc);
+ if (NS_FAILED(rv) || !doc)
+ return rv;
+
nsCOMPtr creator(do_QueryInterface(aNewFrame));
if (!creator)
@@ -2849,6 +2805,8 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresContext* aPresConte
nsCOMPtr content(do_QueryInterface(node));
content->SetParent(aContent);
+ content->SetDocument(doc, PR_TRUE);
+
// create the frame and attach it to our frame
ConstructFrame(aPresContext, aState, content, aNewFrame, PR_FALSE, aChildItems);
}
diff --git a/mozilla/layout/html/style/src/nsCSSFrameConstructor.h b/mozilla/layout/html/style/src/nsCSSFrameConstructor.h
index 29b85b2444b..93584718afc 100644
--- a/mozilla/layout/html/style/src/nsCSSFrameConstructor.h
+++ b/mozilla/layout/html/style/src/nsCSSFrameConstructor.h
@@ -407,6 +407,7 @@ protected:
nsresult ConstructTextControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame);
+
nsresult ConstructSelectFrame(nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
diff --git a/mozilla/layout/style/ua.css b/mozilla/layout/style/ua.css
index 83377947f49..bee93ddf577 100644
--- a/mozilla/layout/style/ua.css
+++ b/mozilla/layout/style/ua.css
@@ -429,6 +429,18 @@ input[type=hidden] {
border: none;
visibility: hidden;
}
+
+
+input[type=file] {
+ white-space: nowrap;
+ border:none;
+}
+
+/* browse button for file selector */
+input[type=file] input[type=button] {
+ height:inherit;
+}
+
input[type=radio] {
/* these margins are for NavQuirks, we need a Standard ua.css */
margin-left: 3px;
@@ -738,8 +750,8 @@ label {
/* Combo box style */
select, select[size="1"] {
vertical-align: bottom;
- border: 1px inset #c0c0c0;
- background-color:rgb(204, 204, 204);
+ border: none;
+ background-color:rgb(204, 204, 204);
color:black;
white-space:nowrap;
text-align: left;
@@ -751,10 +763,53 @@ select[size] {
border: 1px inset rgb(153, 153, 153);
}
-select:active {
- border : 1px solid black;
+select[size="1"] {
+ vertical-align: bottom;
+ border: none;
+ background-color:rgb(204, 204, 204);
+ color:black;
+ white-space:nowrap;
+ text-align: left;
}
+
+/* combobox button */
+select input[type=button] {
+ border: outset 1px rgb(204, 204, 204);
+ background-image:url("arrow.gif");
+ background-repeat:no-repeat;
+ background-position:center;
+ width:12px;
+ height:12px;
+ -moz-border-radius:0px;
+}
+
+/* combobox display area */
+select input#-moz-display {
+ border: inset 1px rgb(204, 204, 204);
+ background-color: white;
+ background-image: none;
+ -moz-border-radius:0px;
+ padding-left: 0px;
+ padding-right: 0px;
+ padding-top: 0px;
+ padding-bottom: 0px;
+}
+
+/* combbox display area - active */
+select input#-moz-display:active {
+ border: inset 1px rgb(204, 204, 204);
+ background-color:white;
+ background-image: none;
+ -moz-border-radius:0px;
+ padding-left: 0px;
+ padding-right: 0px;
+ padding-top: 0px;
+ padding-bottom: 0px;
+ background-color:white;
+}
+
+
option {
display:block;
padding-left:3px;
@@ -985,47 +1040,20 @@ sourcetext { /* XXX should not be in HTML namespace */
display: none;
}
-:-moz-dropdown-visible {
- visibility: visible;
-}
-
-:-moz-dropdown-hidden {
- visibility: hidden;
-}
-
-:-moz-dropdown-btn-out {
- border: 2px outset #c0c0c0;
- background-color: rgb(206, 207, 206);
-}
-
-:-moz-dropdown-btn-pressed {
-/* border: 2px inset #c0c0c0; */
- background-color: rgb(204, 204, 204);
- border: none;
-}
-
+/* combobox dropdown list */
:-moz-dropdown-list {
- position:absolute;
- background-color:rgb(204, 204, 204);
- border: 1px inset rgb(153, 153, 153);
+ background-color:inherit;
+ border: 1px inset rgb(153, 153, 153);
}
-
-:-moz-combobox-text {
- color: black;
- padding-left: 2px;
+/* combobox dropdown list hidden */
+select:-moz-dropdown-list {
+ visibility:hidden;
}
-:-moz-combobox-textselected {
- background-color: rgb(0,0,128);
- color: white;
- border: 1px solid rgb(0,0,128);
-}
-
-:-moz-combobox-textselectedfocus {
- background-color: rgb(0,0,128);
- color: white;
- border: 1px dotted white;
+/* combobox dropdown list visible */
+select[-moz-dropdown-active]:-moz-dropdown-list {
+ visibility: visible;
}
:-moz-anonymous-block {
diff --git a/mozilla/webshell/tests/viewer/samples/mozform.css b/mozilla/webshell/tests/viewer/samples/mozform.css
index 79dd0e7b6cd..f1b1b01f3da 100644
--- a/mozilla/webshell/tests/viewer/samples/mozform.css
+++ b/mozilla/webshell/tests/viewer/samples/mozform.css
@@ -161,25 +161,51 @@ button:focus:-moz-focus-inner {
background-color:rgb(200, 200, 200);
}
-
/* Combo box style */
select, select[size="1"] {
vertical-align: bottom;
- border: 1px inset #c0c0c0;
- background-color:rgb(204, 204, 204);
+ border: none;
+ background-color:rgb(204, 204, 204);
color:black;
white-space:nowrap;
text-align: left;
}
-/* Listbox style */
-select[size] {
- background-color: white;
- border: 1px inset rgb(153, 153, 153);
+
+/* combobox button */
+select input[type=button] {
+ border: outset 1px rgb(204, 204, 204);
+ background-image:url("arrow.gif");
+ background-repeat:no-repeat;
+ background-position:center;
+ width:12px;
+ height:12px;
+ -moz-border-radius:0px;
}
-select:active {
- border : 1px solid black;
+/* combobox display area */
+select input#-moz-display {
+ border: inset 1px rgb(204, 204, 204);
+ background-color: white;
+ background-image: none;
+ -moz-border-radius:0px;
+ padding-left: 0px;
+ padding-right: 0px;
+ padding-top: 0px;
+ padding-bottom: 0px;
+}
+
+/* combbox display area - active */
+select input#-moz-display:active {
+ border: inset 1px rgb(204, 204, 204);
+ background-color:white;
+ background-image: none;
+ -moz-border-radius:0px;
+ padding-left: 0px;
+ padding-right: 0px;
+ padding-top: 0px;
+ padding-bottom: 0px;
+ background-color:white;
}
option {
diff --git a/mozilla/webshell/tests/viewer/samples/test16.html b/mozilla/webshell/tests/viewer/samples/test16.html
index 2eb05453566..2d893acf4c6 100644
--- a/mozilla/webshell/tests/viewer/samples/test16.html
+++ b/mozilla/webshell/tests/viewer/samples/test16.html
@@ -114,10 +114,10 @@ function usestyle(styletype)
group 2
-