diff --git a/content/html/style/public/nsCSSAtomList.h b/content/html/style/public/nsCSSAtomList.h
index df983156370..8afa5d0ac31 100644
--- a/content/html/style/public/nsCSSAtomList.h
+++ b/content/html/style/public/nsCSSAtomList.h
@@ -40,6 +40,8 @@ CSS_ATOM(afterPseudo, ":after")
CSS_ATOM(beforePseudo, ":before")
+CSS_ATOM(buttonLabelPseudo, ":-moz-buttonlabel")
+
CSS_ATOM(checkedPseudo, ":checked")
CSS_ATOM(disabledPseudo, ":disabled")
diff --git a/content/shared/public/nsCSSAtomList.h b/content/shared/public/nsCSSAtomList.h
index df983156370..8afa5d0ac31 100644
--- a/content/shared/public/nsCSSAtomList.h
+++ b/content/shared/public/nsCSSAtomList.h
@@ -40,6 +40,8 @@ CSS_ATOM(afterPseudo, ":after")
CSS_ATOM(beforePseudo, ":before")
+CSS_ATOM(buttonLabelPseudo, ":-moz-buttonlabel")
+
CSS_ATOM(checkedPseudo, ":checked")
CSS_ATOM(disabledPseudo, ":disabled")
diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp
index 8029e78d9cf..165aa3c72cd 100644
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -2458,6 +2458,40 @@ nsCSSFrameConstructor::ConstructCheckboxControlFrame(nsIPresContext* aPres
return rv;
}
+nsresult
+nsCSSFrameConstructor::ConstructButtonLabelFrame(nsIPresContext *aPresContext,
+ nsIContent *aContent,
+ nsIFrame *&aFrame,
+ nsFrameConstructorState& aState,
+ nsFrameItems& aFrameItems)
+{
+ // Construct a button label using generated content specified
+ // through style. A style rule of following form must be
+ // present in ua.css or other style sheet
+ // input[type=button][value]:-moz-buttonlabel {
+ // content:attr(value);
+ // }
+ // The default for the label is specified with a rule similar to
+ // the following:
+ // input[type=reset]:-moz-buttonlabel {
+ // content:"Reset";
+ // }
+ nsresult rv = NS_OK;
+ nsIStyleContext* styleContext = nsnull;
+ nsIFrame* generatedFrame = nsnull;
+
+ // Probe for generated content before
+ aFrame->GetStyleContext(&styleContext);
+ if (CreateGeneratedContentFrame(aPresContext, aState, aFrame, aContent,
+ styleContext, nsCSSAtoms::buttonLabelPseudo,
+ PR_FALSE, PR_FALSE, &generatedFrame)) {
+ // Add the generated frame to the child list
+ aFrameItems.AddChild(generatedFrame);
+ }
+ return rv;
+}
+
+
nsresult
nsCSSFrameConstructor::ConstructButtonControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame)
@@ -2814,6 +2848,10 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext
PR_TRUE, childItems);
}
+ if (nsHTMLAtoms::input == aTag) {
+ // Construct button label frame using generated content
+ ConstructButtonLabelFrame(aPresContext, aContent, newFrame, aState, childItems);
+ }
// if there are any anonymous children create frames for them
CreateAnonymousFrames(aPresContext, aTag, aState, aContent, newFrame,
diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h
index 213ae3ff12e..a90ab2c3150 100644
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -417,6 +417,12 @@ protected:
nsresult ConstructCheckboxControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame);
+ nsresult ConstructButtonLabelFrame(nsIPresContext *aPresContext,
+ nsIContent *aContent,
+ nsIFrame *&aFrame,
+ nsFrameConstructorState& aState,
+ nsFrameItems& aFrameItems);
+
nsresult ConstructButtonControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame);
diff --git a/layout/forms/nsGfxButtonControlFrame.cpp b/layout/forms/nsGfxButtonControlFrame.cpp
index 233477f9146..39366f148d9 100644
--- a/layout/forms/nsGfxButtonControlFrame.cpp
+++ b/layout/forms/nsGfxButtonControlFrame.cpp
@@ -17,16 +17,71 @@
*/
#include "nsGfxButtonControlFrame.h"
-#include "nsHTMLAtoms.h"
-#include "nsFormFrame.h"
-#include "nsIFormControl.h"
-#include "nsIContent.h"
#include "nsIButton.h"
-#include "nsINameSpaceManager.h"
-
+#include "nsWidgetsCID.h"
+static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIButtonIID, NS_IBUTTON_IID);
+const nscoord kSuggestedNotSet = -1;
+
+nsGfxButtonControlFrame::nsGfxButtonControlFrame()
+{
+ mRenderer.SetNameSpace(kNameSpaceID_None);
+ mSuggestedWidth = kSuggestedNotSet;
+ mSuggestedHeight = kSuggestedNotSet;
+}
+
+PRBool
+nsGfxButtonControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter)
+{
+ PRInt32 type;
+ GetType(&type);
+ if ((NS_FORM_INPUT_HIDDEN == type) || (this == aSubmitter)) {
+ return nsHTMLButtonControlFrame::IsSuccessful(aSubmitter);
+ } else {
+ return PR_FALSE;
+ }
+}
+
+PRInt32
+nsGfxButtonControlFrame::GetMaxNumValues()
+{
+ PRInt32 type;
+ GetType(&type);
+ if ((NS_FORM_INPUT_SUBMIT == type) || (NS_FORM_INPUT_HIDDEN == type)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+PRBool
+nsGfxButtonControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
+ nsString* aValues, nsString* aNames)
+{
+ nsAutoString name;
+ nsresult result = GetName(&name);
+ if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_HAS_VALUE != result)) {
+ return PR_FALSE;
+ }
+
+ PRInt32 type;
+ GetType(&type);
+
+ if (NS_FORM_INPUT_RESET == type) {
+ aNumValues = 0;
+ return PR_FALSE;
+ } else {
+ nsAutoString value;
+ GetValue(&value);
+ aValues[0] = value;
+ aNames[0] = name;
+ aNumValues = 1;
+ return PR_TRUE;
+ }
+}
+
nsresult
NS_NewGfxButtonControlFrame(nsIFrame** aNewFrame)
{
@@ -41,193 +96,128 @@ NS_NewGfxButtonControlFrame(nsIFrame** aNewFrame)
*aNewFrame = it;
return NS_OK;
}
-
-
-nsGfxButtonControlFrame::nsGfxButtonControlFrame()
+
+void
+nsGfxButtonControlFrame::MouseClicked(nsIPresContext* aPresContext)
{
- mRenderer.SetNameSpace(kNameSpaceID_None);
-}
+ PRInt32 type;
+ GetType(&type);
-NS_IMETHODIMP
-nsGfxButtonControlFrame::Init(nsIPresContext& aPresContext,
- nsIContent* aContent,
- nsIFrame* aParent,
- nsIStyleContext* aContext,
- nsIFrame* aPrevInFlow)
-{
- nsresult rv = Inherited::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
- mRenderer.SetFrame(this,aPresContext);
- return rv;
-}
+ if ((nsnull != mFormFrame) && !nsFormFrame::GetDisabled(this)) {
+ nsEventStatus status = nsEventStatus_eIgnore;
+ nsEvent event;
+ event.eventStructType = NS_EVENT;
+ nsIContent *formContent = nsnull;
+ mFormFrame->GetContent(&formContent);
-
-//
-// ReResolveStyleContext
-//
-// When the style context changes, make sure that all of our styles are still up to date.
-//
-NS_IMETHODIMP
-nsGfxButtonControlFrame::ReResolveStyleContext ( nsIPresContext* aPresContext, nsIStyleContext* aParentContext,
- PRInt32 aParentChange,
- nsStyleChangeList* aChangeList, PRInt32* aLocalChange)
-{
- // this re-resolves |mStyleContext|, so it may change
- nsresult rv = Inherited::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
+ switch(type) {
+ case NS_FORM_INPUT_RESET:
+ event.message = NS_FORM_RESET;
+ if (nsnull != formContent) {
+ formContent->HandleDOMEvent(*aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
+ }
+ if (nsEventStatus_eConsumeNoDefault != status) {
+ mFormFrame->OnReset();
+ }
+ break;
+ case NS_FORM_INPUT_SUBMIT:
+ event.message = NS_FORM_SUBMIT;
+ if (nsnull != formContent) {
+ formContent->HandleDOMEvent(*aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
+ }
+ if (nsEventStatus_eConsumeNoDefault != status) {
+ mFormFrame->OnSubmit(aPresContext, this);
+ }
}
- }
- mRenderer.ReResolveStyles(*aPresContext, aParentChange, aChangeList, aLocalChange);
-
- return rv;
-
-} // ReResolveStyleContext
+ NS_IF_RELEASE(formContent);
+ }
+}
-
-
-
-NS_METHOD
-nsGfxButtonControlFrame::Paint(nsIPresContext& aPresContext,
- nsIRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsFramePaintLayer aWhichLayer)
+const nsIID&
+nsGfxButtonControlFrame::GetIID()
{
- const nsStyleDisplay* disp = (const nsStyleDisplay*)
- mStyleContext->GetStyleData(eStyleStruct_Display);
- if (!disp->mVisible)
- return NS_OK;
-
- nsRect rect(0, 0, mRect.width, mRect.height);
- mRenderer.PaintButton(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, rect);
-
- if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
- nsString label;
- nsresult result = GetValue(&label);
-
- if (NS_CONTENT_ATTR_HAS_VALUE != result) {
- GetDefaultLabel(label);
- }
+ static NS_DEFINE_IID(kButtonIID, NS_IBUTTON_IID);
+ return kButtonIID;
+}
- nsRect content;
- mRenderer.GetButtonContentRect(rect,content);
-
- // paint the title
- const nsStyleFont* fontStyle = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
- const nsStyleColor* colorStyle = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
-
- aRenderingContext.SetFont(fontStyle->mFont);
-
- PRBool clipState;
- aRenderingContext.PushState();
- aRenderingContext.SetClipRect(rect, nsClipCombine_kIntersect, clipState);
- // if disabled paint
- if (PR_TRUE == mRenderer.isDisabled())
- {
- float p2t;
- aPresContext.GetScaledPixelsToTwips(&p2t);
- nscoord pixel = NSIntPixelsToTwips(1, p2t);
-
- aRenderingContext.SetColor(NS_RGB(255,255,255));
- aRenderingContext.DrawString(label, content.x + pixel, content.y+ pixel);
- }
-
- aRenderingContext.SetColor(colorStyle->mColor);
- aRenderingContext.DrawString(label, content.x, content.y);
- aRenderingContext.PopState(clipState);
- }
-
- return NS_OK;
+const nsIID&
+nsGfxButtonControlFrame::GetCID()
+{
+ static NS_DEFINE_IID(kButtonCID, NS_BUTTON_CID);
+ return kButtonCID;
}
NS_IMETHODIMP
-nsGfxButtonControlFrame::AttributeChanged(nsIPresContext* aPresContext,
- nsIContent* aChild,
- nsIAtom* aAttribute,
- PRInt32 aHint)
+nsGfxButtonControlFrame::GetFrameName(nsString& aResult) const
{
- if (nsHTMLAtoms::value == aAttribute) {
- // redraw button with the changed value
- Invalidate(mRect, PR_FALSE);
- }
- return NS_OK;
+ return MakeFrameName("ButtonControl", aResult);
}
-NS_METHOD
-nsGfxButtonControlFrame::Reflow(nsIPresContext& aPresContext,
+
+
+NS_IMETHODIMP
+nsGfxButtonControlFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
- const nsHTMLReflowState& aReflowState,
+ const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
-
- // add ourself as an nsIFormControlFrame
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
- nsFormFrame::AddFormControlFrame(aPresContext, *this);
+ 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 ((kSuggestedNotSet != mSuggestedWidth) ||
+ (kSuggestedNotSet != mSuggestedHeight))
+ {
+ nsHTMLReflowState suggestedReflowState(aReflowState);
+
+ // Honor the suggested width and/or height.
+ if (kSuggestedNotSet != mSuggestedWidth) {
+ suggestedReflowState.mComputedWidth = mSuggestedWidth;
+ }
- if (nsnull != aDesiredSize.maxElementSize) {
- aDesiredSize.maxElementSize->width = aDesiredSize.width;
- aDesiredSize.maxElementSize->height = aDesiredSize.height;
- }
+ if (kSuggestedNotSet != mSuggestedHeight) {
+ suggestedReflowState.mComputedHeight = mSuggestedHeight;
+ }
- aStatus = NS_FRAME_COMPLETE;
- return NS_OK;
+ return nsHTMLButtonControlFrame::Reflow(aPresContext, aDesiredSize, suggestedReflowState, aStatus);
- }
-
- nsSize ignore;
- GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, ignore);
-
- // if our size is intrinsic. Then we need to return the size we really need
- // so include our inner borders we use for focus.
- nsMargin added = mRenderer.GetAddedButtonBorderAndPadding();
- if (aReflowState.mComputedWidth == NS_INTRINSICSIZE)
- aDesiredSize.width += added.left + added.right;
-
- if (aReflowState.mComputedHeight == NS_INTRINSICSIZE)
- aDesiredSize.height += added.top + added.bottom;
-
- nsMargin bp(0,0,0,0);
- AddBordersAndPadding(&aPresContext, aReflowState, aDesiredSize, bp);
-
-
- if (nsnull != aDesiredSize.maxElementSize) {
- aDesiredSize.AddBorderPaddingToMaxElementSize(bp);
- aDesiredSize.maxElementSize->width += added.left + added.right;
- aDesiredSize.maxElementSize->height += added.top + added.bottom;
-
- }
- aStatus = NS_FRAME_COMPLETE;
- return NS_OK;
+ } else {
+ // Normal reflow.
+ return nsHTMLButtonControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
+ }
}
+NS_IMETHODIMP
+nsGfxButtonControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight)
+{
+ mSuggestedWidth = aWidth;
+ mSuggestedHeight = aHeight;
+ return NS_OK;
+}
NS_IMETHODIMP
nsGfxButtonControlFrame::HandleEvent(nsIPresContext& aPresContext,
- nsGUIEvent* aEvent,
- nsEventStatus& aEventStatus)
+ nsGUIEvent* aEvent,
+ nsEventStatus& aEventStatus)
{
+ // Override the HandleEvent to prevent the nsFrame::HandleEvent
+ // from being called. The nsFrame::HandleEvent causes the button label
+ // to be selected (Drawn with an XOR rectangle over the label)
+
// if disabled do nothing
if (mRenderer.isDisabled()) {
return NS_OK;
}
- return Inherited::HandleEvent(aPresContext, aEvent, aEventStatus);
+ // lets see if the button was clicked
+ switch (aEvent->message) {
+ case NS_MOUSE_LEFT_CLICK:
+ MouseClicked(&aPresContext);
+ break;
+ }
+
+ return NS_OK;
+
}
+
+
diff --git a/layout/forms/nsGfxButtonControlFrame.h b/layout/forms/nsGfxButtonControlFrame.h
index 1021430ebd9..658cec1612a 100644
--- a/layout/forms/nsGfxButtonControlFrame.h
+++ b/layout/forms/nsGfxButtonControlFrame.h
@@ -19,52 +19,46 @@
#ifndef nsGfxButtonControlFrame_h___
#define nsGfxButtonControlFrame_h___
-#include "nsNativeFormControlFrame.h"
-#include "nsButtonControlFrame.h"
-#include "nsButtonFrameRenderer.h"
+#include "nsFormControlFrame.h"
+#include "nsHTMLButtonControlFrame.h"
-class nsGfxButtonControlFrame : public nsButtonControlFrame {
-private:
- typedef nsButtonControlFrame Inherited;
+// Class which implements the input[type=button, reset, submit] and
+// browse button for input[type=file].
+// The label for button is specified through generated content
+// in the ua.css file.
+class nsGfxButtonControlFrame : public nsHTMLButtonControlFrame {
public:
-
nsGfxButtonControlFrame();
- NS_IMETHOD Init(nsIPresContext& aPresContext,
- nsIContent* aContent,
- nsIFrame* aParent,
- nsIStyleContext* aContext,
- nsIFrame* asPrevInFlow);
-
- NS_IMETHOD ReResolveStyleContext ( nsIPresContext* aPresContext,
- nsIStyleContext* aParentContext,
- PRInt32 aParentChange,
- nsStyleChangeList* aChangeList,
- PRInt32* aLocalChange) ;
-
- NS_IMETHOD Paint(nsIPresContext& aPresContext,
- nsIRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsFramePaintLayer aWhichLayer);
-
- NS_IMETHOD Reflow(nsIPresContext& aPresContext,
+ //nsIFrame
+ NS_IMETHOD Reflow(nsIPresContext& aCX,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
+ virtual const nsIID& GetCID();
+ virtual const nsIID& GetIID();
- NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
- nsIContent* aChild,
- nsIAtom* aAttribute,
- PRInt32 aHint);
-
- NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
+ NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
-protected:
- //GFX-rendered state variables
- nsButtonFrameRenderer mRenderer;
+
+ // nsFormControlFrame
+ NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight);
+ NS_IMETHOD GetFrameName(nsString& aResult) const;
+ PRBool IsSuccessful(nsIFormControlFrame* aSubmitter);
+ virtual PRInt32 GetMaxNumValues();
+ virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
+ nsString* aValues, nsString* aNames);
+ virtual void MouseClicked(nsIPresContext* aPresContext);
+
+private:
+ NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
+ NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
+
+ nscoord mSuggestedWidth;
+ nscoord mSuggestedHeight;
};
diff --git a/layout/html/document/src/ua.css b/layout/html/document/src/ua.css
index 3fe675f38b1..aa7e242dab4 100644
--- a/layout/html/document/src/ua.css
+++ b/layout/html/document/src/ua.css
@@ -421,6 +421,49 @@ form {
display: block;
margin: 1em 0;
}
+
+
+/* button */
+input[type=button]:-moz-buttonlabel {
+ content:" ";
+ font-family: sans-serif;
+ font-size: small;
+ background-color:inherit;
+}
+
+input[type=button][value]:-moz-buttonlabel {
+ content:attr(value);
+ font-family: sans-serif;
+ font-size: small;
+ background-color:inherit;
+}
+
+/* submit */
+input[type=submit]:-moz-buttonlabel {
+ content:"submit";
+ font-family: sans-serif;
+ font-size: small;
+}
+
+input[type=submit][value]:-moz-buttonlabel {
+ content:attr(value);
+ font-family: sans-serif;
+ font-size: small;
+}
+
+/* reset */
+input[type=reset]:-moz-buttonlabel {
+ content:"reset";
+ font-family: sans-serif;
+ font-size: small;
+}
+
+input[type=reset][value]:-moz-buttonlabel {
+ content:attr(value);
+ font-family: sans-serif;
+ font-size: small;
+}
+
input {
vertical-align: bottom;
border: 2px inset rgb(204, 204, 204);
@@ -443,6 +486,12 @@ input[type=file] input[type=button] {
height:inherit;
}
+input[type=file] input[type=button]:-moz-buttonlabel {
+ content:"Browse...";
+ font-family: sans-serif;
+}
+
+
input[type=radio] {
/* these margins are for NavQuirks, we need a Standard ua.css */
margin-left: 3px;
@@ -606,13 +655,11 @@ input[type="button"] {
border: 2px outset rgb(156, 154, 156);
background-color: rgb(206, 207, 206);
color:black;
-
padding: 1px;
}
input[type="button"]:active {
border-style: inset;
-
padding-left: 2px;
padding-right: 0px;
padding-top: 2px;
@@ -648,7 +695,6 @@ input[type="button"]:focus:-moz-focus-inner {
padding-right : 1px;
padding-top : 0px;
padding-bottom: 0px;
-
margin: 0px;
border : 1px dotted black;
}
@@ -873,6 +919,7 @@ optgroup:before {
content:attr(label);
}
+
textarea {
vertical-align: bottom;
border: 2px inset #c0c0c0;
diff --git a/layout/html/forms/src/nsGfxButtonControlFrame.cpp b/layout/html/forms/src/nsGfxButtonControlFrame.cpp
index 233477f9146..39366f148d9 100644
--- a/layout/html/forms/src/nsGfxButtonControlFrame.cpp
+++ b/layout/html/forms/src/nsGfxButtonControlFrame.cpp
@@ -17,16 +17,71 @@
*/
#include "nsGfxButtonControlFrame.h"
-#include "nsHTMLAtoms.h"
-#include "nsFormFrame.h"
-#include "nsIFormControl.h"
-#include "nsIContent.h"
#include "nsIButton.h"
-#include "nsINameSpaceManager.h"
-
+#include "nsWidgetsCID.h"
+static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIButtonIID, NS_IBUTTON_IID);
+const nscoord kSuggestedNotSet = -1;
+
+nsGfxButtonControlFrame::nsGfxButtonControlFrame()
+{
+ mRenderer.SetNameSpace(kNameSpaceID_None);
+ mSuggestedWidth = kSuggestedNotSet;
+ mSuggestedHeight = kSuggestedNotSet;
+}
+
+PRBool
+nsGfxButtonControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter)
+{
+ PRInt32 type;
+ GetType(&type);
+ if ((NS_FORM_INPUT_HIDDEN == type) || (this == aSubmitter)) {
+ return nsHTMLButtonControlFrame::IsSuccessful(aSubmitter);
+ } else {
+ return PR_FALSE;
+ }
+}
+
+PRInt32
+nsGfxButtonControlFrame::GetMaxNumValues()
+{
+ PRInt32 type;
+ GetType(&type);
+ if ((NS_FORM_INPUT_SUBMIT == type) || (NS_FORM_INPUT_HIDDEN == type)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+PRBool
+nsGfxButtonControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
+ nsString* aValues, nsString* aNames)
+{
+ nsAutoString name;
+ nsresult result = GetName(&name);
+ if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_HAS_VALUE != result)) {
+ return PR_FALSE;
+ }
+
+ PRInt32 type;
+ GetType(&type);
+
+ if (NS_FORM_INPUT_RESET == type) {
+ aNumValues = 0;
+ return PR_FALSE;
+ } else {
+ nsAutoString value;
+ GetValue(&value);
+ aValues[0] = value;
+ aNames[0] = name;
+ aNumValues = 1;
+ return PR_TRUE;
+ }
+}
+
nsresult
NS_NewGfxButtonControlFrame(nsIFrame** aNewFrame)
{
@@ -41,193 +96,128 @@ NS_NewGfxButtonControlFrame(nsIFrame** aNewFrame)
*aNewFrame = it;
return NS_OK;
}
-
-
-nsGfxButtonControlFrame::nsGfxButtonControlFrame()
+
+void
+nsGfxButtonControlFrame::MouseClicked(nsIPresContext* aPresContext)
{
- mRenderer.SetNameSpace(kNameSpaceID_None);
-}
+ PRInt32 type;
+ GetType(&type);
-NS_IMETHODIMP
-nsGfxButtonControlFrame::Init(nsIPresContext& aPresContext,
- nsIContent* aContent,
- nsIFrame* aParent,
- nsIStyleContext* aContext,
- nsIFrame* aPrevInFlow)
-{
- nsresult rv = Inherited::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
- mRenderer.SetFrame(this,aPresContext);
- return rv;
-}
+ if ((nsnull != mFormFrame) && !nsFormFrame::GetDisabled(this)) {
+ nsEventStatus status = nsEventStatus_eIgnore;
+ nsEvent event;
+ event.eventStructType = NS_EVENT;
+ nsIContent *formContent = nsnull;
+ mFormFrame->GetContent(&formContent);
-
-//
-// ReResolveStyleContext
-//
-// When the style context changes, make sure that all of our styles are still up to date.
-//
-NS_IMETHODIMP
-nsGfxButtonControlFrame::ReResolveStyleContext ( nsIPresContext* aPresContext, nsIStyleContext* aParentContext,
- PRInt32 aParentChange,
- nsStyleChangeList* aChangeList, PRInt32* aLocalChange)
-{
- // this re-resolves |mStyleContext|, so it may change
- nsresult rv = Inherited::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
+ switch(type) {
+ case NS_FORM_INPUT_RESET:
+ event.message = NS_FORM_RESET;
+ if (nsnull != formContent) {
+ formContent->HandleDOMEvent(*aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
+ }
+ if (nsEventStatus_eConsumeNoDefault != status) {
+ mFormFrame->OnReset();
+ }
+ break;
+ case NS_FORM_INPUT_SUBMIT:
+ event.message = NS_FORM_SUBMIT;
+ if (nsnull != formContent) {
+ formContent->HandleDOMEvent(*aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
+ }
+ if (nsEventStatus_eConsumeNoDefault != status) {
+ mFormFrame->OnSubmit(aPresContext, this);
+ }
}
- }
- mRenderer.ReResolveStyles(*aPresContext, aParentChange, aChangeList, aLocalChange);
-
- return rv;
-
-} // ReResolveStyleContext
+ NS_IF_RELEASE(formContent);
+ }
+}
-
-
-
-NS_METHOD
-nsGfxButtonControlFrame::Paint(nsIPresContext& aPresContext,
- nsIRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsFramePaintLayer aWhichLayer)
+const nsIID&
+nsGfxButtonControlFrame::GetIID()
{
- const nsStyleDisplay* disp = (const nsStyleDisplay*)
- mStyleContext->GetStyleData(eStyleStruct_Display);
- if (!disp->mVisible)
- return NS_OK;
-
- nsRect rect(0, 0, mRect.width, mRect.height);
- mRenderer.PaintButton(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, rect);
-
- if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
- nsString label;
- nsresult result = GetValue(&label);
-
- if (NS_CONTENT_ATTR_HAS_VALUE != result) {
- GetDefaultLabel(label);
- }
+ static NS_DEFINE_IID(kButtonIID, NS_IBUTTON_IID);
+ return kButtonIID;
+}
- nsRect content;
- mRenderer.GetButtonContentRect(rect,content);
-
- // paint the title
- const nsStyleFont* fontStyle = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
- const nsStyleColor* colorStyle = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
-
- aRenderingContext.SetFont(fontStyle->mFont);
-
- PRBool clipState;
- aRenderingContext.PushState();
- aRenderingContext.SetClipRect(rect, nsClipCombine_kIntersect, clipState);
- // if disabled paint
- if (PR_TRUE == mRenderer.isDisabled())
- {
- float p2t;
- aPresContext.GetScaledPixelsToTwips(&p2t);
- nscoord pixel = NSIntPixelsToTwips(1, p2t);
-
- aRenderingContext.SetColor(NS_RGB(255,255,255));
- aRenderingContext.DrawString(label, content.x + pixel, content.y+ pixel);
- }
-
- aRenderingContext.SetColor(colorStyle->mColor);
- aRenderingContext.DrawString(label, content.x, content.y);
- aRenderingContext.PopState(clipState);
- }
-
- return NS_OK;
+const nsIID&
+nsGfxButtonControlFrame::GetCID()
+{
+ static NS_DEFINE_IID(kButtonCID, NS_BUTTON_CID);
+ return kButtonCID;
}
NS_IMETHODIMP
-nsGfxButtonControlFrame::AttributeChanged(nsIPresContext* aPresContext,
- nsIContent* aChild,
- nsIAtom* aAttribute,
- PRInt32 aHint)
+nsGfxButtonControlFrame::GetFrameName(nsString& aResult) const
{
- if (nsHTMLAtoms::value == aAttribute) {
- // redraw button with the changed value
- Invalidate(mRect, PR_FALSE);
- }
- return NS_OK;
+ return MakeFrameName("ButtonControl", aResult);
}
-NS_METHOD
-nsGfxButtonControlFrame::Reflow(nsIPresContext& aPresContext,
+
+
+NS_IMETHODIMP
+nsGfxButtonControlFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
- const nsHTMLReflowState& aReflowState,
+ const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
-
- // add ourself as an nsIFormControlFrame
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
- nsFormFrame::AddFormControlFrame(aPresContext, *this);
+ 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 ((kSuggestedNotSet != mSuggestedWidth) ||
+ (kSuggestedNotSet != mSuggestedHeight))
+ {
+ nsHTMLReflowState suggestedReflowState(aReflowState);
+
+ // Honor the suggested width and/or height.
+ if (kSuggestedNotSet != mSuggestedWidth) {
+ suggestedReflowState.mComputedWidth = mSuggestedWidth;
+ }
- if (nsnull != aDesiredSize.maxElementSize) {
- aDesiredSize.maxElementSize->width = aDesiredSize.width;
- aDesiredSize.maxElementSize->height = aDesiredSize.height;
- }
+ if (kSuggestedNotSet != mSuggestedHeight) {
+ suggestedReflowState.mComputedHeight = mSuggestedHeight;
+ }
- aStatus = NS_FRAME_COMPLETE;
- return NS_OK;
+ return nsHTMLButtonControlFrame::Reflow(aPresContext, aDesiredSize, suggestedReflowState, aStatus);
- }
-
- nsSize ignore;
- GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, ignore);
-
- // if our size is intrinsic. Then we need to return the size we really need
- // so include our inner borders we use for focus.
- nsMargin added = mRenderer.GetAddedButtonBorderAndPadding();
- if (aReflowState.mComputedWidth == NS_INTRINSICSIZE)
- aDesiredSize.width += added.left + added.right;
-
- if (aReflowState.mComputedHeight == NS_INTRINSICSIZE)
- aDesiredSize.height += added.top + added.bottom;
-
- nsMargin bp(0,0,0,0);
- AddBordersAndPadding(&aPresContext, aReflowState, aDesiredSize, bp);
-
-
- if (nsnull != aDesiredSize.maxElementSize) {
- aDesiredSize.AddBorderPaddingToMaxElementSize(bp);
- aDesiredSize.maxElementSize->width += added.left + added.right;
- aDesiredSize.maxElementSize->height += added.top + added.bottom;
-
- }
- aStatus = NS_FRAME_COMPLETE;
- return NS_OK;
+ } else {
+ // Normal reflow.
+ return nsHTMLButtonControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
+ }
}
+NS_IMETHODIMP
+nsGfxButtonControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight)
+{
+ mSuggestedWidth = aWidth;
+ mSuggestedHeight = aHeight;
+ return NS_OK;
+}
NS_IMETHODIMP
nsGfxButtonControlFrame::HandleEvent(nsIPresContext& aPresContext,
- nsGUIEvent* aEvent,
- nsEventStatus& aEventStatus)
+ nsGUIEvent* aEvent,
+ nsEventStatus& aEventStatus)
{
+ // Override the HandleEvent to prevent the nsFrame::HandleEvent
+ // from being called. The nsFrame::HandleEvent causes the button label
+ // to be selected (Drawn with an XOR rectangle over the label)
+
// if disabled do nothing
if (mRenderer.isDisabled()) {
return NS_OK;
}
- return Inherited::HandleEvent(aPresContext, aEvent, aEventStatus);
+ // lets see if the button was clicked
+ switch (aEvent->message) {
+ case NS_MOUSE_LEFT_CLICK:
+ MouseClicked(&aPresContext);
+ break;
+ }
+
+ return NS_OK;
+
}
+
+
diff --git a/layout/html/forms/src/nsGfxButtonControlFrame.h b/layout/html/forms/src/nsGfxButtonControlFrame.h
index 1021430ebd9..658cec1612a 100644
--- a/layout/html/forms/src/nsGfxButtonControlFrame.h
+++ b/layout/html/forms/src/nsGfxButtonControlFrame.h
@@ -19,52 +19,46 @@
#ifndef nsGfxButtonControlFrame_h___
#define nsGfxButtonControlFrame_h___
-#include "nsNativeFormControlFrame.h"
-#include "nsButtonControlFrame.h"
-#include "nsButtonFrameRenderer.h"
+#include "nsFormControlFrame.h"
+#include "nsHTMLButtonControlFrame.h"
-class nsGfxButtonControlFrame : public nsButtonControlFrame {
-private:
- typedef nsButtonControlFrame Inherited;
+// Class which implements the input[type=button, reset, submit] and
+// browse button for input[type=file].
+// The label for button is specified through generated content
+// in the ua.css file.
+class nsGfxButtonControlFrame : public nsHTMLButtonControlFrame {
public:
-
nsGfxButtonControlFrame();
- NS_IMETHOD Init(nsIPresContext& aPresContext,
- nsIContent* aContent,
- nsIFrame* aParent,
- nsIStyleContext* aContext,
- nsIFrame* asPrevInFlow);
-
- NS_IMETHOD ReResolveStyleContext ( nsIPresContext* aPresContext,
- nsIStyleContext* aParentContext,
- PRInt32 aParentChange,
- nsStyleChangeList* aChangeList,
- PRInt32* aLocalChange) ;
-
- NS_IMETHOD Paint(nsIPresContext& aPresContext,
- nsIRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsFramePaintLayer aWhichLayer);
-
- NS_IMETHOD Reflow(nsIPresContext& aPresContext,
+ //nsIFrame
+ NS_IMETHOD Reflow(nsIPresContext& aCX,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
+ virtual const nsIID& GetCID();
+ virtual const nsIID& GetIID();
- NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
- nsIContent* aChild,
- nsIAtom* aAttribute,
- PRInt32 aHint);
-
- NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
+ NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
-protected:
- //GFX-rendered state variables
- nsButtonFrameRenderer mRenderer;
+
+ // nsFormControlFrame
+ NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight);
+ NS_IMETHOD GetFrameName(nsString& aResult) const;
+ PRBool IsSuccessful(nsIFormControlFrame* aSubmitter);
+ virtual PRInt32 GetMaxNumValues();
+ virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
+ nsString* aValues, nsString* aNames);
+ virtual void MouseClicked(nsIPresContext* aPresContext);
+
+private:
+ NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
+ NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
+
+ nscoord mSuggestedWidth;
+ nscoord mSuggestedHeight;
};
diff --git a/layout/html/style/public/nsCSSAtomList.h b/layout/html/style/public/nsCSSAtomList.h
index df983156370..8afa5d0ac31 100644
--- a/layout/html/style/public/nsCSSAtomList.h
+++ b/layout/html/style/public/nsCSSAtomList.h
@@ -40,6 +40,8 @@ CSS_ATOM(afterPseudo, ":after")
CSS_ATOM(beforePseudo, ":before")
+CSS_ATOM(buttonLabelPseudo, ":-moz-buttonlabel")
+
CSS_ATOM(checkedPseudo, ":checked")
CSS_ATOM(disabledPseudo, ":disabled")
diff --git a/layout/html/style/src/nsCSSFrameConstructor.cpp b/layout/html/style/src/nsCSSFrameConstructor.cpp
index 8029e78d9cf..165aa3c72cd 100644
--- a/layout/html/style/src/nsCSSFrameConstructor.cpp
+++ b/layout/html/style/src/nsCSSFrameConstructor.cpp
@@ -2458,6 +2458,40 @@ nsCSSFrameConstructor::ConstructCheckboxControlFrame(nsIPresContext* aPres
return rv;
}
+nsresult
+nsCSSFrameConstructor::ConstructButtonLabelFrame(nsIPresContext *aPresContext,
+ nsIContent *aContent,
+ nsIFrame *&aFrame,
+ nsFrameConstructorState& aState,
+ nsFrameItems& aFrameItems)
+{
+ // Construct a button label using generated content specified
+ // through style. A style rule of following form must be
+ // present in ua.css or other style sheet
+ // input[type=button][value]:-moz-buttonlabel {
+ // content:attr(value);
+ // }
+ // The default for the label is specified with a rule similar to
+ // the following:
+ // input[type=reset]:-moz-buttonlabel {
+ // content:"Reset";
+ // }
+ nsresult rv = NS_OK;
+ nsIStyleContext* styleContext = nsnull;
+ nsIFrame* generatedFrame = nsnull;
+
+ // Probe for generated content before
+ aFrame->GetStyleContext(&styleContext);
+ if (CreateGeneratedContentFrame(aPresContext, aState, aFrame, aContent,
+ styleContext, nsCSSAtoms::buttonLabelPseudo,
+ PR_FALSE, PR_FALSE, &generatedFrame)) {
+ // Add the generated frame to the child list
+ aFrameItems.AddChild(generatedFrame);
+ }
+ return rv;
+}
+
+
nsresult
nsCSSFrameConstructor::ConstructButtonControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame)
@@ -2814,6 +2848,10 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext
PR_TRUE, childItems);
}
+ if (nsHTMLAtoms::input == aTag) {
+ // Construct button label frame using generated content
+ ConstructButtonLabelFrame(aPresContext, aContent, newFrame, aState, childItems);
+ }
// if there are any anonymous children create frames for them
CreateAnonymousFrames(aPresContext, aTag, aState, aContent, newFrame,
diff --git a/layout/html/style/src/nsCSSFrameConstructor.h b/layout/html/style/src/nsCSSFrameConstructor.h
index 213ae3ff12e..a90ab2c3150 100644
--- a/layout/html/style/src/nsCSSFrameConstructor.h
+++ b/layout/html/style/src/nsCSSFrameConstructor.h
@@ -417,6 +417,12 @@ protected:
nsresult ConstructCheckboxControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame);
+ nsresult ConstructButtonLabelFrame(nsIPresContext *aPresContext,
+ nsIContent *aContent,
+ nsIFrame *&aFrame,
+ nsFrameConstructorState& aState,
+ nsFrameItems& aFrameItems);
+
nsresult ConstructButtonControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame);
diff --git a/layout/style/ua.css b/layout/style/ua.css
index 3fe675f38b1..aa7e242dab4 100644
--- a/layout/style/ua.css
+++ b/layout/style/ua.css
@@ -421,6 +421,49 @@ form {
display: block;
margin: 1em 0;
}
+
+
+/* button */
+input[type=button]:-moz-buttonlabel {
+ content:" ";
+ font-family: sans-serif;
+ font-size: small;
+ background-color:inherit;
+}
+
+input[type=button][value]:-moz-buttonlabel {
+ content:attr(value);
+ font-family: sans-serif;
+ font-size: small;
+ background-color:inherit;
+}
+
+/* submit */
+input[type=submit]:-moz-buttonlabel {
+ content:"submit";
+ font-family: sans-serif;
+ font-size: small;
+}
+
+input[type=submit][value]:-moz-buttonlabel {
+ content:attr(value);
+ font-family: sans-serif;
+ font-size: small;
+}
+
+/* reset */
+input[type=reset]:-moz-buttonlabel {
+ content:"reset";
+ font-family: sans-serif;
+ font-size: small;
+}
+
+input[type=reset][value]:-moz-buttonlabel {
+ content:attr(value);
+ font-family: sans-serif;
+ font-size: small;
+}
+
input {
vertical-align: bottom;
border: 2px inset rgb(204, 204, 204);
@@ -443,6 +486,12 @@ input[type=file] input[type=button] {
height:inherit;
}
+input[type=file] input[type=button]:-moz-buttonlabel {
+ content:"Browse...";
+ font-family: sans-serif;
+}
+
+
input[type=radio] {
/* these margins are for NavQuirks, we need a Standard ua.css */
margin-left: 3px;
@@ -606,13 +655,11 @@ input[type="button"] {
border: 2px outset rgb(156, 154, 156);
background-color: rgb(206, 207, 206);
color:black;
-
padding: 1px;
}
input[type="button"]:active {
border-style: inset;
-
padding-left: 2px;
padding-right: 0px;
padding-top: 2px;
@@ -648,7 +695,6 @@ input[type="button"]:focus:-moz-focus-inner {
padding-right : 1px;
padding-top : 0px;
padding-bottom: 0px;
-
margin: 0px;
border : 1px dotted black;
}
@@ -873,6 +919,7 @@ optgroup:before {
content:attr(label);
}
+
textarea {
vertical-align: bottom;
border: 2px inset #c0c0c0;