diff --git a/content/html/content/src/nsHTMLAtoms.cpp b/content/html/content/src/nsHTMLAtoms.cpp
index 026b7f7351dc..a49ce9e24611 100644
--- a/content/html/content/src/nsHTMLAtoms.cpp
+++ b/content/html/content/src/nsHTMLAtoms.cpp
@@ -211,6 +211,7 @@ nsIAtom* nsHTMLAtoms::pre;
nsIAtom* nsHTMLAtoms::processingInstructionPseudo;
nsIAtom* nsHTMLAtoms::profile;
nsIAtom* nsHTMLAtoms::prompt;
+nsIAtom* nsHTMLAtoms::radioPseudo;
nsIAtom* nsHTMLAtoms::readonly;
nsIAtom* nsHTMLAtoms::rel;
nsIAtom* nsHTMLAtoms::repeat;
@@ -481,6 +482,7 @@ void nsHTMLAtoms::AddrefAtoms()
processingInstructionPseudo = NS_NewAtom(":-moz-pi");
profile = NS_NewAtom("profile");
prompt = NS_NewAtom("prompt");
+ radioPseudo = NS_NewAtom(":-moz-radio");
readonly = NS_NewAtom("readonly");
rel = NS_NewAtom("rel");
repeat = NS_NewAtom("repeat");
@@ -740,6 +742,7 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(processingInstructionPseudo);
NS_RELEASE(profile);
NS_RELEASE(prompt);
+ NS_RELEASE(radioPseudo);
NS_RELEASE(readonly);
NS_RELEASE(rel);
NS_RELEASE(repeat);
diff --git a/content/html/content/src/nsHTMLAtoms.h b/content/html/content/src/nsHTMLAtoms.h
index eb556d3dbd18..9dff9cbb1e61 100644
--- a/content/html/content/src/nsHTMLAtoms.h
+++ b/content/html/content/src/nsHTMLAtoms.h
@@ -243,7 +243,8 @@ public:
static nsIAtom* processingInstructionPseudo;
static nsIAtom* profile;
static nsIAtom* prompt;
-
+
+ static nsIAtom* radioPseudo;
static nsIAtom* readonly;
static nsIAtom* rel;
static nsIAtom* repeat;
diff --git a/content/shared/public/nsHTMLAtoms.h b/content/shared/public/nsHTMLAtoms.h
index eb556d3dbd18..9dff9cbb1e61 100644
--- a/content/shared/public/nsHTMLAtoms.h
+++ b/content/shared/public/nsHTMLAtoms.h
@@ -243,7 +243,8 @@ public:
static nsIAtom* processingInstructionPseudo;
static nsIAtom* profile;
static nsIAtom* prompt;
-
+
+ static nsIAtom* radioPseudo;
static nsIAtom* readonly;
static nsIAtom* rel;
static nsIAtom* repeat;
diff --git a/content/shared/src/nsHTMLAtoms.cpp b/content/shared/src/nsHTMLAtoms.cpp
index 026b7f7351dc..a49ce9e24611 100644
--- a/content/shared/src/nsHTMLAtoms.cpp
+++ b/content/shared/src/nsHTMLAtoms.cpp
@@ -211,6 +211,7 @@ nsIAtom* nsHTMLAtoms::pre;
nsIAtom* nsHTMLAtoms::processingInstructionPseudo;
nsIAtom* nsHTMLAtoms::profile;
nsIAtom* nsHTMLAtoms::prompt;
+nsIAtom* nsHTMLAtoms::radioPseudo;
nsIAtom* nsHTMLAtoms::readonly;
nsIAtom* nsHTMLAtoms::rel;
nsIAtom* nsHTMLAtoms::repeat;
@@ -481,6 +482,7 @@ void nsHTMLAtoms::AddrefAtoms()
processingInstructionPseudo = NS_NewAtom(":-moz-pi");
profile = NS_NewAtom("profile");
prompt = NS_NewAtom("prompt");
+ radioPseudo = NS_NewAtom(":-moz-radio");
readonly = NS_NewAtom("readonly");
rel = NS_NewAtom("rel");
repeat = NS_NewAtom("repeat");
@@ -740,6 +742,7 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(processingInstructionPseudo);
NS_RELEASE(profile);
NS_RELEASE(prompt);
+ NS_RELEASE(radioPseudo);
NS_RELEASE(readonly);
NS_RELEASE(rel);
NS_RELEASE(repeat);
diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp
index e78dc10f274b..89a4d5028a8a 100644
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -49,6 +49,7 @@
#include "nsLayoutAtoms.h"
#include "nsIDOMHTMLSelectElement.h"
#include "nsIComboboxControlFrame.h"
+#include "nsIRadioControlFrame.h"
#include "nsIListControlFrame.h"
#include "nsIDOMCharacterData.h"
#include "nsIDOMHTMLImageElement.h"
@@ -122,6 +123,7 @@ static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID);
static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIComboboxControlFrameIID, NS_ICOMBOBOXCONTROLFRAME_IID);
+static NS_DEFINE_IID(kIRadioControlFrameIID, NS_IRADIOCONTROLFRAME_IID);
static NS_DEFINE_IID(kIListControlFrameIID, NS_ILISTCONTROLFRAME_IID);
static NS_DEFINE_IID(kIDOMHTMLImageElementIID, NS_IDOMHTMLIMAGEELEMENT_IID);
static NS_DEFINE_IID(kIDOMCharacterDataIID, NS_IDOMCHARACTERDATA_IID);
@@ -765,7 +767,7 @@ nsCSSFrameConstructor::CreateInputFrame(nsIPresContext *aPresContext,
rv = ConstructTextControlFrame(aPresContext, aFrame);
}
else if (val.EqualsIgnoreCase("radio")) {
- rv = NS_NewRadioControlFrame(&aFrame);
+ rv = ConstructRadioControlFrame(aPresContext, aFrame, aContent);
}
else if (val.EqualsIgnoreCase("text")) {
rv = ConstructTextControlFrame(aPresContext, aFrame);
@@ -2233,6 +2235,23 @@ nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresContext* aPresContext,
return rv;
}
+nsresult
+nsCSSFrameConstructor::ConstructRadioControlFrame(nsIPresContext* aPresContext,
+ nsIFrame*& aNewFrame,
+ nsIContent* aContent)
+{
+ nsresult rv = NS_NewRadioControlFrame(&aNewFrame);
+ nsCOMPtr radioStyle;
+ aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::radioPseudo,
+ radioStyle, PR_FALSE, getter_AddRefs(radioStyle));
+ nsIRadioControlFrame* radio = nsnull;
+ if (NS_SUCCEEDED(aNewFrame->QueryInterface(kIRadioControlFrameIID, (void**)&radio))) {
+ radio->SetRadioButtonFaceStyleContext(radioStyle);
+ NS_RELEASE(radio);
+ }
+ return rv;
+}
+
nsresult
nsCSSFrameConstructor::ConstructTextControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame)
@@ -2711,7 +2730,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext,
else if (aTag == nsXULAtoms::fontpicker)
rv = NS_NewFontPickerFrame(&newFrame);
else if (aTag == nsXULAtoms::radio)
- rv = NS_NewRadioControlFrame(&newFrame);
+ rv = ConstructRadioControlFrame(aPresContext, newFrame, aContent);
else if (aTag == nsXULAtoms::text)
rv = ConstructTextControlFrame(aPresContext, newFrame);
else if (aTag == nsXULAtoms::widget)
diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h
index 3a42487d4ea5..5518b71d2b13 100644
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -380,6 +380,9 @@ protected:
nsIFrame* aParentFrame,
nsIFrame*& aFrame);
+ nsresult ConstructRadioControlFrame(nsIPresContext* aPresContext,
+ nsIFrame*& aNewFrame,
+ nsIContent* aContent);
nsresult ConstructTextControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame);
diff --git a/layout/forms/nsIRadioControlFrame.h b/layout/forms/nsIRadioControlFrame.h
new file mode 100644
index 000000000000..2e116cde5197
--- /dev/null
+++ b/layout/forms/nsIRadioControlFrame.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+#ifndef nsIRadioControlFrame_h___
+#define nsIRadioControlFrame_h___
+
+#include "nsISupports.h"
+class nsIStyleContext;
+
+// IID for the nsIRadioControlFrame class
+// {06450E00-24D9-11d3-966B-00105A1B1B76}
+#define NS_IRADIOCONTROLFRAME_IID \
+{ 0x6450e00, 0x24d9, 0x11d3, \
+ { 0x96, 0x6b, 0x0, 0x10, 0x5a, 0x1b, 0x1b, 0x76 } }
+
+
+/**
+ * nsIRadioControlFrame is the common interface radio buttons.
+ * @see nsFromControlFrame and its base classes for more info
+ */
+class nsIRadioControlFrame : public nsISupports {
+
+public:
+
+ /**
+ * Sets the Pseudo Style Contexts for the Radio button
+ *
+ */
+ NS_IMETHOD SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioButtonFaceStyleContext) = 0;
+};
+
+#endif
+
diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp
index 7ce48e1c7c1d..8fda0934ebca 100644
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -126,7 +126,7 @@ nsListControlFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
// on in the HandleEvent. The GetFrameForPointUsing is always called before the HandleEvent.
//
nsresult rv;
-
+ mHitFrame = nsnull;
nsIFrame *childFrame;
FirstChild(nsnull, &childFrame);
rv = GetFrameForPointUsing(aPoint, nsnull, aFrame);
@@ -424,7 +424,7 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
aStatus = NS_FRAME_COMPLETE;
mDisplayed = PR_TRUE;
-
+
return NS_OK;
}
@@ -766,12 +766,15 @@ nsListControlFrame :: CaptureMouseEvents(PRBool aGrabMouseEvents)
if (view) {
view->GetViewManager(*getter_AddRefs(viewMan));
-
+// nsIWidget* widget = nsnull;
+// view->GetWidget(widget);
if (viewMan) {
if (aGrabMouseEvents) {
viewMan->GrabMouseEvents(view,result);
+// widget->CaptureMouse(PR_TRUE);
} else {
viewMan->GrabMouseEvents(nsnull,result);
+// widget->CaptureMouse(PR_FALSE);
}
}
}
@@ -779,6 +782,37 @@ nsListControlFrame :: CaptureMouseEvents(PRBool aGrabMouseEvents)
return NS_OK;
}
+nsIView* nsListControlFrame::GetViewFor(nsIWidget* aWidget)
+{
+ nsIView* view = nsnull;
+ void* clientData;
+
+ NS_PRECONDITION(nsnull != aWidget, "null widget ptr");
+
+ // The widget's client data points back to the owning view
+ if (aWidget && NS_SUCCEEDED(aWidget->GetClientData(clientData))) {
+ view = (nsIView*)clientData;
+ }
+
+ return view;
+}
+
+// Determine if a view is an ancestor of another view.
+
+PRBool nsListControlFrame::IsAncestor(nsIView* aAncestor, nsIView* aChild)
+{
+ nsIView* view = aChild;
+ while (nsnull != view) {
+ if (view == aAncestor)
+ // Is an ancestor
+ return(PR_TRUE);
+ else {
+ view->GetParent(view);
+ }
+ }
+ // Not an ancestor
+ return(PR_FALSE);
+}
//----------------------------------------------------------------------
NS_IMETHODIMP nsListControlFrame::HandleLikeDropDownListEvent(nsIPresContext& aPresContext,
@@ -786,15 +820,26 @@ NS_IMETHODIMP nsListControlFrame::HandleLikeDropDownListEvent(nsIPresContext& aP
nsEventStatus& aEventStatus)
{
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) {
- // Don't do anything unless a frame was target of the event.
- if (nsnull == mHitFrame) {
- if (IsInDropDownMode() == PR_TRUE) {
- mComboboxFrame->ListWasSelected(&aPresContext);
- }
- return NS_OK;
- }
- }
-
+ if (nsnull == mHitFrame) {
+ // Button down without hitting a frame in the drop down list.
+
+ // May need to give the scrollbars a chance at the event.
+ // The drop down list's scrollbar view will be a descendant
+ // of the drop down list's view. So check to see if the view
+ // that associated with event's widget is a descendant.
+ // If so, then we do not pop the drop down list back up.
+ nsIView* eventView = GetViewFor(aEvent->widget);
+ nsIView* view=nsnull;
+ GetView(&view);
+ if (PR_TRUE == IsAncestor(view, eventView)) {
+ return NS_OK;
+ }
+ // Roll the drop-down list back up.
+ mComboboxFrame->ListWasSelected(&aPresContext);
+ return NS_OK;
+ }
+ }
+
// Mouse Move behavior is as follows:
// When the DropDown occurs, if an item is selected it displayed as being selected.
// It may or may not be currently visible, when the mouse is moved across any item
@@ -817,29 +862,24 @@ NS_IMETHODIMP nsListControlFrame::HandleLikeDropDownListEvent(nsIPresContext& aP
mSelectedIndex = newSelectedIndex;
}
}
- }
-
-
+ }
} else if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) {
+ // Start by finding the newly "hit" content from the hit frame
+ if (nsnull != mHitFrame) {
+ PRInt32 index = GetSelectedIndex(mHitFrame);
+ if (kNothingSelected != index) {
+ SetFrameSelected(index, PR_TRUE);
+ mSelectedIndex = index;
+ }
+
if (mComboboxFrame) {
mComboboxFrame->ListWasSelected(&aPresContext);
}
-
- } else if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) {
- // Start by finding the newly "hit" content from the hit frame
- if (nsnull != mHitFrame) {
- PRInt32 index = GetSelectedIndex(mHitFrame);
- if (kNothingSelected != index) {
- SetFrameSelected(index, PR_TRUE);
- mSelectedIndex = index;
- }
- }
-
- if (mComboboxFrame) {
- mComboboxFrame->ListWasSelected(&aPresContext);
}
}
+
+ aEventStatus = nsEventStatus_eConsumeNoDefault;
return NS_OK;
}
@@ -887,8 +927,6 @@ NS_IMETHODIMP nsListControlFrame::HandleEvent(nsIPresContext& aPresContext,
HandleLikeListEvent(aPresContext, aEvent, aEventStatus);
}
- aEventStatus = nsEventStatus_eConsumeNoDefault;
-
return NS_OK;
}
@@ -993,10 +1031,7 @@ NS_IMETHODIMP
nsListControlFrame::AboutToDropDown()
{
// Resync the view's position with the frame.
- nsRect rect;
- GetRect(rect);
- MoveTo(rect.x, rect.y);
- return NS_OK;
+ return(SyncViewWithFrame());
}
@@ -1470,7 +1505,105 @@ nsresult nsListControlFrame::CreateScrollingViewWidget(nsIView* aView, const nsS
return nsScrollFrame::CreateScrollingViewWidget(aView, aPosition);
}
}
+
+void
+nsListControlFrame::GetViewOffset(nsIViewManager* aManager, nsIView* aView,
+ nsPoint& aPoint)
+{
+ aPoint.x = 0;
+ aPoint.y = 0;
+
+ nsIView *parent;
+ nsRect bounds;
+
+ parent = aView;
+ while (nsnull != parent) {
+ parent->GetBounds(bounds);
+ aPoint.x += bounds.x;
+ aPoint.y += bounds.y;
+ parent->GetParent(parent);
+ }
+}
+//----------------------------------------------------------------------
+nsresult
+nsListControlFrame::SyncViewWithFrame()
+{
+ // Resync the view's position with the frame.
+ // The problem is the dropdown's view is attached directly under
+ // the root view. This means it's view needs to have it's coordinates calculated
+ // as if it were in it's normal position in the view hierarchy.
+
+ nsPoint parentPos;
+ nsCOMPtr viewManager;
+
+ //Get parent frame
+ nsIFrame* parent;
+ GetParentWithView(&parent);
+ NS_ASSERTION(parent, "GetParentWithView failed");
+
+ // Get parent view
+ nsIView* parentView = nsnull;
+ parent->GetView(&parentView);
+
+ parentView->GetViewManager(*getter_AddRefs(viewManager));
+ GetViewOffset(viewManager, parentView, parentPos);
+ nsIView* view = nsnull;
+ GetView(&view);
+
+ nsIView* containingView = nsnull;
+ nsPoint offset;
+ GetOffsetFromView(offset, &containingView);
+ nsSize size;
+ GetSize(size);
+
+ viewManager->ResizeView(view, mRect.width, mRect.height);
+ viewManager->MoveViewTo(view, parentPos.x + offset.x, parentPos.y + offset.y );
+
+ return NS_OK;
+}
+
+nsresult
+nsListControlFrame::GetScrollingParentView(nsIFrame* aParent, nsIView** aParentView)
+{
+ if (IsInDropDownMode() == PR_TRUE) {
+ // Use the parent frame to get the view manager
+ nsIView* parentView = nsnull;
+ nsresult rv = aParent->GetView(&parentView);
+ NS_ASSERTION(parentView, "GetView failed");
+ nsCOMPtr viewManager;
+ parentView->GetViewManager(*getter_AddRefs(viewManager));
+ NS_ASSERTION(viewManager, "GetViewManager failed");
+
+ // Ask the view manager for the root view and
+ // use it as the parent for popup scrolling lists.
+ // Using the normal view as the parent causes the
+ // drop-down list to be clipped to a parent view.
+ // Using the root view as the parent
+ // prevents this from happening.
+ viewManager->GetRootView(*aParentView);
+ NS_ASSERTION(aParentView, "GetRootView failed");
+ return rv;
+ } else {
+ return nsScrollFrame::GetScrollingParentView(aParent, aParentView);
+ }
+}
+
+NS_IMETHODIMP
+nsListControlFrame::DidReflow(nsIPresContext& aPresContext,
+ nsDidReflowStatus aStatus)
+{
+ if (PR_TRUE == IsInDropDownMode())
+ {
+ nsresult rv = nsScrollFrame::DidReflow(aPresContext, aStatus);
+ SyncViewWithFrame();
+ return rv;
+ } else {
+ return nsScrollFrame::DidReflow(aPresContext, aStatus);
+ }
+}
+
+
diff --git a/layout/forms/nsListControlFrame.h b/layout/forms/nsListControlFrame.h
index cd5a4f297d67..2dca5a9702e9 100644
--- a/layout/forms/nsListControlFrame.h
+++ b/layout/forms/nsListControlFrame.h
@@ -27,6 +27,7 @@ class nsIDOMHTMLSelectElement;
class nsIDOMHTMLCollection;
class nsIDOMHTMLOptionElement;
class nsIComboboxControlFrame;
+class nsIViewManager;
/**
* Frame-based listbox.
@@ -65,6 +66,8 @@ public:
nsIFrame* aPrevInFlow);
NS_IMETHOD Deselect();
+
+ NS_IMETHOD DidReflow(nsIPresContext& aPresContext, nsDidReflowStatus aStatus);
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
@@ -122,17 +125,19 @@ public:
nsIContent* GetOptionContent(PRUint32 aIndex);
PRBool IsContentSelected(nsIContent* aContent);
PRBool IsFrameSelected(PRUint32 aIndex);
- void SetFrameSelected(PRUint32 aIndex, PRBool aSelected);
-
-protected:
- // nsScrollFrame overrides
- // Override the widget created for the list box so a Borderless top level widget is created
- // for drop-down lists.
- virtual nsresult CreateScrollingViewWidget(nsIView* aView,const nsStylePosition* aPosition);
+ void SetFrameSelected(PRUint32 aIndex, PRBool aSelected);
+ void GetViewOffset(nsIViewManager* aManager, nsIView* aView, nsPoint& aPoint);
+protected:
+
nsListControlFrame();
virtual ~nsListControlFrame();
+ // nsScrollFrame overrides
+ // Override the widget created for the list box so a Borderless top level widget is created
+ // for drop-down lists.
+ virtual nsresult CreateScrollingViewWidget(nsIView* aView,const nsStylePosition* aPosition);
+ virtual nsresult GetScrollingParentView(nsIFrame* aParent, nsIView** aParentView);
PRInt32 GetNumberOfOptions();
nsIFrame * GetOptionFromChild(nsIFrame* aParentFrame);
@@ -142,6 +147,9 @@ protected:
nsIFrame** aFrame);
// Utility methods
+ PRBool IsAncestor(nsIView* aAncestor, nsIView* aChild);
+ nsIView* GetViewFor(nsIWidget* aWidget);
+ nsresult SyncViewWithFrame();
PRBool IsInDropDownMode();
PRBool IsOptionElement(nsIContent* aContent);
PRBool IsOptionElementFrame(nsIFrame *aFrame);
diff --git a/layout/html/base/src/nsHTMLAtoms.cpp b/layout/html/base/src/nsHTMLAtoms.cpp
index 026b7f7351dc..a49ce9e24611 100644
--- a/layout/html/base/src/nsHTMLAtoms.cpp
+++ b/layout/html/base/src/nsHTMLAtoms.cpp
@@ -211,6 +211,7 @@ nsIAtom* nsHTMLAtoms::pre;
nsIAtom* nsHTMLAtoms::processingInstructionPseudo;
nsIAtom* nsHTMLAtoms::profile;
nsIAtom* nsHTMLAtoms::prompt;
+nsIAtom* nsHTMLAtoms::radioPseudo;
nsIAtom* nsHTMLAtoms::readonly;
nsIAtom* nsHTMLAtoms::rel;
nsIAtom* nsHTMLAtoms::repeat;
@@ -481,6 +482,7 @@ void nsHTMLAtoms::AddrefAtoms()
processingInstructionPseudo = NS_NewAtom(":-moz-pi");
profile = NS_NewAtom("profile");
prompt = NS_NewAtom("prompt");
+ radioPseudo = NS_NewAtom(":-moz-radio");
readonly = NS_NewAtom("readonly");
rel = NS_NewAtom("rel");
repeat = NS_NewAtom("repeat");
@@ -740,6 +742,7 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(processingInstructionPseudo);
NS_RELEASE(profile);
NS_RELEASE(prompt);
+ NS_RELEASE(radioPseudo);
NS_RELEASE(readonly);
NS_RELEASE(rel);
NS_RELEASE(repeat);
diff --git a/layout/html/base/src/nsHTMLAtoms.h b/layout/html/base/src/nsHTMLAtoms.h
index eb556d3dbd18..9dff9cbb1e61 100644
--- a/layout/html/base/src/nsHTMLAtoms.h
+++ b/layout/html/base/src/nsHTMLAtoms.h
@@ -243,7 +243,8 @@ public:
static nsIAtom* processingInstructionPseudo;
static nsIAtom* profile;
static nsIAtom* prompt;
-
+
+ static nsIAtom* radioPseudo;
static nsIAtom* readonly;
static nsIAtom* rel;
static nsIAtom* repeat;
diff --git a/layout/html/base/src/nsScrollFrame.cpp b/layout/html/base/src/nsScrollFrame.cpp
index f6b313b06334..8a92604aaeba 100644
--- a/layout/html/base/src/nsScrollFrame.cpp
+++ b/layout/html/base/src/nsScrollFrame.cpp
@@ -162,19 +162,28 @@ nsScrollFrame::CreateScrollingViewWidget(nsIView* aView, const nsStylePosition*
return(rv);
}
+nsresult
+nsScrollFrame::GetScrollingParentView(nsIFrame* aParent, nsIView** aParentView)
+{
+ nsresult rv = aParent->GetView(aParentView);
+ NS_ASSERTION(aParentView, "GetParentWithView failed");
+ return(rv);
+}
+
nsresult
nsScrollFrame::CreateScrollingView(nsIPresContext& aPresContext)
{
nsIView* view;
- // Get parent view
+ //Get parent frame
nsIFrame* parent;
GetParentWithView(&parent);
NS_ASSERTION(parent, "GetParentWithView failed");
- nsIView* parentView;
- parent->GetView(&parentView);
- NS_ASSERTION(parentView, "GetParentWithView failed");
+ // Get parent view
+ nsIView* parentView = nsnull;
+ GetScrollingParentView(parent, &parentView);
+
// Get the view manager
nsIViewManager* viewManager;
parentView->GetViewManager(viewManager);
diff --git a/layout/html/base/src/nsScrollFrame.h b/layout/html/base/src/nsScrollFrame.h
index 078aaae0bc68..ea95784081ed 100644
--- a/layout/html/base/src/nsScrollFrame.h
+++ b/layout/html/base/src/nsScrollFrame.h
@@ -69,7 +69,8 @@ protected:
// Creation of the widget for the scrolling view is factored into a virtual method so
// that sub-classes may control widget creation.
virtual nsresult CreateScrollingViewWidget(nsIView* aView,const nsStylePosition* aPosition);
-
+ // Getting the view for scollframe may be overriden to provide a parent view for te scroll frame
+ virtual nsresult GetScrollingParentView(nsIFrame* aParent, nsIView** aParentView);
private:
nsresult CreateScrollingView(nsIPresContext& aPresContext);
};
diff --git a/layout/html/document/src/ua.css b/layout/html/document/src/ua.css
index 7389c9515e5b..4a35e8105c4d 100644
--- a/layout/html/document/src/ua.css
+++ b/layout/html/document/src/ua.css
@@ -430,24 +430,54 @@ input[type=radio] {
margin-right: 5px;
margin-top: 3px;
margin-bottom: 3px;
- border: 2px inset rgb(192, 192, 192);
- background-color:white;
+ border: 2px outset rgb(192, 192, 192);
+ background-color:rgb(192, 192, 192);
color:black;
width:12px;
height:12px;
+ -moz-border-radius:6px;
}
+input[type=radio]:active {
+ background-color:white;
+ border: 2px inset rgb(192, 192, 192);
+}
+
+input[type=radio]:hover {
+ border : 2px solid black;
+}
+
+:-moz-radio {
+ background-color:black;
+ width:6px;
+ height:6px;
+ left:6px;
+ top:6px;
+ -moz-border-radius:3px;
+}
+
+
input[type=checkbox] {
/* these margins are for NavQuirks, we need a Standard ua.css */
margin-left: 3px;
margin-right: 5px;
margin-top: 3px;
margin-bottom: 4px;
- border: 2px inset rgb(192, 192, 192);
+ border: 2px outset rgb(192, 192, 192);
width:11px;
height:11px;
- background-color:white;
+ background-color:rgb(192, 192, 192);
color:black;
+ -moz-border-radius:1px;
+}
+
+input[type=checkbox]:active {
+ background-color:gray;
+ border: 2px inset rgb(192, 192, 192);
+}
+
+input[type=checkbox]:hover {
+ border : 1px solid black;
}
input[type="submit"] {
@@ -706,9 +736,29 @@ select {
background-color: white;
color:black;
white-space:nowrap;
+ text-align: left;
}
+
+select:active {
+ border : 1px solid black;
+}
+
option {
display:block;
+ padding-left:3px;
+ padding-right:3px;
+}
+
+/* Combobox item style */
+select option[-moz-option-selected], select[size="1"] option[-moz-option-selected] {
+ color:black;
+ background-color:white;
+}
+
+/* List box item selected style */
+select[size] option[-moz-option-selected] {
+ color:white;
+ background-color:black;
}
option.selected {
@@ -717,10 +767,6 @@ option.selected {
color: rgb(255,255,255);
}
-option[-moz-option-selected] {
- color:white;
- background-color: rgb(0,0,128);
-}
option.selectedfocus {
border: 1px dotted white;
@@ -940,14 +986,15 @@ sourcetext { /* XXX should not be in HTML namespace */
}
:-moz-dropdown-btn-pressed {
- border: 2px inset #c0c0c0;
- background-color: rgb(206, 207, 206);
+/* border: 2px inset #c0c0c0; */
+ background-color: rgb(192, 192, 192);
+ border: none;
}
:-moz-dropdown-list {
position:absolute;
- background-color:white;
- border: 1px solid blue;
+ background-color:rgb(192, 192, 192);
+ border: 1px solid black;
}
diff --git a/layout/html/forms/public/MANIFEST b/layout/html/forms/public/MANIFEST
index cbc538d84c4a..7e1cb1f05df5 100644
--- a/layout/html/forms/public/MANIFEST
+++ b/layout/html/forms/public/MANIFEST
@@ -5,3 +5,4 @@
nsIComboboxControlFrame.h
nsIListControlFrame.h
nsIFormControlFrame.h
+nsIRadioControlFrame.h
diff --git a/layout/html/forms/public/Makefile.in b/layout/html/forms/public/Makefile.in
index dbc2453e73ea..a6d48b492392 100644
--- a/layout/html/forms/public/Makefile.in
+++ b/layout/html/forms/public/Makefile.in
@@ -27,6 +27,7 @@ EXPORTS = \
nsIListControlFrame.h \
nsIComboboxControlFrame.h \
nsIFormControlFrame.h \
+ nsIRadioControlFrame.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
diff --git a/layout/html/forms/public/makefile.win b/layout/html/forms/public/makefile.win
index 793c7f1d9282..d6406a9ca198 100644
--- a/layout/html/forms/public/makefile.win
+++ b/layout/html/forms/public/makefile.win
@@ -20,6 +20,7 @@ DEPTH=..\..\..\..
EXPORTS=nsIFormManager.h \
nsIListControlFrame.h \
nsIComboboxControlFrame.h \
+ nsIRadioControlFrame.h \
nsIFormControlFrame.h
MODULE=raptor
diff --git a/layout/html/forms/public/nsIRadioControlFrame.h b/layout/html/forms/public/nsIRadioControlFrame.h
new file mode 100644
index 000000000000..2e116cde5197
--- /dev/null
+++ b/layout/html/forms/public/nsIRadioControlFrame.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+#ifndef nsIRadioControlFrame_h___
+#define nsIRadioControlFrame_h___
+
+#include "nsISupports.h"
+class nsIStyleContext;
+
+// IID for the nsIRadioControlFrame class
+// {06450E00-24D9-11d3-966B-00105A1B1B76}
+#define NS_IRADIOCONTROLFRAME_IID \
+{ 0x6450e00, 0x24d9, 0x11d3, \
+ { 0x96, 0x6b, 0x0, 0x10, 0x5a, 0x1b, 0x1b, 0x76 } }
+
+
+/**
+ * nsIRadioControlFrame is the common interface radio buttons.
+ * @see nsFromControlFrame and its base classes for more info
+ */
+class nsIRadioControlFrame : public nsISupports {
+
+public:
+
+ /**
+ * Sets the Pseudo Style Contexts for the Radio button
+ *
+ */
+ NS_IMETHOD SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioButtonFaceStyleContext) = 0;
+};
+
+#endif
+
diff --git a/layout/html/forms/src/nsListControlFrame.cpp b/layout/html/forms/src/nsListControlFrame.cpp
index 7ce48e1c7c1d..8fda0934ebca 100644
--- a/layout/html/forms/src/nsListControlFrame.cpp
+++ b/layout/html/forms/src/nsListControlFrame.cpp
@@ -126,7 +126,7 @@ nsListControlFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
// on in the HandleEvent. The GetFrameForPointUsing is always called before the HandleEvent.
//
nsresult rv;
-
+ mHitFrame = nsnull;
nsIFrame *childFrame;
FirstChild(nsnull, &childFrame);
rv = GetFrameForPointUsing(aPoint, nsnull, aFrame);
@@ -424,7 +424,7 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
aStatus = NS_FRAME_COMPLETE;
mDisplayed = PR_TRUE;
-
+
return NS_OK;
}
@@ -766,12 +766,15 @@ nsListControlFrame :: CaptureMouseEvents(PRBool aGrabMouseEvents)
if (view) {
view->GetViewManager(*getter_AddRefs(viewMan));
-
+// nsIWidget* widget = nsnull;
+// view->GetWidget(widget);
if (viewMan) {
if (aGrabMouseEvents) {
viewMan->GrabMouseEvents(view,result);
+// widget->CaptureMouse(PR_TRUE);
} else {
viewMan->GrabMouseEvents(nsnull,result);
+// widget->CaptureMouse(PR_FALSE);
}
}
}
@@ -779,6 +782,37 @@ nsListControlFrame :: CaptureMouseEvents(PRBool aGrabMouseEvents)
return NS_OK;
}
+nsIView* nsListControlFrame::GetViewFor(nsIWidget* aWidget)
+{
+ nsIView* view = nsnull;
+ void* clientData;
+
+ NS_PRECONDITION(nsnull != aWidget, "null widget ptr");
+
+ // The widget's client data points back to the owning view
+ if (aWidget && NS_SUCCEEDED(aWidget->GetClientData(clientData))) {
+ view = (nsIView*)clientData;
+ }
+
+ return view;
+}
+
+// Determine if a view is an ancestor of another view.
+
+PRBool nsListControlFrame::IsAncestor(nsIView* aAncestor, nsIView* aChild)
+{
+ nsIView* view = aChild;
+ while (nsnull != view) {
+ if (view == aAncestor)
+ // Is an ancestor
+ return(PR_TRUE);
+ else {
+ view->GetParent(view);
+ }
+ }
+ // Not an ancestor
+ return(PR_FALSE);
+}
//----------------------------------------------------------------------
NS_IMETHODIMP nsListControlFrame::HandleLikeDropDownListEvent(nsIPresContext& aPresContext,
@@ -786,15 +820,26 @@ NS_IMETHODIMP nsListControlFrame::HandleLikeDropDownListEvent(nsIPresContext& aP
nsEventStatus& aEventStatus)
{
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) {
- // Don't do anything unless a frame was target of the event.
- if (nsnull == mHitFrame) {
- if (IsInDropDownMode() == PR_TRUE) {
- mComboboxFrame->ListWasSelected(&aPresContext);
- }
- return NS_OK;
- }
- }
-
+ if (nsnull == mHitFrame) {
+ // Button down without hitting a frame in the drop down list.
+
+ // May need to give the scrollbars a chance at the event.
+ // The drop down list's scrollbar view will be a descendant
+ // of the drop down list's view. So check to see if the view
+ // that associated with event's widget is a descendant.
+ // If so, then we do not pop the drop down list back up.
+ nsIView* eventView = GetViewFor(aEvent->widget);
+ nsIView* view=nsnull;
+ GetView(&view);
+ if (PR_TRUE == IsAncestor(view, eventView)) {
+ return NS_OK;
+ }
+ // Roll the drop-down list back up.
+ mComboboxFrame->ListWasSelected(&aPresContext);
+ return NS_OK;
+ }
+ }
+
// Mouse Move behavior is as follows:
// When the DropDown occurs, if an item is selected it displayed as being selected.
// It may or may not be currently visible, when the mouse is moved across any item
@@ -817,29 +862,24 @@ NS_IMETHODIMP nsListControlFrame::HandleLikeDropDownListEvent(nsIPresContext& aP
mSelectedIndex = newSelectedIndex;
}
}
- }
-
-
+ }
} else if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) {
+ // Start by finding the newly "hit" content from the hit frame
+ if (nsnull != mHitFrame) {
+ PRInt32 index = GetSelectedIndex(mHitFrame);
+ if (kNothingSelected != index) {
+ SetFrameSelected(index, PR_TRUE);
+ mSelectedIndex = index;
+ }
+
if (mComboboxFrame) {
mComboboxFrame->ListWasSelected(&aPresContext);
}
-
- } else if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) {
- // Start by finding the newly "hit" content from the hit frame
- if (nsnull != mHitFrame) {
- PRInt32 index = GetSelectedIndex(mHitFrame);
- if (kNothingSelected != index) {
- SetFrameSelected(index, PR_TRUE);
- mSelectedIndex = index;
- }
- }
-
- if (mComboboxFrame) {
- mComboboxFrame->ListWasSelected(&aPresContext);
}
}
+
+ aEventStatus = nsEventStatus_eConsumeNoDefault;
return NS_OK;
}
@@ -887,8 +927,6 @@ NS_IMETHODIMP nsListControlFrame::HandleEvent(nsIPresContext& aPresContext,
HandleLikeListEvent(aPresContext, aEvent, aEventStatus);
}
- aEventStatus = nsEventStatus_eConsumeNoDefault;
-
return NS_OK;
}
@@ -993,10 +1031,7 @@ NS_IMETHODIMP
nsListControlFrame::AboutToDropDown()
{
// Resync the view's position with the frame.
- nsRect rect;
- GetRect(rect);
- MoveTo(rect.x, rect.y);
- return NS_OK;
+ return(SyncViewWithFrame());
}
@@ -1470,7 +1505,105 @@ nsresult nsListControlFrame::CreateScrollingViewWidget(nsIView* aView, const nsS
return nsScrollFrame::CreateScrollingViewWidget(aView, aPosition);
}
}
+
+void
+nsListControlFrame::GetViewOffset(nsIViewManager* aManager, nsIView* aView,
+ nsPoint& aPoint)
+{
+ aPoint.x = 0;
+ aPoint.y = 0;
+
+ nsIView *parent;
+ nsRect bounds;
+
+ parent = aView;
+ while (nsnull != parent) {
+ parent->GetBounds(bounds);
+ aPoint.x += bounds.x;
+ aPoint.y += bounds.y;
+ parent->GetParent(parent);
+ }
+}
+//----------------------------------------------------------------------
+nsresult
+nsListControlFrame::SyncViewWithFrame()
+{
+ // Resync the view's position with the frame.
+ // The problem is the dropdown's view is attached directly under
+ // the root view. This means it's view needs to have it's coordinates calculated
+ // as if it were in it's normal position in the view hierarchy.
+
+ nsPoint parentPos;
+ nsCOMPtr viewManager;
+
+ //Get parent frame
+ nsIFrame* parent;
+ GetParentWithView(&parent);
+ NS_ASSERTION(parent, "GetParentWithView failed");
+
+ // Get parent view
+ nsIView* parentView = nsnull;
+ parent->GetView(&parentView);
+
+ parentView->GetViewManager(*getter_AddRefs(viewManager));
+ GetViewOffset(viewManager, parentView, parentPos);
+ nsIView* view = nsnull;
+ GetView(&view);
+
+ nsIView* containingView = nsnull;
+ nsPoint offset;
+ GetOffsetFromView(offset, &containingView);
+ nsSize size;
+ GetSize(size);
+
+ viewManager->ResizeView(view, mRect.width, mRect.height);
+ viewManager->MoveViewTo(view, parentPos.x + offset.x, parentPos.y + offset.y );
+
+ return NS_OK;
+}
+
+nsresult
+nsListControlFrame::GetScrollingParentView(nsIFrame* aParent, nsIView** aParentView)
+{
+ if (IsInDropDownMode() == PR_TRUE) {
+ // Use the parent frame to get the view manager
+ nsIView* parentView = nsnull;
+ nsresult rv = aParent->GetView(&parentView);
+ NS_ASSERTION(parentView, "GetView failed");
+ nsCOMPtr viewManager;
+ parentView->GetViewManager(*getter_AddRefs(viewManager));
+ NS_ASSERTION(viewManager, "GetViewManager failed");
+
+ // Ask the view manager for the root view and
+ // use it as the parent for popup scrolling lists.
+ // Using the normal view as the parent causes the
+ // drop-down list to be clipped to a parent view.
+ // Using the root view as the parent
+ // prevents this from happening.
+ viewManager->GetRootView(*aParentView);
+ NS_ASSERTION(aParentView, "GetRootView failed");
+ return rv;
+ } else {
+ return nsScrollFrame::GetScrollingParentView(aParent, aParentView);
+ }
+}
+
+NS_IMETHODIMP
+nsListControlFrame::DidReflow(nsIPresContext& aPresContext,
+ nsDidReflowStatus aStatus)
+{
+ if (PR_TRUE == IsInDropDownMode())
+ {
+ nsresult rv = nsScrollFrame::DidReflow(aPresContext, aStatus);
+ SyncViewWithFrame();
+ return rv;
+ } else {
+ return nsScrollFrame::DidReflow(aPresContext, aStatus);
+ }
+}
+
+
diff --git a/layout/html/forms/src/nsListControlFrame.h b/layout/html/forms/src/nsListControlFrame.h
index cd5a4f297d67..2dca5a9702e9 100644
--- a/layout/html/forms/src/nsListControlFrame.h
+++ b/layout/html/forms/src/nsListControlFrame.h
@@ -27,6 +27,7 @@ class nsIDOMHTMLSelectElement;
class nsIDOMHTMLCollection;
class nsIDOMHTMLOptionElement;
class nsIComboboxControlFrame;
+class nsIViewManager;
/**
* Frame-based listbox.
@@ -65,6 +66,8 @@ public:
nsIFrame* aPrevInFlow);
NS_IMETHOD Deselect();
+
+ NS_IMETHOD DidReflow(nsIPresContext& aPresContext, nsDidReflowStatus aStatus);
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
@@ -122,17 +125,19 @@ public:
nsIContent* GetOptionContent(PRUint32 aIndex);
PRBool IsContentSelected(nsIContent* aContent);
PRBool IsFrameSelected(PRUint32 aIndex);
- void SetFrameSelected(PRUint32 aIndex, PRBool aSelected);
-
-protected:
- // nsScrollFrame overrides
- // Override the widget created for the list box so a Borderless top level widget is created
- // for drop-down lists.
- virtual nsresult CreateScrollingViewWidget(nsIView* aView,const nsStylePosition* aPosition);
+ void SetFrameSelected(PRUint32 aIndex, PRBool aSelected);
+ void GetViewOffset(nsIViewManager* aManager, nsIView* aView, nsPoint& aPoint);
+protected:
+
nsListControlFrame();
virtual ~nsListControlFrame();
+ // nsScrollFrame overrides
+ // Override the widget created for the list box so a Borderless top level widget is created
+ // for drop-down lists.
+ virtual nsresult CreateScrollingViewWidget(nsIView* aView,const nsStylePosition* aPosition);
+ virtual nsresult GetScrollingParentView(nsIFrame* aParent, nsIView** aParentView);
PRInt32 GetNumberOfOptions();
nsIFrame * GetOptionFromChild(nsIFrame* aParentFrame);
@@ -142,6 +147,9 @@ protected:
nsIFrame** aFrame);
// Utility methods
+ PRBool IsAncestor(nsIView* aAncestor, nsIView* aChild);
+ nsIView* GetViewFor(nsIWidget* aWidget);
+ nsresult SyncViewWithFrame();
PRBool IsInDropDownMode();
PRBool IsOptionElement(nsIContent* aContent);
PRBool IsOptionElementFrame(nsIFrame *aFrame);
diff --git a/layout/html/forms/src/nsRadioControlFrame.cpp b/layout/html/forms/src/nsRadioControlFrame.cpp
index 0e4d65dc634e..b616f5740df2 100644
--- a/layout/html/forms/src/nsRadioControlFrame.cpp
+++ b/layout/html/forms/src/nsRadioControlFrame.cpp
@@ -40,6 +40,8 @@
#include "nsINameSpaceManager.h"
#include "nsILookAndFeel.h"
#include "nsIComponentManager.h"
+#include "nsCOMPtr.h"
+#include "nsCSSRendering.h"
static NS_DEFINE_IID(kIRadioIID, NS_IRADIOBUTTON_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
@@ -49,6 +51,7 @@ static NS_DEFINE_IID(kILookAndFeelIID, NS_ILOOKANDFEEL_IID);
#define NS_DEFAULT_RADIOBOX_SIZE 12
+static NS_DEFINE_IID(kIRadioControlFrameIID, NS_IRADIOCONTROLFRAME_IID);
nsresult
NS_NewRadioControlFrame(nsIFrame** aNewFrame)
@@ -69,8 +72,29 @@ nsRadioControlFrame::nsRadioControlFrame()
{
// Initialize GFX-rendered state
mChecked = PR_FALSE;
+ mRadioButtonFaceStyle = nsnull;
}
+nsRadioControlFrame::~nsRadioControlFrame()
+{
+ NS_IF_RELEASE(mRadioButtonFaceStyle);
+}
+
+//--------------------------------------------------------------
+nsresult
+nsRadioControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
+{
+ NS_PRECONDITION(0 != aInstancePtr, "null ptr");
+ if (NULL == aInstancePtr) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ if (aIID.Equals(kIRadioControlFrameIID)) {
+ *aInstancePtr = (void*) ((nsIRadioControlFrame*) this);
+ return NS_OK;
+ }
+
+ return nsFormControlFrame::QueryInterface(aIID, aInstancePtr);
+}
const nsIID&
@@ -86,6 +110,42 @@ nsRadioControlFrame::GetCID()
return kRadioCID;
}
+
+NS_IMETHODIMP
+nsRadioControlFrame::ReResolveStyleContext(nsIPresContext* aPresContext,
+ nsIStyleContext* aParentContext,
+ PRInt32 aParentChange,
+ nsStyleChangeList* aChangeList,
+ PRInt32* aLocalChange)
+{
+ // this re-resolves |mStyleContext|, so it may change
+ nsresult rv = nsFormControlFrame::ReResolveStyleContext(aPresContext, aParentContext, aParentChange,
+ aChangeList, aLocalChange);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ if (NS_COMFALSE != rv) { // frame style changed
+ if (aLocalChange) {
+ aParentChange = *aLocalChange; // tell children about or change
+ }
+ }
+
+ // see if the outline has changed.
+ nsCOMPtr oldRadioButtonFaceStyle = mRadioButtonFaceStyle;
+ aPresContext->ProbePseudoStyleContextFor(mContent, nsHTMLAtoms::radioPseudo, mStyleContext,
+ PR_FALSE,
+ &mRadioButtonFaceStyle);
+
+ if ((mRadioButtonFaceStyle && oldRadioButtonFaceStyle) && (mRadioButtonFaceStyle != oldRadioButtonFaceStyle)) {
+ nsFormControlFrame::CaptureStyleChangeFor(this, oldRadioButtonFaceStyle, mRadioButtonFaceStyle,
+ aParentChange, aChangeList, aLocalChange);
+ }
+
+ return rv;
+}
+
+
nscoord
nsRadioControlFrame::GetRadioboxSize(float aPixToTwip) const
{
@@ -339,50 +399,45 @@ nsRadioControlFrame::GetFrameName(nsString& aResult) const
}
+NS_IMETHODIMP
+nsRadioControlFrame::SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioButtonFaceStyleContext)
+{
+ mRadioButtonFaceStyle = aRadioButtonFaceStyleContext;
+ NS_ADDREF(mRadioButtonFaceStyle);
+ return NS_OK;
+}
+
void
nsRadioControlFrame::PaintRadioButton(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect)
{
- aRenderingContext.PushState();
-
- const nsStyleColor* color = (const nsStyleColor*)
- mStyleContext->GetStyleData(eStyleStruct_Color);
-
- //XXX: This is backwards for now. The PaintCircular border code actually draws pie slices.
-
- nsFormControlHelper::PaintCircularBorder(aPresContext,aRenderingContext,
- aDirtyRect, mStyleContext, PR_FALSE, this, mRect.width, mRect.height);
- nsFormControlHelper::PaintCircularBackground(aPresContext,aRenderingContext,
- aDirtyRect, mStyleContext, PR_FALSE, this, mRect.width, mRect.height);
-
-
+
PRBool checked = PR_TRUE;
GetCurrentCheckState(&checked); // Get check state from the content model
if (PR_TRUE == checked) {
- // Have to do 180 degress at a time because FillArc will not correctly
- // go from 0-360
- float p2t;
- aPresContext.GetScaledPixelsToTwips(&p2t);
+ // Paint the button for the radio button using CSS background rendering code
+ if (nsnull != mRadioButtonFaceStyle) {
+ const nsStyleColor* myColor = (const nsStyleColor*)
+ mRadioButtonFaceStyle->GetStyleData(eStyleStruct_Color);
+ const nsStyleSpacing* mySpacing = (const nsStyleSpacing*)
+ mRadioButtonFaceStyle->GetStyleData(eStyleStruct_Spacing);
+ const nsStylePosition* myPosition = (const nsStylePosition*)
+ mRadioButtonFaceStyle->GetStyleData(eStyleStruct_Position);
- nscoord onePixel = NSIntPixelsToTwips(1, p2t);
-//XXX nscoord twelvePixels = NSIntPixelsToTwips(12, p2t);
+ nscoord width = myPosition->mWidth.GetCoordValue();
+ nscoord height = myPosition->mHeight.GetCoordValue();
+ // Position the button centered within the radio control's rectangle.
+ nscoord x = (mRect.width - width) / 2;
+ nscoord y = (mRect.height - height) / 2;
+ nsRect rect(x, y, width, height);
- nsRect outside;
- nsFormControlHelper::GetCircularRect(mRect.width, mRect.height, outside);
-
- outside.Deflate(onePixel, onePixel);
- outside.Deflate(onePixel, onePixel);
- outside.Deflate(onePixel, onePixel);
- outside.Deflate(onePixel, onePixel);
-
- aRenderingContext.SetColor(color->mColor);
- aRenderingContext.FillArc(outside, 0, 180);
- aRenderingContext.FillArc(outside, 180, 360);
+ nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,
+ aDirtyRect, rect, *myColor, *mySpacing, 0, 0);
+ nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
+ aDirtyRect, rect, *mySpacing, mRadioButtonFaceStyle, 0);
+ }
}
-
- PRBool clip;
- aRenderingContext.PopState(clip);
}
NS_METHOD
@@ -396,6 +451,9 @@ nsRadioControlFrame::Paint(nsIPresContext& aPresContext,
if (!disp->mVisible)
return NS_OK;
+ // Paint the background
+ nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
+
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
PaintRadioButton(aPresContext, aRenderingContext, aDirtyRect);
}
diff --git a/layout/html/forms/src/nsRadioControlFrame.h b/layout/html/forms/src/nsRadioControlFrame.h
index 1ec93fc45b75..8f596536b6e5 100644
--- a/layout/html/forms/src/nsRadioControlFrame.h
+++ b/layout/html/forms/src/nsRadioControlFrame.h
@@ -19,6 +19,7 @@
#ifndef nsRadioControlFrame_h___
#define nsRadioControlFrame_h___
+#include "nsIRadioControlFrame.h"
#include "nsFormControlFrame.h"
#include "nsVoidArray.h"
#include "nsString.h"
@@ -26,10 +27,11 @@ class nsIAtom;
// nsRadioControlFrame
-class nsRadioControlFrame : public nsFormControlFrame
+class nsRadioControlFrame : public nsFormControlFrame, public nsIRadioControlFrame
{
public:
nsRadioControlFrame();
+ ~nsRadioControlFrame();
// nsFormControlFrame overrides
nsresult RequiresWidget(PRBool &aHasWidget);
@@ -49,6 +51,10 @@ public:
NS_IMETHOD GetFrameName(nsString& aResult) const;
+ //nsIRadioControlFrame methods
+ NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
+ NS_IMETHOD SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioButtonFaceStyleContext);
+
virtual PRBool GetChecked(PRBool aGetInitialValue);
virtual void SetChecked(PRBool aValue, PRBool aSetInitialValue);
@@ -63,6 +69,12 @@ public:
virtual const nsIID& GetIID();
+ NS_IMETHOD ReResolveStyleContext(nsIPresContext* aPresContext,
+ nsIStyleContext* aParentContext,
+ PRInt32 aParentChange,
+ nsStyleChangeList* aChangeList,
+ PRInt32* aLocalChange);
+
//
// XXX: The following paint methods are TEMPORARY. It is being used to get printing working
// under windows. Later it may be used to GFX-render the controls to the display.
@@ -97,6 +109,12 @@ protected:
nsSize& aDesiredWidgetSize);
//GFX-rendered state variables
PRBool mChecked;
+
+ nsIStyleContext* mRadioButtonFaceStyle;
+
+private:
+ NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
+ NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
};
// nsRadioControlGroup
@@ -120,8 +138,10 @@ protected:
nsString mName;
nsVoidArray mRadios;
nsRadioControlFrame* mCheckedRadio;
+
};
+
#endif
diff --git a/layout/html/style/src/nsCSSFrameConstructor.cpp b/layout/html/style/src/nsCSSFrameConstructor.cpp
index e78dc10f274b..89a4d5028a8a 100644
--- a/layout/html/style/src/nsCSSFrameConstructor.cpp
+++ b/layout/html/style/src/nsCSSFrameConstructor.cpp
@@ -49,6 +49,7 @@
#include "nsLayoutAtoms.h"
#include "nsIDOMHTMLSelectElement.h"
#include "nsIComboboxControlFrame.h"
+#include "nsIRadioControlFrame.h"
#include "nsIListControlFrame.h"
#include "nsIDOMCharacterData.h"
#include "nsIDOMHTMLImageElement.h"
@@ -122,6 +123,7 @@ static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID);
static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIComboboxControlFrameIID, NS_ICOMBOBOXCONTROLFRAME_IID);
+static NS_DEFINE_IID(kIRadioControlFrameIID, NS_IRADIOCONTROLFRAME_IID);
static NS_DEFINE_IID(kIListControlFrameIID, NS_ILISTCONTROLFRAME_IID);
static NS_DEFINE_IID(kIDOMHTMLImageElementIID, NS_IDOMHTMLIMAGEELEMENT_IID);
static NS_DEFINE_IID(kIDOMCharacterDataIID, NS_IDOMCHARACTERDATA_IID);
@@ -765,7 +767,7 @@ nsCSSFrameConstructor::CreateInputFrame(nsIPresContext *aPresContext,
rv = ConstructTextControlFrame(aPresContext, aFrame);
}
else if (val.EqualsIgnoreCase("radio")) {
- rv = NS_NewRadioControlFrame(&aFrame);
+ rv = ConstructRadioControlFrame(aPresContext, aFrame, aContent);
}
else if (val.EqualsIgnoreCase("text")) {
rv = ConstructTextControlFrame(aPresContext, aFrame);
@@ -2233,6 +2235,23 @@ nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresContext* aPresContext,
return rv;
}
+nsresult
+nsCSSFrameConstructor::ConstructRadioControlFrame(nsIPresContext* aPresContext,
+ nsIFrame*& aNewFrame,
+ nsIContent* aContent)
+{
+ nsresult rv = NS_NewRadioControlFrame(&aNewFrame);
+ nsCOMPtr radioStyle;
+ aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::radioPseudo,
+ radioStyle, PR_FALSE, getter_AddRefs(radioStyle));
+ nsIRadioControlFrame* radio = nsnull;
+ if (NS_SUCCEEDED(aNewFrame->QueryInterface(kIRadioControlFrameIID, (void**)&radio))) {
+ radio->SetRadioButtonFaceStyleContext(radioStyle);
+ NS_RELEASE(radio);
+ }
+ return rv;
+}
+
nsresult
nsCSSFrameConstructor::ConstructTextControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame)
@@ -2711,7 +2730,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext,
else if (aTag == nsXULAtoms::fontpicker)
rv = NS_NewFontPickerFrame(&newFrame);
else if (aTag == nsXULAtoms::radio)
- rv = NS_NewRadioControlFrame(&newFrame);
+ rv = ConstructRadioControlFrame(aPresContext, newFrame, aContent);
else if (aTag == nsXULAtoms::text)
rv = ConstructTextControlFrame(aPresContext, newFrame);
else if (aTag == nsXULAtoms::widget)
diff --git a/layout/html/style/src/nsCSSFrameConstructor.h b/layout/html/style/src/nsCSSFrameConstructor.h
index 3a42487d4ea5..5518b71d2b13 100644
--- a/layout/html/style/src/nsCSSFrameConstructor.h
+++ b/layout/html/style/src/nsCSSFrameConstructor.h
@@ -380,6 +380,9 @@ protected:
nsIFrame* aParentFrame,
nsIFrame*& aFrame);
+ nsresult ConstructRadioControlFrame(nsIPresContext* aPresContext,
+ nsIFrame*& aNewFrame,
+ nsIContent* aContent);
nsresult ConstructTextControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame);
diff --git a/layout/style/ua.css b/layout/style/ua.css
index 7389c9515e5b..4a35e8105c4d 100644
--- a/layout/style/ua.css
+++ b/layout/style/ua.css
@@ -430,24 +430,54 @@ input[type=radio] {
margin-right: 5px;
margin-top: 3px;
margin-bottom: 3px;
- border: 2px inset rgb(192, 192, 192);
- background-color:white;
+ border: 2px outset rgb(192, 192, 192);
+ background-color:rgb(192, 192, 192);
color:black;
width:12px;
height:12px;
+ -moz-border-radius:6px;
}
+input[type=radio]:active {
+ background-color:white;
+ border: 2px inset rgb(192, 192, 192);
+}
+
+input[type=radio]:hover {
+ border : 2px solid black;
+}
+
+:-moz-radio {
+ background-color:black;
+ width:6px;
+ height:6px;
+ left:6px;
+ top:6px;
+ -moz-border-radius:3px;
+}
+
+
input[type=checkbox] {
/* these margins are for NavQuirks, we need a Standard ua.css */
margin-left: 3px;
margin-right: 5px;
margin-top: 3px;
margin-bottom: 4px;
- border: 2px inset rgb(192, 192, 192);
+ border: 2px outset rgb(192, 192, 192);
width:11px;
height:11px;
- background-color:white;
+ background-color:rgb(192, 192, 192);
color:black;
+ -moz-border-radius:1px;
+}
+
+input[type=checkbox]:active {
+ background-color:gray;
+ border: 2px inset rgb(192, 192, 192);
+}
+
+input[type=checkbox]:hover {
+ border : 1px solid black;
}
input[type="submit"] {
@@ -706,9 +736,29 @@ select {
background-color: white;
color:black;
white-space:nowrap;
+ text-align: left;
}
+
+select:active {
+ border : 1px solid black;
+}
+
option {
display:block;
+ padding-left:3px;
+ padding-right:3px;
+}
+
+/* Combobox item style */
+select option[-moz-option-selected], select[size="1"] option[-moz-option-selected] {
+ color:black;
+ background-color:white;
+}
+
+/* List box item selected style */
+select[size] option[-moz-option-selected] {
+ color:white;
+ background-color:black;
}
option.selected {
@@ -717,10 +767,6 @@ option.selected {
color: rgb(255,255,255);
}
-option[-moz-option-selected] {
- color:white;
- background-color: rgb(0,0,128);
-}
option.selectedfocus {
border: 1px dotted white;
@@ -940,14 +986,15 @@ sourcetext { /* XXX should not be in HTML namespace */
}
:-moz-dropdown-btn-pressed {
- border: 2px inset #c0c0c0;
- background-color: rgb(206, 207, 206);
+/* border: 2px inset #c0c0c0; */
+ background-color: rgb(192, 192, 192);
+ border: none;
}
:-moz-dropdown-list {
position:absolute;
- background-color:white;
- border: 1px solid blue;
+ background-color:rgb(192, 192, 192);
+ border: 1px solid black;
}