diff --git a/layout/html/forms/src/nsGfxTextControlFrame2.cpp b/layout/html/forms/src/nsGfxTextControlFrame2.cpp
index 9061a535aa8b..0b9a9c07c624 100644
--- a/layout/html/forms/src/nsGfxTextControlFrame2.cpp
+++ b/layout/html/forms/src/nsGfxTextControlFrame2.cpp
@@ -50,7 +50,9 @@
#include "nsINameSpaceManager.h"
#include "nsINodeInfo.h"
#include "nsIScrollableView.h"
-
+#include "nsIScrollableFrame.h" //to turn off scroll bars
+#include "nsFormControlFrame.h" //for registering accesskeys
+#include "nsIDeviceContext.h" // to measure fonts
#include "nsIContent.h"
#include "nsIAtom.h"
@@ -494,10 +496,13 @@ nsGfxTextControlFrame2::nsGfxTextControlFrame2()
mIsProcessing=PR_FALSE;
mFormFrame = nsnull;
mCachedState = nsnull;
+ mSuggestedWidth = NS_FORMSIZE_NOTSET;
+ mSuggestedHeight = NS_FORMSIZE_NOTSET;
}
nsGfxTextControlFrame2::~nsGfxTextControlFrame2()
{
+ nsFormControlFrame::RegUnRegAccessKey(nsnull, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
if (mFormFrame) {
mFormFrame->RemoveFormControlFrame(*this);
mFormFrame = nsnull;
@@ -535,6 +540,233 @@ PRBool nsGfxTextControlFrame2::IsPasswordTextControl() const
}
+nsresult
+nsGfxTextControlFrame2::GetColRowSizeAttr(nsIFormControlFrame* aFrame,
+ nsIAtom * aColSizeAttr,
+ nsHTMLValue & aColSize,
+ nsresult & aColStatus,
+ nsIAtom * aRowSizeAttr,
+ nsHTMLValue & aRowSize,
+ nsresult & aRowStatus)
+{
+ nsIContent* iContent = nsnull;
+ aFrame->GetFormContent((nsIContent*&) iContent);
+ if (!iContent) {
+ return NS_ERROR_FAILURE;
+ }
+ nsIHTMLContent* hContent = nsnull;
+ nsresult result = iContent->QueryInterface(kIHTMLContentIID, (void**)&hContent);
+ if ((NS_OK != result) || !hContent) {
+ NS_RELEASE(iContent);
+ return NS_ERROR_FAILURE;
+ }
+
+ aColStatus = NS_CONTENT_ATTR_NOT_THERE;
+ if (nsnull != aColSizeAttr) {
+ aColStatus = hContent->GetHTMLAttribute(aColSizeAttr, aColSize);
+ }
+
+ aRowStatus= NS_CONTENT_ATTR_NOT_THERE;
+ if (nsnull != aRowSizeAttr) {
+ aRowStatus = hContent->GetHTMLAttribute(aRowSizeAttr, aRowSize);
+ }
+
+ NS_RELEASE(hContent);
+ NS_RELEASE(iContent);
+
+ return NS_OK;
+}
+
+
+
+NS_IMETHODIMP
+nsGfxTextControlFrame2::ReflowStandard(nsIPresContext* aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ const nsHTMLReflowState& aReflowState,
+ nsReflowStatus& aStatus,
+ nsMargin& aBorder,
+ nsMargin& aPadding)
+{
+ // get the css size and let the frame use or override it
+ nsSize styleSize;
+ nsFormControlFrame::GetStyleSize(aPresContext, aReflowState, styleSize);
+
+ nsSize desiredSize;
+ nsSize minSize;
+
+ PRBool widthExplicit, heightExplicit;
+ PRInt32 ignore;
+ PRInt32 type;
+ GetType(&type);
+ if ((NS_FORM_INPUT_TEXT == type) || (NS_FORM_INPUT_PASSWORD == type)) {
+ PRInt32 width = 0;
+ if (NS_CONTENT_ATTR_HAS_VALUE != GetSizeFromContent(&width)) {
+ width = GetDefaultColumnWidth();
+ }
+ nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull,
+ nsnull, width,
+ PR_FALSE, nsnull, 1);
+ CalculateSizeStandard(aPresContext, aReflowState.rendContext, this, styleSize,
+ textSpec, desiredSize, minSize, widthExplicit,
+ heightExplicit, ignore, aBorder, aPadding);
+ } else {
+ nsInputDimensionSpec areaSpec(nsHTMLAtoms::cols, PR_FALSE, nsnull,
+ nsnull, GetDefaultColumnWidth(),
+ PR_FALSE, nsHTMLAtoms::rows, 1);
+ CalculateSizeStandard(aPresContext, aReflowState.rendContext, this, styleSize,
+ areaSpec, desiredSize, minSize, widthExplicit,
+ heightExplicit, ignore, aBorder, aPadding);
+ }
+
+ // CalculateSize makes calls in the nsFormControlHelper that figures
+ // out the entire size of the control when in NavQuirks mode. For the
+ // textarea, this means the scrollbar sizes hav already been added to
+ // its overall size and do not need to be added here.
+ if (NS_FORM_TEXTAREA == type) {
+ float p2t;
+ aPresContext->GetPixelsToTwips(&p2t);
+
+ nscoord scrollbarWidth = 0;
+ nscoord scrollbarHeight = 0;
+ float scale;
+ nsCOMPtr dx;
+ aPresContext->GetDeviceContext(getter_AddRefs(dx));
+ if (dx) {
+ float sbWidth;
+ float sbHeight;
+ dx->GetCanonicalPixelScale(scale);
+ dx->GetScrollBarDimensions(sbWidth, sbHeight);
+ scrollbarWidth = PRInt32(sbWidth * scale);
+ scrollbarHeight = PRInt32(sbHeight * scale);
+ } else {
+ scrollbarWidth = nsFormControlFrame::GetScrollbarWidth(p2t);
+ scrollbarHeight = scrollbarWidth;
+ }
+
+ if (!heightExplicit) {
+ desiredSize.height += scrollbarHeight;
+ minSize.height += scrollbarHeight;
+ }
+ if (!widthExplicit) {
+ desiredSize.width += scrollbarWidth;
+ minSize.width += scrollbarWidth;
+ }
+ }
+ desiredSize.width += aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom;
+ desiredSize.height += aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right;
+
+ aDesiredSize.width = desiredSize.width;
+ aDesiredSize.height = desiredSize.height;
+ aDesiredSize.ascent = aDesiredSize.height;
+ aDesiredSize.descent = 0;
+
+ if (aDesiredSize.maxElementSize) {
+ aDesiredSize.maxElementSize->width = minSize.width;
+ aDesiredSize.maxElementSize->height = minSize.height;
+ }
+
+ return NS_OK;
+
+}
+
+
+PRInt32
+nsGfxTextControlFrame2::CalculateSizeStandard (nsIPresContext* aPresContext,
+ nsIRenderingContext* aRendContext,
+ nsIFormControlFrame* aFrame,
+ const nsSize& aCSSSize,
+ nsInputDimensionSpec& aSpec,
+ nsSize& aDesiredSize,
+ nsSize& aMinSize,
+ PRBool& aWidthExplicit,
+ PRBool& aHeightExplicit,
+ nscoord& aRowHeight,
+ nsMargin& aBorder,
+ nsMargin& aPadding)
+{
+ nscoord charWidth = 0;
+ aWidthExplicit = PR_FALSE;
+ aHeightExplicit = PR_FALSE;
+
+ aDesiredSize.width = CSS_NOTSET;
+ aDesiredSize.height = CSS_NOTSET;
+
+ nsHTMLValue colAttr;
+ nsresult colStatus;
+ nsHTMLValue rowAttr;
+ nsresult rowStatus;
+ if (NS_ERROR_FAILURE == GetColRowSizeAttr(aFrame,
+ aSpec.mColSizeAttr, colAttr, colStatus,
+ aSpec.mRowSizeAttr, rowAttr, rowStatus)) {
+ return 0;
+ }
+
+ float p2t;
+ aPresContext->GetScaledPixelsToTwips(&p2t);
+
+ // determine the width, char height, row height
+ if (NS_CONTENT_ATTR_HAS_VALUE == colStatus) { // col attr will provide width
+ PRInt32 col = ((colAttr.GetUnit() == eHTMLUnit_Pixel) ? colAttr.GetPixelValue() : colAttr.GetIntValue());
+ col = (col <= 0) ? 1 : col; // XXX why a default of 1 char, why hide it
+ charWidth = nsFormControlHelper::GetTextSize(aPresContext, aFrame, col, aDesiredSize, aRendContext);
+ aMinSize.width = aDesiredSize.width;
+ } else {
+ charWidth = nsFormControlHelper::GetTextSize(aPresContext, aFrame, aSpec.mColDefaultSize, aDesiredSize, aRendContext);
+ aMinSize.width = aDesiredSize.width;
+ if (CSS_NOTSET != aCSSSize.width) { // css provides width
+ NS_ASSERTION(aCSSSize.width >= 0, "form control's computed width is < 0");
+ if (NS_INTRINSICSIZE != aCSSSize.width) {
+ aDesiredSize.width = aCSSSize.width;
+ aWidthExplicit = PR_TRUE;
+ }
+ }
+ }
+
+ nscoord fontHeight = 0;
+ //nscoord fontLeading = 0;
+ // get leading
+ nsCOMPtr fontMet;
+ nsresult res = nsFormControlHelper::GetFrameFontFM(aPresContext, aFrame, getter_AddRefs(fontMet));
+ if (NS_SUCCEEDED(res) && fontMet) {
+ aRendContext->SetFont(fontMet);
+ fontMet->GetHeight(fontHeight);
+ // leading is NOT suppose to be added in
+ //fontMet->GetLeading(fontLeading);
+ //aDesiredSize.height += fontLeading;
+ }
+ aRowHeight = aDesiredSize.height;
+ aMinSize.height = aDesiredSize.height;
+ PRInt32 numRows = 0;
+
+ if (NS_CONTENT_ATTR_HAS_VALUE == rowStatus) { // row attr will provide height
+ PRInt32 rowAttrInt = ((rowAttr.GetUnit() == eHTMLUnit_Pixel)
+ ? rowAttr.GetPixelValue() : rowAttr.GetIntValue());
+ numRows = (rowAttrInt > 0) ? rowAttrInt : 1;
+ aDesiredSize.height = aDesiredSize.height * numRows;
+ } else {
+ aDesiredSize.height = aDesiredSize.height * aSpec.mRowDefaultSize;
+ if (CSS_NOTSET != aCSSSize.height) { // css provides height
+ NS_ASSERTION(aCSSSize.height > 0, "form control's computed height is <= 0");
+ if (NS_INTRINSICSIZE != aCSSSize.height) {
+ aDesiredSize.height = aCSSSize.height;
+ aHeightExplicit = PR_TRUE;
+ }
+ }
+ }
+
+ numRows = (aRowHeight > 0) ? (aDesiredSize.height / aRowHeight) : 0;
+ if (numRows == 1) {
+ PRInt32 type;
+ GetType(&type);
+ if (NS_FORM_TEXTAREA == type) {
+ aDesiredSize.height += fontHeight;
+ }
+ }
+
+ return numRows;
+}
+
+
NS_IMETHODIMP
nsGfxTextControlFrame2::CreateFrameFor(nsIPresContext* aPresContext,
nsIContent * aContent,
@@ -544,7 +776,7 @@ nsGfxTextControlFrame2::CreateFrameFor(nsIPresContext* aPresContext,
return NS_ERROR_FAILURE;
}
-#define DIV_STRING "user-focus: none; overflow:scroll; border: 0px !important; padding: 0px; margin:0px"
+#define DIV_STRING "user-focus: none; overflow:auto; border: 0px !important; padding: 0px; margin:0px"
NS_IMETHODIMP
nsGfxTextControlFrame2::CreateAnonymousContent(nsIPresContext* aPresContext,
@@ -681,6 +913,8 @@ nsGfxTextControlFrame2::CreateAnonymousContent(nsIPresContext* aPresContext,
+
+
NS_IMETHODIMP nsGfxTextControlFrame2::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
@@ -736,10 +970,83 @@ NS_IMETHODIMP nsGfxTextControlFrame2::Reflow(nsIPresContext* aPresConte
}
}
}
+ else if (eReflowReason_Initial == aReflowState.reason)
+ {
+ nsFormControlFrame::RegUnRegAccessKey(nsnull, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
+ nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this));
+ }
- nsresult rv = ReflowChild(child, aPresContext, aDesiredSize, kidReflowState, 0, 0, 0, aStatus);
+//get margins
+ // Figure out if we are doing Quirks or Standard
+ nsCompatibility mode;
+ aPresContext->GetCompatibilityMode(&mode);
+
+ nsMargin border;
+ border.SizeTo(0, 0, 0, 0);
+ nsMargin padding;
+ padding.SizeTo(0, 0, 0, 0);
+ // Get the CSS border
+ const nsStyleSpacing* spacing;
+ GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
+ spacing->CalcBorderFor(this, border);
+ spacing->CalcPaddingFor(this, padding);
+
+ // calculate the the desired size for the text control
+ // use the suggested size if it has been set
+ nsresult rv = NS_OK;
+ nsHTMLReflowState suggestedReflowState(aReflowState);
+ if ((NS_FORMSIZE_NOTSET != mSuggestedWidth) ||
+ (NS_FORMSIZE_NOTSET != mSuggestedHeight))
+ {
+ // Honor the suggested width and/or height.
+ if (NS_FORMSIZE_NOTSET != mSuggestedWidth)
+ {
+ suggestedReflowState.mComputedWidth = mSuggestedWidth;
+ aDesiredSize.width = mSuggestedWidth;
+ }
+
+ if (NS_FORMSIZE_NOTSET != mSuggestedHeight)
+ {
+ suggestedReflowState.mComputedHeight = mSuggestedHeight;
+ aDesiredSize.height = mSuggestedHeight;
+ }
+ rv = NS_OK;
+
+ aDesiredSize.ascent = aDesiredSize.height;
+ aDesiredSize.descent = 0;
+
+ aStatus = NS_FRAME_COMPLETE;
+ }
+ else
+ {
+ // this is the right way
+ // Quirks mode will NOT obey CSS border and padding
+ // GetDesiredSize calculates the size without CSS borders
+ // the nsLeafFrame::Reflow will add in the borders
+ if (eCompatibility_NavQuirks == mode) {
+ //rv = ReflowNavQuirks(aPresContext, aDesiredSize, aReflowState, aStatus, border, padding);
+ } else {
+ rv = ReflowStandard(aPresContext, aDesiredSize, aReflowState, aStatus, border, padding);
+ }
+
+ if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedWidth) {
+ if (aReflowState.mComputedWidth > aDesiredSize.width) {
+ aDesiredSize.width = aReflowState.mComputedWidth;
+ }
+ }
+ if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedHeight) {
+ if (aReflowState.mComputedHeight > aDesiredSize.height) {
+ aDesiredSize.height = aReflowState.mComputedHeight;
+ }
+ }
+ }
+
+
+ nsHTMLReflowMetrics kidReflowDesiredSize(0,0);
+
+ rv = ReflowChild(child, aPresContext, kidReflowDesiredSize, kidReflowState, 0, 0, 0, aStatus);
// Place and size the child.
- FinishReflowChild(child, aPresContext, aDesiredSize, aReflowState.mComputedBorderPadding.left,
+ FinishReflowChild(child, aPresContext, kidReflowDesiredSize, aReflowState.mComputedBorderPadding.left,
aReflowState.mComputedBorderPadding.top, 0);
aStatus = NS_FRAME_COMPLETE;
@@ -791,6 +1098,23 @@ nsGfxTextControlFrame2::GetType(PRInt32* aType) const
return rv;
}
+nsresult
+nsGfxTextControlFrame2::GetSizeFromContent(PRInt32* aSize) const
+{
+ *aSize = -1;
+ nsresult result = NS_CONTENT_ATTR_NOT_THERE;
+ nsIHTMLContent* content = nsnull;
+ mContent->QueryInterface(kIHTMLContentIID, (void**) &content);
+ if (nsnull != content) {
+ nsHTMLValue value;
+ result = content->GetHTMLAttribute(nsHTMLAtoms::size, value);
+ if (eHTMLUnit_Integer == value.GetUnit()) {
+ *aSize = value.GetIntValue();
+ }
+ NS_RELEASE(content);
+ }
+ return result;
+}
void nsGfxTextControlFrame2::SetFocus(PRBool aOn , PRBool aRepaint){}
void nsGfxTextControlFrame2::ScrollIntoView(nsIPresContext* aPresContext){}
@@ -843,6 +1167,8 @@ nsGfxTextControlFrame2::IsSuccessful(nsIFormControlFrame* aSubmitter)
NS_IMETHODIMP
nsGfxTextControlFrame2::SetSuggestedSize(nscoord aWidth, nscoord aHeight)
{
+ mSuggestedWidth = aWidth;
+ mSuggestedHeight = aHeight;
return NS_OK;
}
@@ -1281,6 +1607,18 @@ nsGfxTextControlFrame2::SetInitialChildList(nsIPresContext* aPresContext,
//look for scroll view below this frame go along first child list
nsIFrame *first;
FirstChild(aPresContext,nsnull, &first);
+
+//we must turn off scrollbars for singleline text controls
+ PRInt32 type;
+ GetType(&type);
+ if ((NS_FORM_INPUT_TEXT == type) || (NS_FORM_INPUT_PASSWORD == type))
+ {
+ nsIScrollableFrame *scrollableFrame = nsnull;
+ if (first)
+ first->QueryInterface(NS_GET_IID(nsIScrollableFrame), (void **) &scrollableFrame);
+ if (scrollableFrame)
+ scrollableFrame->SetScrollbarVisibility(aPresContext,PR_FALSE,PR_FALSE);
+ }
while(first)
{
nsIScrollableView *scrollView;
diff --git a/layout/html/forms/src/nsGfxTextControlFrame2.h b/layout/html/forms/src/nsGfxTextControlFrame2.h
index eb616dd2ef19..04c585061235 100644
--- a/layout/html/forms/src/nsGfxTextControlFrame2.h
+++ b/layout/html/forms/src/nsGfxTextControlFrame2.h
@@ -30,7 +30,9 @@
#include "nsIStatefulFrame.h"
#include "nsIEditor.h"
#include "nsIGfxTextControlFrame.h"
-
+#include "nsFormControlHelper.h"//for the inputdimensions
+#include "nsHTMLValue.h" //for nsHTMLValue
+#include "nsIFontMetrics.h"
class nsIPresState;
class nsGfxTextControlFrame;
@@ -139,6 +141,37 @@ protected:
virtual PRBool IsSingleLineTextControl() const;
virtual PRBool IsPlainTextControl() const;
virtual PRBool IsPasswordTextControl() const;
+ nsresult GetSizeFromContent(PRInt32* aSize) const;
+ PRInt32 GetDefaultColumnWidth() const { return (PRInt32)(20); } // this was DEFAULT_PIXEL_WIDTH
+
+ nsresult GetColRowSizeAttr(nsIFormControlFrame* aFrame,
+ nsIAtom * aColSizeAttr,
+ nsHTMLValue & aColSize,
+ nsresult & aColStatus,
+ nsIAtom * aRowSizeAttr,
+ nsHTMLValue & aRowSize,
+ nsresult & aRowStatus);
+
+ NS_IMETHOD ReflowStandard(nsIPresContext* aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ const nsHTMLReflowState& aReflowState,
+ nsReflowStatus& aStatus,
+ nsMargin& aBorder,
+ nsMargin& aPadding);
+
+ PRInt32 CalculateSizeStandard (nsIPresContext* aPresContext,
+ nsIRenderingContext* aRendContext,
+ nsIFormControlFrame* aFrame,
+ const nsSize& aCSSSize,
+ nsInputDimensionSpec& aSpec,
+ nsSize& aDesiredSize,
+ nsSize& aMinSize,
+ PRBool& aWidthExplicit,
+ PRBool& aHeightExplicit,
+ nscoord& aRowHeight,
+ nsMargin& aBorder,
+ nsMargin& aPadding);
+
NS_IMETHOD CreateFrameFor(nsIPresContext* aPresContext,
nsIContent * aContent,
@@ -149,7 +182,12 @@ protected:
private:
nsCOMPtr mEditor;
nsCOMPtr mSelCon;
- nsString *mCachedState;
+
+ //cached sizes and states
+ nsString* mCachedState;
+ nscoord mSuggestedWidth;
+ nscoord mSuggestedHeight;
+
PRBool mIsProcessing;
nsFormFrame *mFormFrame;
nsTextAreaSelectionImpl *mTextSelImpl;