diff --git a/mozilla/layout/forms/nsComboboxControlFrame.cpp b/mozilla/layout/forms/nsComboboxControlFrame.cpp index d12709f7f36..062ca5fd144 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.cpp +++ b/mozilla/layout/forms/nsComboboxControlFrame.cpp @@ -132,6 +132,8 @@ nsComboboxControlFrame::~nsComboboxControlFrame() NS_IF_RELEASE(mPresContext); NS_IF_RELEASE(mDisplayContent); NS_IF_RELEASE(mButtonContent); + + nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); } //-------------------------------------------------------------- @@ -265,9 +267,7 @@ nsComboboxControlFrame::Reset(nsIPresContext* aPresContext) } void -nsComboboxControlFrame::PostCreateWidget(nsIPresContext* aPresContext, - nscoord& aWidth, - nscoord& aHeight) +nsComboboxControlFrame::InitializeControl(nsIPresContext* aPresContext) { Reset(aPresContext); } @@ -724,6 +724,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*,this)); } @@ -912,6 +913,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, #else // DO_OLD_REFLOW #ifdef DEBUG_rods +nsComboboxControlFrame * pCB = nsnull; static int myCounter = 0; #endif @@ -922,7 +924,8 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, nsReflowStatus& aStatus) { #ifdef DEBUG_rods - printf("****** nsComboboxControlFrame::Reflow %d Reason: ", myCounter++); + //if (pCB) { + printf("%p ****** nsComboboxControlFrame::Reflow %d Reason: ", this, myCounter++); switch (aReflowState.reason) { case eReflowReason_Initial: printf("eReflowReason_Initial\n");break; @@ -933,6 +936,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, break; case eReflowReason_StyleChange:printf("eReflowReason_StyleChange\n");break; } + //} #endif #if 0 @@ -993,7 +997,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, // but it does seems to go into this code. } else { if (targetFrame != dropdownFrame) { +#ifdef DEBUG_rods printf("+++++++++++++++++++++++\n"); +#endif rv = nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); displayFrame->GetRect(displayRect); buttonFrame->GetRect(buttonRect); @@ -1001,14 +1007,34 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, buttonRect.height = displayRect.height; buttonFrame->SetRect(aPresContext, buttonRect); aStatus = NS_FRAME_COMPLETE; +#ifdef DEBUG_rods printf("--> W: %d H: %d\n", aDesiredSize.width, aDesiredSize.height); +#endif return rv; } else { #if 0 + nsRect dropdownRect; + dropdownFrame->GetRect(dropdownRect); nsHTMLReflowMetrics dropdownDesiredSize(aDesiredSize); ReflowComboChildFrame(dropdownFrame, aPresContext, dropdownDesiredSize, firstPassState, - aStatus, firstPassState.availableWidth, firstPassState.availableHeight); - return NS_OK; + aStatus, dropdownRect.width, dropdownRect.height); + nsCOMPtr context; + targetFrame->GetStyleContext(getter_AddRefs(context)); + const nsStyleDisplay* disp = (const nsStyleDisplay*)context->GetStyleData(eStyleStruct_Display); + printf("IsVisible %s\n", disp->mVisible == NS_STYLE_VISIBILITY_VISIBLE?"yes":"No"); + //if (disp->mVisible == NS_STYLE_VISIBILITY_VISIBLE) { + nsRect rect; + GetRect(rect); + aDesiredSize.width = rect.width;// + borderPadding.left + borderPadding.right; + aDesiredSize.height = rect.height;// + borderPadding.top + borderPadding.bottom; + aDesiredSize.ascent = aDesiredSize.height; + aDesiredSize.descent = 0; + dropdownRect.width = rect.width; + dropdownFrame->SetRect(aPresContext, dropdownRect); + printf("Skipping out.........................."); + aStatus = NS_FRAME_COMPLETE; + return NS_OK; + //} #endif } } @@ -1035,10 +1061,15 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, dx->GetCanonicalPixelScale(scale); scrollbarWidth = NSIntPixelsToTwips(info.mSize, p2t*scale); } +#ifdef DEBUG_rods printf("UNC %d AV %d \n", firstPassState.mComputedWidth,firstPassState.availableWidth); +#endif //Set the desired size for the button and display frame if (NS_UNCONSTRAINEDSIZE == firstPassState.mComputedWidth) { +#ifdef DEBUG_rods printf("=====================================\n"); +#endif + // A width has not been specified for the select so size the display area to // match the width of the longest item in the drop-down list. The dropdown // list has already been reflowed and sized to shrink around its contents above. @@ -1077,7 +1108,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, dspBorderPadding.SizeTo(0, 0, 0, 0); dspSpacing->CalcBorderPaddingFor(displayFrame, dspBorderPadding); +#ifdef DEBUG_rods printf("W: %d\n", dropdownRect.width-size.width+dspBorderPadding.left+dspBorderPadding.right); +#endif // Set width of display to match width of the drop down SetChildFrameSize(displayFrame, dropdownRect.width-size.width+dspBorderPadding.left+dspBorderPadding.right, size.height+dspBorderPadding.top+dspBorderPadding.bottom); @@ -1103,7 +1136,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, } } else { +#ifdef DEBUG_rods printf("*************************************\n"); +#endif // for debug ------- PRInt32 length = 0; mListControlFrame->GetNumberOfOptions(&length); @@ -1129,7 +1164,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, // nsAreaFrame::Reflow adds in the border and padding so we need to remove it //displayWidth -= borderPadding.left + borderPadding.right; +#ifdef DEBUG_rods printf("WW: %d\n", displayWidth); +#endif // Set the displayFrame to match the displayWidth computed above if (displayWidth >= 0) { SetChildFrameSize(displayFrame, displayWidth, size.height); @@ -1146,7 +1183,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, buttonRect.height = displayRect.height; buttonFrame->SetRect(aPresContext, buttonRect); displayFrame->SetRect(aPresContext, displayRect); +#ifdef DEBUG_rods printf("DW: %d\n", aDesiredSize.width); +#endif // nsAreaFrame::Reflow adds in the border and padding so we need to remove it // XXX rods - this hould not be subtracted in //aDesiredSize.width += borderPadding.left + borderPadding.right; @@ -1156,6 +1195,8 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, } aDesiredSize.width = firstPassState.mComputedWidth + borderPadding.left + borderPadding.right; aDesiredSize.height = firstPassState.mComputedHeight + borderPadding.top + borderPadding.bottom; + aDesiredSize.ascent = aDesiredSize.height; + aDesiredSize.descent = 0; } // Set the max element size to be the same as the desired element size. @@ -1164,18 +1205,15 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.maxElementSize->height = aDesiredSize.height; } - nsRect absoluteTwips; - nsRect absolutePixels; - GetAbsoluteFramePosition(aPresContext, this, absoluteTwips, absolutePixels); - PositionDropdown(aPresContext, aDesiredSize.height, absoluteTwips, absolutePixels); - aStatus = NS_FRAME_COMPLETE; #if 0 COMPARE_QUIRK_SIZE("nsComboboxControlFrame", 127, 22) #endif nsFormControlFrame::SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize); +#ifdef DEBUG_rods printf("--> W: %d H: %d\n", aDesiredSize.width, aDesiredSize.height); +#endif return rv; } @@ -1422,6 +1460,7 @@ nsComboboxControlFrame::SelectionChanged() } if (shouldSetValue) { rv = htmlContent->SetHTMLAttribute(nsHTMLAtoms::value, mTextStr, PR_TRUE); +#if 1 if (NS_SUCCEEDED(rv)) { nsIFrame* displayFrame = GetDisplayFrame(mPresContext); @@ -1439,6 +1478,15 @@ nsComboboxControlFrame::SelectionChanged() NS_RELEASE(cmd); } } +#else + if (mParent) { + nsCOMPtr shell; + rv = mPresContext->GetShell(getter_AddRefs(shell)); + mState |= NS_FRAME_IS_DIRTY; + mParent->ReflowDirtyChild(shell, (nsIFrame*) this); + } + +#endif } } } @@ -1467,12 +1515,19 @@ nsComboboxControlFrame::DoneAddingContent(PRBool aIsDone) NS_IMETHODIMP nsComboboxControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex) { +#ifdef DEBUG_rodsXXX + if (!pCB) pCB = this; +#endif + nsISelectControlFrame* listFrame = nsnull; nsIFrame* dropdownFrame = GetDropdownFrame(); nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame), (void**)&listFrame); if (NS_SUCCEEDED(rv) && listFrame) { rv = listFrame->AddOption(aPresContext, aIndex); + PRInt32 index; + mListControlFrame->GetSelectedIndex(&index); + UpdateSelection(PR_FALSE, PR_TRUE, index); NS_RELEASE(listFrame); } // If we added the first option, we might need to select it. diff --git a/mozilla/layout/forms/nsComboboxControlFrame.h b/mozilla/layout/forms/nsComboboxControlFrame.h index 781bfab81e3..4359a810c32 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.h +++ b/mozilla/layout/forms/nsComboboxControlFrame.h @@ -35,8 +35,6 @@ #include "nsIRollupListener.h" #include "nsIPresState.h" -class nsButtonControlFrame; -class nsTextControlFrame; class nsFormFrame; class nsIView; class nsStyleContext; @@ -109,9 +107,7 @@ public: NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue); void SetFocus(PRBool aOn, PRBool aRepaint); void ScrollIntoView(nsIPresContext* aPresContext); - virtual void PostCreateWidget(nsIPresContext* aPresContext, - nscoord& aWidth, - nscoord& aHeight); + virtual void InitializeControl(nsIPresContext* aPresContext); virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter); virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; } virtual void Reset(nsIPresContext* aPresContext); diff --git a/mozilla/layout/forms/nsFileControlFrame.cpp b/mozilla/layout/forms/nsFileControlFrame.cpp index 3bf49fa1a11..e7940b39b3d 100644 --- a/mozilla/layout/forms/nsFileControlFrame.cpp +++ b/mozilla/layout/forms/nsFileControlFrame.cpp @@ -22,9 +22,7 @@ #include "nsFileControlFrame.h" #include "nsFormFrame.h" -#include "nsButtonControlFrame.h" -#include "nsTextControlFrame.h" -#include "nsNativeTextControlFrame.h" // XXX: remove when frame construction is done properly +#include "nsGfxTextControlFrame.h" #include "nsIContent.h" #include "prtypes.h" #include "nsIAtom.h" @@ -312,7 +310,7 @@ nsFileControlFrame::SetInitialChildList(nsIPresContext* aPresContext, * frame constuctor create the frame and its implementation. So we are given the text * node from the constructor and we find it in our tree. */ -nsTextControlFrame* +nsGfxTextControlFrame* nsFileControlFrame::GetTextControlFrame(nsIPresContext* aPresContext, nsIFrame* aStart) { // find the text control frame. @@ -331,13 +329,13 @@ nsFileControlFrame::GetTextControlFrame(nsIPresContext* aPresContext, nsIFrame* value.ToUpperCase(); nsString txt("TEXT"); if (value == txt) { - return (nsTextControlFrame*)childFrame; + return (nsGfxTextControlFrame*)childFrame; } } } // if not continue looking - nsTextControlFrame* frame = GetTextControlFrame(aPresContext, childFrame); + nsGfxTextControlFrame* frame = GetTextControlFrame(aPresContext, childFrame); if (frame) return frame; diff --git a/mozilla/layout/forms/nsFileControlFrame.h b/mozilla/layout/forms/nsFileControlFrame.h index c90cf974c43..6f2b9260d63 100644 --- a/mozilla/layout/forms/nsFileControlFrame.h +++ b/mozilla/layout/forms/nsFileControlFrame.h @@ -30,8 +30,7 @@ #include "nsIStatefulFrame.h" class nsIPresState; -class nsButtonControlFrame; -class nsTextControlFrame; +class nsGfxTextControlFrame; class nsFormFrame; class nsISupportsArray; class nsIHTMLContent; @@ -176,7 +175,7 @@ protected: virtual PRIntn GetSkipSides() const; - nsTextControlFrame* mTextFrame; + nsGfxTextControlFrame* mTextFrame; nsFormFrame* mFormFrame; nsIHTMLContent* mTextContent; nsString* mCachedState; @@ -184,7 +183,7 @@ protected: nsIPresContext* mPresContext; // weak reference private: - nsTextControlFrame* GetTextControlFrame(nsIPresContext* aPresContext, + nsGfxTextControlFrame* GetTextControlFrame(nsIPresContext* aPresContext, nsIFrame* aStart); NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; } diff --git a/mozilla/layout/forms/nsFormControlFrame.cpp b/mozilla/layout/forms/nsFormControlFrame.cpp index 8017cca428c..dba52d5f230 100644 --- a/mozilla/layout/forms/nsFormControlFrame.cpp +++ b/mozilla/layout/forms/nsFormControlFrame.cpp @@ -54,6 +54,11 @@ #include "nsStyleUtil.h" #include "nsINameSpaceManager.h" #include "nsIDOMHTMLInputElement.h" +#include "nsIDOMHTMLLabelElement.h" +#include "nsIDOMHTMLTextAreaElement.h" +#include "nsIDOMHTMLLegendElement.h" +#include "nsIDOMHTMLButtonElement.h" +#include "nsIEventStateManager.h" static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID); @@ -87,6 +92,7 @@ nsFormControlFrame::~nsFormControlFrame() mFormFrame->RemoveRadioControlFrame(this); mFormFrame = nsnull; } + RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); } // Frames are not refcounted, no need to AddRef @@ -302,42 +308,29 @@ nsFormControlFrame::Reflow(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { + if (!mDidInit) { + mPresContext = aPresContext; + InitializeControl(aPresContext); + mDidInit = PR_TRUE; + } + // add ourself as an nsIFormControlFrame if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this)); } + nsresult skiprv = SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext, aDesiredSize, aReflowState, aStatus); if (NS_SUCCEEDED(skiprv)) { return skiprv; } - nsWidgetRendering mode; - aPresContext->GetWidgetRenderingMode(&mode); - if (eWidgetRendering_Native == mode) { - GetDesiredSize(aPresContext, aReflowState, aDesiredSize, mWidgetSize); - - if (!mDidInit) { - PostCreateWidget(aPresContext, aDesiredSize.width, aDesiredSize.height); - mDidInit = PR_TRUE; - } - aDesiredSize.ascent = aDesiredSize.height; - aDesiredSize.descent = 0; - - } else { - nsresult rv = nsLeafFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); - if (!mDidInit) { - //GetDesiredSize(aPresContext, aReflowState, aDesiredSize); - PostCreateWidget(aPresContext, aDesiredSize.width, aDesiredSize.height); - mDidInit = PR_TRUE; - } - return rv; - } + nsresult rv = nsLeafFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); aStatus = NS_FRAME_COMPLETE; SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize); - return NS_OK; + return rv; } @@ -347,9 +340,72 @@ nsFormControlFrame::GetWidgetInitData(nsIPresContext* aPresContext) return nsnull; } -void -nsFormControlFrame::PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWidth, nscoord& aHeight) + +nsresult +nsFormControlFrame::RegUnRegAccessKey(nsIPresContext* aPresContext, nsIFrame * aFrame, PRBool aDoReg) { +#if 0 + NS_ASSERTION(aPresContext, "aPresContext is NULL in RegUnRegAccessKey!"); + NS_ASSERTION(aFrame, "aFrame is NULL in RegUnRegAccessKey!"); + + nsresult rv = NS_ERROR_FAILURE; + nsAutoString accessKey; + + if (aFrame != nsnull) { + nsCOMPtr content; + if (NS_SUCCEEDED(aFrame->GetContent(getter_AddRefs(content)))) { +#if 1 + PRInt32 nameSpaceID; + content->GetNameSpaceID(nameSpaceID); + nsAutoString resultValue; + rv = content->GetAttribute(nameSpaceID, nsHTMLAtoms::accesskey, accessKey); +#else + nsCOMPtr inputElement(do_QueryInterface(content)); + if (inputElement) { + rv = inputElement->GetAccessKey(accessKey); + } else { + nsCOMPtr textarea(do_QueryInterface(content)); + if (textarea) { + rv = textarea->GetAccessKey(accessKey); + } else { + nsCOMPtr label(do_QueryInterface(content)); + if (label) { + rv = label->GetAccessKey(accessKey); + } else { + nsCOMPtr legend(do_QueryInterface(content)); + if (legend) { + rv = legend->GetAccessKey(accessKey); + } else { + nsCOMPtr btn(do_QueryInterface(content)); + if (btn) { + rv = btn->GetAccessKey(accessKey); + } + } + } + } + } +#endif + } + } + + if (NS_CONTENT_ATTR_NOT_THERE != rv) { + nsCOMPtr stateManager; + if (NS_SUCCEEDED(aPresContext->GetEventStateManager(getter_AddRefs(stateManager)))) { + if (aDoReg) { + return stateManager->RegisterAccessKey(aFrame, (PRUint32)accessKey.First()); + } else { + return stateManager->UnregisterAccessKey(aFrame); + } + } + } +#endif + return NS_ERROR_FAILURE; +} + +void +nsFormControlFrame::InitializeControl(nsIPresContext* aPresContext) +{ + RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); } void diff --git a/mozilla/layout/forms/nsFormControlFrame.h b/mozilla/layout/forms/nsFormControlFrame.h index 23fd9988058..f5b8a139f4b 100644 --- a/mozilla/layout/forms/nsFormControlFrame.h +++ b/mozilla/layout/forms/nsFormControlFrame.h @@ -31,11 +31,14 @@ #include "nsLeafFrame.h" #include "nsCoord.h" #include "nsIStyleContext.h" +#include "nsIPresContext.h" +#include "nsCOMPtr.h" class nsIView; class nsIPresContext; class nsStyleCoord; class nsFormFrame; +class nsIFocusableContent; #define CSS_NOTSET -1 #define ATTR_NOTSET -1 @@ -152,11 +155,9 @@ public: virtual void ControlChanged(nsIPresContext* aPresContext) {} /** - * Perform opertations after the widget associated with this frame has been - * created. + * Chance to Initialize to a defualt value */ - virtual void PostCreateWidget(nsIPresContext* aPresContext, - nscoord& aWidth, nscoord& aHeight); + virtual void InitializeControl(nsIPresContext* aPresContext); virtual void SetFocus(PRBool aOn = PR_TRUE, PRBool aRepaint = PR_FALSE); virtual void ScrollIntoView(nsIPresContext* aPresContext); @@ -221,6 +222,8 @@ public: nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus); + // AccessKey Helper function + static nsresult RegUnRegAccessKey(nsIPresContext* aPresContext, nsIFrame * aFrame, PRBool aDoReg); protected: @@ -301,6 +304,8 @@ protected: nscoord mSuggestedWidth; nscoord mSuggestedHeight; + nsCOMPtr mPresContext; + // Reflow Optimization nsSize mCacheSize; nsSize mCachedMaxElementSize; diff --git a/mozilla/layout/forms/nsFormControlHelper.cpp b/mozilla/layout/forms/nsFormControlHelper.cpp index bb3614c0055..dc24f6195e7 100644 --- a/mozilla/layout/forms/nsFormControlHelper.cpp +++ b/mozilla/layout/forms/nsFormControlHelper.cpp @@ -453,7 +453,7 @@ nsFormControlHelper::CalculateSize (nsIPresContext* aPresContext, // need to set charWidth and aDesiredSize.height charWidth = GetTextSize(aPresContext, aFrame, 1, aDesiredSize, aRendContext); col = (col <= 0) ? 15 : col; // XXX why a default of 15 pixels, why hide it - // XXX this conflicts with a default of 20 found in nsTextControlFrame. + // XXX this conflicts with a default of 20 found in nsGfxTextControlFrame. aDesiredSize.width = NSIntPixelsToTwips(col, p2t); } else { col = (col <= 0) ? 1 : col; // XXX why a default of 1 char, why hide it diff --git a/mozilla/layout/forms/nsGfxButtonControlFrame.cpp b/mozilla/layout/forms/nsGfxButtonControlFrame.cpp index adbea904cac..653af3cc93c 100644 --- a/mozilla/layout/forms/nsGfxButtonControlFrame.cpp +++ b/mozilla/layout/forms/nsGfxButtonControlFrame.cpp @@ -332,7 +332,7 @@ nsGfxButtonControlFrame::Reflow(nsIPresContext* aPresContext, nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this)); } -#if 1 +#if 0 nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext, aDesiredSize, aReflowState, aStatus); @@ -362,6 +362,12 @@ nsGfxButtonControlFrame::Reflow(nsIPresContext* aPresContext, aPresContext->GetCompatibilityMode(&mode); if (mode == eCompatibility_NavQuirks) { + // nsHTMLButtonControlFrame::Reflow registers it for Standard Mode + // and sets up mPresContext + if (eReflowReason_Initial == aReflowState.reason) { + mPresContext = aPresContext; + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); + } // Do NavQuirks Sizing and layout rv = DoNavQuirksReflow(aPresContext, aDesiredSize, aReflowState, aStatus); } else { diff --git a/mozilla/layout/forms/nsGfxCheckboxControlFrame.cpp b/mozilla/layout/forms/nsGfxCheckboxControlFrame.cpp index 135aaa523b0..423eac39b71 100644 --- a/mozilla/layout/forms/nsGfxCheckboxControlFrame.cpp +++ b/mozilla/layout/forms/nsGfxCheckboxControlFrame.cpp @@ -27,9 +27,12 @@ #include "nsFormFrame.h" #include "nsIFormControl.h" #include "nsIContent.h" -#include "nsWidgetsCID.h" #include "nsIComponentManager.h" +#include "nsHTMLAtoms.h" +#include "nsINameSpaceManager.h" +#include "nsIPresState.h" +//------------------------------------------------------------ nsresult NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) { @@ -46,18 +49,156 @@ NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) } +//------------------------------------------------------------ // Initialize GFX-rendered state nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame() : mChecked(eOff) { } +//---------------------------------------------------------------------- +// nsISupports +//---------------------------------------------------------------------- +// Frames are not refcounted, no need to AddRef +NS_IMETHODIMP +nsGfxCheckboxControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) +{ + NS_ASSERTION(aInstancePtr, "QueryInterface requires a non-NULL destination!"); + if ( !aInstancePtr ) + return NS_ERROR_NULL_POINTER; + if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void*)(nsIStatefulFrame*) this; + return NS_OK; + } + return nsFormControlFrame::QueryInterface(aIID, aInstancePtr); +} +//------------------------------------------------------------ +// +// Init +// +// We need to override this in order to see if we're a tristate checkbox. +// +NS_IMETHODIMP +nsGfxCheckboxControlFrame::Init(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aContext, + nsIFrame* aPrevInFlow) +{ + nsFormControlFrame::Init ( aPresContext, aContent, aParent, aContext, aPrevInFlow ); + + // figure out if we're a tristate at the start. This may change later on once + // we've been running for a while, so more code is in AttributeChanged() to pick + // that up. Regardless, we need this check when initializing. + nsAutoString value; + nsresult res = mContent->GetAttribute ( kNameSpaceID_None, GetTristateAtom(), value ); + if ( res == NS_CONTENT_ATTR_HAS_VALUE ) + mIsTristate = PR_TRUE; + + // give the attribute a default value so it's always present, if we're a tristate + if ( IsTristateCheckbox() ) + mContent->SetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), "0", PR_FALSE ); + + return NS_OK; +} + +//------------------------------------------------------------ +// +// GetTristateAtom [static] +// +// Use a lazily instantiated static initialization scheme to create an atom that +// represents the attribute set when this should be a tri-state checkbox. +// +// Does NOT addref! +// +nsIAtom* +nsGfxCheckboxControlFrame :: GetTristateAtom ( ) +{ + return nsHTMLAtoms::moz_tristate; +} + +//------------------------------------------------------------ +// +// GetTristateValueAtom [static] +// +// Use a lazily instantiated static initialization scheme to create an atom that +// represents the attribute that holds the value when the button is a tri-state (since +// we can't use "checked"). +// +// Does NOT addref! +// +nsIAtom* +nsGfxCheckboxControlFrame :: GetTristateValueAtom ( ) +{ + return nsHTMLAtoms::moz_tristatevalue; +} + +//------------------------------------------------------------ +// +// AttributeChanged +// +// Override to check for the attribute that determines if we're a normal or a +// tristate checkbox. If we notice a switch from one to the other, we need +// to adjust the proper attributes in the content model accordingly. +// +// Also, since the value of a tri-state is kept in a separate attribute (we +// can't use "checked" because it's a boolean), we have to notice it changing +// here. +// +NS_IMETHODIMP +nsGfxCheckboxControlFrame::AttributeChanged(nsIPresContext* aPresContext, + nsIContent* aChild, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aHint) +{ + if ( aAttribute == GetTristateAtom() ) { + nsAutoString value; + nsresult res = mContent->GetAttribute ( kNameSpaceID_None, GetTristateAtom(), value ); + PRBool isNowTristate = (res == NS_CONTENT_ATTR_HAS_VALUE); + if ( isNowTristate != mIsTristate ) + SwitchModesWithEmergencyBrake(aPresContext, isNowTristate); + } + else if ( aAttribute == GetTristateValueAtom() ) { + // ignore this change if we're not a tri-state checkbox + if ( IsTristateCheckbox() ) { + nsAutoString value; + nsresult res = mContent->GetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), value ); + if ( res == NS_CONTENT_ATTR_HAS_VALUE ) + SetCheckboxControlFrameState(aPresContext, value); + } + } + else + return nsFormControlFrame::AttributeChanged(aPresContext, aChild, aNameSpaceID, aAttribute, aHint); + + return NS_OK; +} + +//------------------------------------------------------------ +// +// InitializeControl +// +// Set the default checked state of the checkbox. +// +void +nsGfxCheckboxControlFrame::InitializeControl(nsIPresContext* aPresContext) +{ + nsFormControlFrame::InitializeControl(aPresContext); + + PRBool checked = PR_FALSE; + nsresult result = GetDefaultCheckState(&checked); + if (NS_CONTENT_ATTR_HAS_VALUE == result) { + SetCheckboxState (aPresContext, checked ? eOn : eOff ); + } +} + +//------------------------------------------------------------ void nsGfxCheckboxControlFrame::PaintCheckBox(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsFramePaintLayer aWhichLayer) + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) { aRenderingContext.PushState(); @@ -111,6 +252,7 @@ nsGfxCheckboxControlFrame::PaintCheckBox(nsIPresContext* aPresContext, } +//------------------------------------------------------------ // // PaintMixedMark // @@ -155,6 +297,7 @@ nsGfxCheckboxControlFrame::PaintMixedMark ( nsIRenderingContext& aRenderingConte } // PaintMixedMark +//------------------------------------------------------------ NS_METHOD nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -167,7 +310,7 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext, return NS_OK; // Paint the background - Inherited::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { // Paint the checkmark PaintCheckBox(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); @@ -176,20 +319,232 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext, } -nsCheckboxControlFrame::CheckState -nsGfxCheckboxControlFrame :: GetCheckboxState ( ) +//------------------------------------------------------------ +nsGfxCheckboxControlFrame::CheckState +nsGfxCheckboxControlFrame::GetCheckboxState ( ) { return mChecked; } +//------------------------------------------------------------ void -nsGfxCheckboxControlFrame :: SetCheckboxState (nsIPresContext* aPresContext, - nsCheckboxControlFrame::CheckState aValue ) +nsGfxCheckboxControlFrame::SetCheckboxState (nsIPresContext* aPresContext, + nsGfxCheckboxControlFrame::CheckState aValue ) { mChecked = aValue; nsFormControlHelper::ForceDrawFrame(aPresContext, this); } +//------------------------------------------------------------ +void nsGfxCheckboxControlFrame::GetCheckboxControlFrameState(nsString& aValue) +{ + CheckStateToString(GetCheckboxState(), aValue); +} + + +//------------------------------------------------------------ +void nsGfxCheckboxControlFrame::SetCheckboxControlFrameState(nsIPresContext* aPresContext, + const nsString& aValue) +{ + CheckState state = StringToCheckState(aValue); + SetCheckboxState(aPresContext, state); +} + +//------------------------------------------------------------ +NS_IMETHODIMP nsGfxCheckboxControlFrame::SetProperty(nsIPresContext* aPresContext, + nsIAtom* aName, + const nsString& aValue) +{ + if (nsHTMLAtoms::checked == aName) + SetCheckboxControlFrameState(aPresContext, aValue); + else + return nsFormControlFrame::SetProperty(aPresContext, aName, aValue); + + return NS_OK; +} + + +//------------------------------------------------------------ +NS_IMETHODIMP nsGfxCheckboxControlFrame::GetProperty(nsIAtom* aName, nsString& aValue) +{ + if (nsHTMLAtoms::checked == aName) + GetCheckboxControlFrameState(aValue); + else + return nsFormControlFrame::GetProperty(aName, aValue); + + return NS_OK; +} + +//------------------------------------------------------------ +PRInt32 +nsGfxCheckboxControlFrame::GetMaxNumValues() +{ + return 1; +} + +//------------------------------------------------------------ +PRBool +nsGfxCheckboxControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, + nsString* aValues, nsString* aNames) +{ + nsAutoString name; + nsresult nameResult = GetName(&name); + if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_HAS_VALUE != nameResult)) { + return PR_FALSE; + } + + PRBool result = PR_TRUE; + CheckState state = GetCheckboxState(); + + nsAutoString value; + nsresult valueResult = GetValue(&value); + + if (eOn != state) { + result = PR_FALSE; + } else { + if (NS_CONTENT_ATTR_HAS_VALUE != valueResult) { + aValues[0] = "on"; + } else { + aValues[0] = value; + } + aNames[0] = name; + aNumValues = 1; + } + + return result; +} + +//------------------------------------------------------------ +void +nsGfxCheckboxControlFrame::Reset(nsIPresContext* aPresContext) +{ + PRBool checked; + GetDefaultCheckState(&checked); + SetCheckboxState (aPresContext, checked ? eOn : eOff ); +} + + +//------------------------------------------------------------ +// +// CheckStateToString +// +// Converts from a CheckState to a string +// +void +nsGfxCheckboxControlFrame::CheckStateToString ( CheckState inState, nsString& outStateAsString ) +{ + switch ( inState ) { + case eOn: + outStateAsString = NS_STRING_TRUE; + break; + + case eOff: + outStateAsString = NS_STRING_FALSE; + break; + + case eMixed: + outStateAsString = "2"; + break; + } +} // CheckStateToString + + +//------------------------------------------------------------ +// +// StringToCheckState +// +// Converts from a string to a CheckState enum +// +nsGfxCheckboxControlFrame::CheckState +nsGfxCheckboxControlFrame::StringToCheckState ( const nsString & aStateAsString ) +{ + if ( aStateAsString == NS_STRING_TRUE ) + return eOn; + else if ( aStateAsString == NS_STRING_FALSE ) + return eOff; + + // not true and not false means mixed + return eMixed; + +} // StringToCheckState + + +//------------------------------------------------------------ +// +// SwitchModesWithEmergencyBrake +// +// Since we use an attribute to decide if we're a tristate box or not, this can change +// at any time. Since we have to use separate attributes to store the values depending +// on the mode, we have to convert from one to the other. +// +void +nsGfxCheckboxControlFrame::SwitchModesWithEmergencyBrake ( nsIPresContext* aPresContext, + PRBool inIsNowTristate ) +{ + if ( inIsNowTristate ) { + // we were a normal checkbox, and now we're a tristate. That means that the + // state of the checkbox was in "checked" and needs to be copied over into + // our parallel attribute. + nsAutoString value; + CheckStateToString ( GetCheckboxState(), value ); + mContent->SetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), value, PR_FALSE ); + } + else { + // we were a tri-state checkbox, and now we're a normal checkbox. The current + // state is already up to date (because it's always up to date). We just have + // to make sure it's not mixed. If it is, just set it to checked. Remove our + // parallel attribute so that we're nice and HTML4 compliant. + if ( GetCheckboxState() == eMixed ) + SetCheckboxState(aPresContext, eOn); + mContent->UnsetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), PR_FALSE ); + } + + // switch! + mIsTristate = inIsNowTristate; + +} // SwitchModesWithEmergencyBrake + +//---------------------------------------------------------------------- +// nsIStatefulFrame +//---------------------------------------------------------------------- +NS_IMETHODIMP nsGfxCheckboxControlFrame::GetStateType(nsIPresContext* aPresContext, + nsIStatefulFrame::StateType* aStateType) +{ + *aStateType=nsIStatefulFrame::eCheckboxType; + return NS_OK; +} + +NS_IMETHODIMP nsGfxCheckboxControlFrame::SaveState(nsIPresContext* aPresContext, + nsIPresState** aState) +{ + // Construct a pres state. + NS_NewPresState(aState); // The addref happens here. + + // This string will hold a single item, whether or not we're checked. + nsAutoString stateString; + GetCheckboxControlFrameState(stateString); + (*aState)->SetStateProperty("checked", stateString); + + return NS_OK; +} + +NS_IMETHODIMP nsGfxCheckboxControlFrame::RestoreState(nsIPresContext* aPresContext, + nsIPresState* aState) +{ + if (!mDidInit) { + mPresContext = aPresContext; + InitializeControl(aPresContext); + mDidInit = PR_TRUE; + } + nsAutoString string; + aState->GetStateProperty("checked", string); + SetCheckboxControlFrameState(aPresContext, string); + return NS_OK; +} + +//------------------------------------------------------------ +// Extra Debug Methods +//------------------------------------------------------------ #ifdef DEBUG_rodsXXX NS_IMETHODIMP nsGfxCheckboxControlFrame::Reflow(nsIPresContext* aPresContext, @@ -197,7 +552,7 @@ nsGfxCheckboxControlFrame::Reflow(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { - nsresult rv = nsNativeFormControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); + nsresult rv = nsFormControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); COMPARE_QUIRK_SIZE("nsGfxCheckboxControlFrame", 13, 13) return rv; diff --git a/mozilla/layout/forms/nsGfxCheckboxControlFrame.h b/mozilla/layout/forms/nsGfxCheckboxControlFrame.h index 588deb65d03..c227a02159a 100644 --- a/mozilla/layout/forms/nsGfxCheckboxControlFrame.h +++ b/mozilla/layout/forms/nsGfxCheckboxControlFrame.h @@ -22,13 +22,13 @@ #ifndef nsGfxCheckboxControlFrame_h___ #define nsGfxCheckboxControlFrame_h___ -#include "nsCheckboxControlFrame.h" +#include "nsFormControlFrame.h" +#include "nsIStatefulFrame.h" -class nsGfxCheckboxControlFrame : public nsCheckboxControlFrame { -private: - typedef nsCheckboxControlFrame Inherited; - +class nsGfxCheckboxControlFrame : public nsFormControlFrame, + public nsIStatefulFrame +{ public: nsGfxCheckboxControlFrame(); @@ -37,17 +37,43 @@ public: return MakeFrameName("CheckboxControl", aResult); } #endif + // this should be protected, but VC6 is lame. + enum CheckState { eOff, eOn, eMixed } ; - // overrides base class HandleEvent to do nothing - // events are handled by the DOM - NS_IMETHOD HandleEvent(nsIPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) { return NS_OK; } + NS_IMETHOD Init(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aContext, + nsIFrame* aPrevInFlow) ; + + NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext, + nsIContent* aChild, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aHint) ; NS_IMETHOD Paint(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer); + + void InitializeControl(nsIPresContext* aPresContext); + + // nsIFormControlFrame + NS_IMETHOD SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsString& aValue); + NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue); + virtual void Reset(nsIPresContext* aPresContext); + virtual PRInt32 GetMaxNumValues(); + virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, + nsString* aValues, nsString* aNames); + + // nsIStatefulFrame + NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + NS_IMETHOD GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType); + NS_IMETHOD SaveState(nsIPresContext* aPresContext, nsIPresState** aState); + NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState); + + #ifdef DEBUG_rodsXXX NS_IMETHOD Reflow(nsIPresContext* aCX, nsHTMLReflowMetrics& aDesiredSize, @@ -56,8 +82,35 @@ public: #endif protected: - virtual CheckState GetCheckboxState(); - virtual void SetCheckboxState(nsIPresContext* aPresContext, CheckState aValue); + + // native/gfx implementations need to implement needs. + CheckState GetCheckboxState(); + void SetCheckboxState(nsIPresContext* aPresContext, CheckState aValue); + + // Utility methods for implementing SetProperty/GetProperty + void SetCheckboxControlFrameState(nsIPresContext* aPresContext, + const nsString& aValue); + void GetCheckboxControlFrameState(nsString& aValue); + + // utility routine for converting from DOM values to internal enum + void CheckStateToString ( CheckState inState, nsString& outStateAsString ) ; + CheckState StringToCheckState ( const nsString & aStateAsString ) ; + + // figure out if we're a tri-state checkbox. + PRBool IsTristateCheckbox ( ) const { return mIsTristate; } + + // we just became a tri-state, or we just lost tri-state status. fix up + // the attributes for the new mode. + void SwitchModesWithEmergencyBrake ( nsIPresContext* aPresContext, + PRBool inIsNowTristate ) ; + + // for tri-state checkbox. meaningless for normal HTML + PRBool mIsTristate; + + static nsIAtom* GetTristateAtom() ; + static nsIAtom* GetTristateValueAtom() ; + +protected: virtual void PaintCheckBox(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -68,7 +121,11 @@ protected: //GFX-rendered state variables CheckState mChecked; - + +private: + NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; } + NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; } + }; #endif diff --git a/mozilla/layout/forms/nsGfxRadioControlFrame.cpp b/mozilla/layout/forms/nsGfxRadioControlFrame.cpp index 04073d8cf0e..e005f53b162 100644 --- a/mozilla/layout/forms/nsGfxRadioControlFrame.cpp +++ b/mozilla/layout/forms/nsGfxRadioControlFrame.cpp @@ -21,7 +21,6 @@ */ #include "nsGfxRadioControlFrame.h" -#include "nsIRadioButton.h" #include "nsHTMLAtoms.h" #include "nsHTMLParts.h" #include "nsFormFrame.h" @@ -31,6 +30,8 @@ #include "nsIComponentManager.h" #include "nsCOMPtr.h" #include "nsCSSRendering.h" +#include "nsIPresState.h" +#include "nsINameSpaceManager.h" nsresult @@ -57,11 +58,31 @@ nsGfxRadioControlFrame::nsGfxRadioControlFrame() nsGfxRadioControlFrame::~nsGfxRadioControlFrame() { - NS_IF_RELEASE(mRadioButtonFaceStyle); + NS_IF_RELEASE(mRadioButtonFaceStyle); } -//-------------------------------------------------------------- +// Frames are not refcounted, no need to AddRef +NS_IMETHODIMP +nsGfxRadioControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) +{ + NS_PRECONDITION(0 != aInstancePtr, "null ptr"); + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(NS_GET_IID(nsIRadioControlFrame))) { + *aInstancePtr = (void*) ((nsIRadioControlFrame*) this); + return NS_OK; + } + if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void*) ((nsIStatefulFrame*) this); + return NS_OK; + } + + return nsFormControlFrame::QueryInterface(aIID, aInstancePtr); +} + +//-------------------------------------------------------------- NS_IMETHODIMP nsGfxRadioControlFrame::GetAdditionalStyleContext(PRInt32 aIndex, nsIStyleContext** aStyleContext) const @@ -82,6 +103,7 @@ nsGfxRadioControlFrame::GetAdditionalStyleContext(PRInt32 aIndex, return NS_OK; } +//-------------------------------------------------------------- NS_IMETHODIMP nsGfxRadioControlFrame::SetAdditionalStyleContext(PRInt32 aIndex, nsIStyleContext* aStyleContext) @@ -99,7 +121,69 @@ nsGfxRadioControlFrame::SetAdditionalStyleContext(PRInt32 aIndex, return NS_OK; } +//-------------------------------------------------------------- +NS_IMETHODIMP nsGfxRadioControlFrame::SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsString& aValue) +{ + if (nsHTMLAtoms::checked == aName) { + PRBool state = (aValue == NS_STRING_TRUE) ? PR_TRUE : PR_FALSE; + SetRadioState(aPresContext, state); + if (mFormFrame) { + mFormFrame->OnRadioChecked(aPresContext, *this, state); + } + } + else { + return nsFormControlFrame::SetProperty(aPresContext, aName, aValue); + } + + return NS_OK; +} + +//-------------------------------------------------------------- +NS_IMETHODIMP nsGfxRadioControlFrame::GetProperty(nsIAtom* aName, nsString& aValue) +{ + // Return the value of the property from the widget it is not null. + // If is null, assume the widget is GFX-rendered and return a member variable instead. + + if (nsHTMLAtoms::checked == aName) { + nsFormControlHelper::GetBoolString(GetRadioState(), aValue); + } else { + return nsFormControlFrame::GetProperty(aName, aValue); + } + + return NS_OK; +} + +//-------------------------------------------------------------- +PRBool +nsGfxRadioControlFrame::GetChecked(PRBool aGetInitialValue) +{ + PRBool checked = PR_FALSE; + if (PR_TRUE == aGetInitialValue) { + GetDefaultCheckState(&checked); + } + else { + GetCurrentCheckState(&checked); + } + return(checked); +} + +//-------------------------------------------------------------- +void +nsGfxRadioControlFrame::SetChecked(nsIPresContext* aPresContext, PRBool aValue, PRBool aSetInitialValue) +{ + if (aSetInitialValue) { + if (aValue) { + mContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::checked, nsAutoString("1"), PR_FALSE); // XXX should be "empty" value + } else { + mContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::checked, nsAutoString("0"), PR_FALSE); + } + } + + SetRadioState(aPresContext, aValue); +} + +//-------------------------------------------------------------- NS_IMETHODIMP nsGfxRadioControlFrame::SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioButtonFaceStyleContext) { @@ -108,6 +192,47 @@ nsGfxRadioControlFrame::SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioBu return NS_OK; } +//-------------------------------------------------------------- +PRBool +nsGfxRadioControlFrame::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; + } + + PRBool state = GetRadioState(); + + if(PR_TRUE != state) { + return PR_FALSE; + } + + nsAutoString value; + result = GetValue(&value); + + if (NS_CONTENT_ATTR_HAS_VALUE == result) { + aValues[0] = value; + } else { + aValues[0] = "on"; + } + aNames[0] = name; + aNumValues = 1; + + return PR_TRUE; +} + +//-------------------------------------------------------------- +void +nsGfxRadioControlFrame::Reset(nsIPresContext* aPresContext) +{ + PRBool checked = PR_TRUE; + GetDefaultCheckState(&checked); + SetCurrentCheckState(checked); +} + +//-------------------------------------------------------------- void nsGfxRadioControlFrame::PaintRadioButton(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -141,6 +266,7 @@ nsGfxRadioControlFrame::PaintRadioButton(nsIPresContext* aPresContext, } } +//-------------------------------------------------------------- NS_METHOD nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -153,7 +279,7 @@ nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext, return NS_OK; // Paint the background - Inherited::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { PaintRadioButton(aPresContext, aRenderingContext, aDirtyRect); @@ -162,17 +288,79 @@ nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext, } +//-------------------------------------------------------------- PRBool nsGfxRadioControlFrame::GetRadioState() { return mChecked; } +//-------------------------------------------------------------- void nsGfxRadioControlFrame::SetRadioState(nsIPresContext* aPresContext, PRBool aValue) { mChecked = aValue; nsFormControlHelper::ForceDrawFrame(aPresContext, this); } +void +nsGfxRadioControlFrame::InitializeControl(nsIPresContext* aPresContext) +{ + nsFormControlFrame::InitializeControl(aPresContext); + + // set the widget to the initial state + PRBool checked = PR_FALSE; + nsresult result = GetDefaultCheckState(&checked); + if (NS_CONTENT_ATTR_HAS_VALUE == result) { + SetRadioState(aPresContext, checked); + } +} + +//---------------------------------------------------------------------- +// nsIStatefulFrame +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsGfxRadioControlFrame::GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType) +{ + *aStateType = nsIStatefulFrame::eRadioType; + return NS_OK; +} + +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsGfxRadioControlFrame::SaveState(nsIPresContext* aPresContext, nsIPresState** aState) +{ + // Construct a pres state. + NS_NewPresState(aState); // The addref happens here. + + // This string will hold a single item, whether or not we're checked. + nsAutoString stateString; + nsFormControlHelper::GetBoolString(GetRadioState(), stateString); + (*aState)->SetStateProperty("checked", stateString); + + return NS_OK; +} + + + +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsGfxRadioControlFrame::RestoreState(nsIPresContext* aPresContext, nsIPresState* aState) +{ + if (!mDidInit) { + mPresContext = aPresContext; + InitializeControl(aPresContext); + mDidInit = PR_TRUE; + } + nsAutoString string; + aState->GetStateProperty("checked", string); + PRBool state = (string == NS_STRING_TRUE) ? PR_TRUE : PR_FALSE; + SetRadioState(aPresContext, state); + return NS_OK; +} + + +//---------------------------------------------------------------------- +// Extra Debug Helper Methods +//---------------------------------------------------------------------- #ifdef DEBUG_rodsXXX NS_IMETHODIMP nsGfxRadioControlFrame::Reflow(nsIPresContext* aPresContext, diff --git a/mozilla/layout/forms/nsGfxRadioControlFrame.h b/mozilla/layout/forms/nsGfxRadioControlFrame.h index 73ac07ce117..e40ab27e3f8 100644 --- a/mozilla/layout/forms/nsGfxRadioControlFrame.h +++ b/mozilla/layout/forms/nsGfxRadioControlFrame.h @@ -23,25 +23,36 @@ #ifndef nsGfxRadioControlFrame_h___ #define nsGfxRadioControlFrame_h___ -#include "nsRadioControlFrame.h" +#include "nsFormControlFrame.h" +#include "nsIStatefulFrame.h" +#include "nsIRadioControlFrame.h" // nsGfxRadioControlFrame #define NS_GFX_RADIO_CONTROL_FRAME_FACE_CONTEXT_INDEX 0 // for additional style contexts #define NS_GFX_RADIO_CONTROL_FRAME_LAST_CONTEXT_INDEX 0 -class nsGfxRadioControlFrame : public nsRadioControlFrame +class nsGfxRadioControlFrame : public nsFormControlFrame, + public nsIStatefulFrame, + public nsIRadioControlFrame + { private: - typedef nsRadioControlFrame Inherited; public: nsGfxRadioControlFrame(); ~nsGfxRadioControlFrame(); //nsIRadioControlFrame methods + NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); NS_IMETHOD SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioButtonFaceStyleContext); + + virtual PRBool GetChecked(PRBool aGetInitialValue); + virtual void SetChecked(nsIPresContext* aPresContext, PRBool aValue, PRBool aSetInitialValue); + + void InitializeControl(nsIPresContext* aPresContext); + NS_IMETHOD GetAdditionalStyleContext(PRInt32 aIndex, nsIStyleContext** aStyleContext) const; NS_IMETHOD SetAdditionalStyleContext(PRInt32 aIndex, @@ -67,6 +78,21 @@ public: nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); + virtual PRInt32 GetMaxNumValues() { return 1; } + + virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, + nsString* aValues, nsString* aNames); + virtual void Reset(nsIPresContext* aPresContext); + + // nsIFormControlFrame + NS_IMETHOD SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsString& aValue); + NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue); + + //nsIStatefulFrame + NS_IMETHOD GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType); + NS_IMETHOD SaveState(nsIPresContext* aPresContext, nsIPresState** aState); + NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState); + ///XXX: End o the temporary methods #ifdef DEBUG_rodsXXX NS_IMETHOD Reflow(nsIPresContext* aCX, diff --git a/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp b/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp index e4d3a18f7c9..e67c837e849 100644 --- a/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp @@ -92,6 +92,7 @@ nsHTMLButtonControlFrame::nsHTMLButtonControlFrame() nsHTMLButtonControlFrame::~nsHTMLButtonControlFrame() { + nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); if (mFormFrame) { mFormFrame->RemoveFormControlFrame(*this); mFormFrame = nsnull; @@ -513,15 +514,18 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext* aPresContext, nsReflowStatus& aStatus) { if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { + mPresContext = aPresContext; + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this)); } +#if 0 nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext, aDesiredSize, aReflowState, aStatus); if (NS_SUCCEEDED(skiprv)) { return skiprv; } - +#endif // XXX remove the following when the reflow state is fixed ButtonHack((nsHTMLReflowState&)aReflowState, "html4 button"); @@ -662,10 +666,12 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext* aPresContext, //aDesiredSize.width += aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right; //aDesiredSize.height += aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom; +#if 1 //adjust our max element size, if necessary if (aDesiredSize.maxElementSize) { aDesiredSize.AddBorderPaddingToMaxElementSize(aReflowState.mComputedBorderPadding); } +#endif aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.descent = 0; @@ -684,11 +690,10 @@ nsHTMLButtonControlFrame::GetSkipSides() const } NS_IMETHODIMP -nsHTMLButtonControlFrame::GetFont(nsIPresContext* aPresContext, - const nsFont*& aFont) +nsHTMLButtonControlFrame::GetFont(nsIPresContext* aPresContext, + const nsFont*& aFont) { - nsFormControlHelper::GetFont(this, aPresContext, mStyleContext, aFont); - return NS_OK; + return nsFormControlHelper::GetFont(this, aPresContext, mStyleContext, aFont); } NS_IMETHODIMP diff --git a/mozilla/layout/forms/nsHTMLButtonControlFrame.h b/mozilla/layout/forms/nsHTMLButtonControlFrame.h index 4c902e08dd0..84ea27d4f86 100644 --- a/mozilla/layout/forms/nsHTMLButtonControlFrame.h +++ b/mozilla/layout/forms/nsHTMLButtonControlFrame.h @@ -156,6 +156,8 @@ protected: PRBool mDidInit; nsButtonFrameRenderer mRenderer; + nsCOMPtr mPresContext; + //Resize Reflow OpitmizationSize; nsSize mCacheSize; nsSize mCachedMaxElementSize; diff --git a/mozilla/layout/forms/nsImageControlFrame.cpp b/mozilla/layout/forms/nsImageControlFrame.cpp index 9f6ec1af23f..378216ed8bb 100644 --- a/mozilla/layout/forms/nsImageControlFrame.cpp +++ b/mozilla/layout/forms/nsImageControlFrame.cpp @@ -46,6 +46,7 @@ #include "nsIHTMLAttributes.h" #include "nsGenericHTMLElement.h" #include "nsFormFrame.h" +#include "nsFormControlFrame.h" //Enumeration of possible mouse states used to detect mouse clicks /*enum nsMouseState { @@ -145,6 +146,8 @@ protected: nsCursor mPreviousCursor; nsRect mTranslatedRect; PRBool mGotFocus; + + nsCOMPtr mPresContext; }; @@ -160,6 +163,8 @@ nsImageControlFrame::nsImageControlFrame() nsImageControlFrame::~nsImageControlFrame() { + nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); + if (mFormFrame) { mFormFrame->RemoveFormControlFrame(*this); mFormFrame = nsnull; @@ -255,6 +260,8 @@ nsImageControlFrame::Reflow(nsIPresContext* aPresContext, nsReflowStatus& aStatus) { if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { + mPresContext = aPresContext; + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); // add ourself as an nsIFormControlFrame nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this)); } diff --git a/mozilla/layout/forms/nsLegendFrame.cpp b/mozilla/layout/forms/nsLegendFrame.cpp index 17146e4e349..dec875b4bcf 100644 --- a/mozilla/layout/forms/nsLegendFrame.cpp +++ b/mozilla/layout/forms/nsLegendFrame.cpp @@ -30,7 +30,6 @@ #include "nsIFrame.h" #include "nsISupports.h" #include "nsIAtom.h" -#include "nsIPresContext.h" #include "nsIHTMLContent.h" #include "nsHTMLIIDs.h" #include "nsHTMLParts.h" @@ -39,6 +38,7 @@ #include "nsStyleConsts.h" #include "nsStyleUtil.h" #include "nsFont.h" +#include "nsFormControlFrame.h" static NS_DEFINE_IID(kLegendFrameCID, NS_LEGEND_FRAME_CID); static NS_DEFINE_IID(kIDOMHTMLLegendElementIID, NS_IDOMHTMLLEGENDELEMENT_IID); @@ -63,6 +63,11 @@ nsLegendFrame::nsLegendFrame() { } +nsLegendFrame::~nsLegendFrame() +{ + nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); +} + // Frames are not refcounted, no need to AddRef NS_IMETHODIMP nsLegendFrame::QueryInterface(REFNSIID aIID, void** aInstancePtrResult) @@ -78,6 +83,20 @@ nsLegendFrame::QueryInterface(REFNSIID aIID, void** aInstancePtrResult) return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtrResult); } +NS_IMETHODIMP +nsLegendFrame::Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (eReflowReason_Initial == aReflowState.reason) { + mPresContext = aPresContext; + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); + } + return nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); +} + + PRInt32 nsLegendFrame::GetAlign() { PRInt32 intValue = NS_STYLE_TEXT_ALIGN_LEFT; diff --git a/mozilla/layout/forms/nsLegendFrame.h b/mozilla/layout/forms/nsLegendFrame.h index 6401d24caa4..5538435740c 100644 --- a/mozilla/layout/forms/nsLegendFrame.h +++ b/mozilla/layout/forms/nsLegendFrame.h @@ -24,6 +24,9 @@ #define nsLegendFrame_h___ #include "nsAreaFrame.h" +#include "nsIPresContext.h" +#include "nsCOMPtr.h" + class nsIContent; class nsIFrame; class nsIPresContext; @@ -38,14 +41,23 @@ class nsLegendFrame : public nsAreaFrame { public: nsLegendFrame(); + virtual ~nsLegendFrame(); NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + NS_IMETHOD Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus); + + #ifdef NS_DEBUG NS_IMETHOD GetFrameName(nsString& aResult) const; #endif PRInt32 GetAlign(); + + nsCOMPtr mPresContext; }; diff --git a/mozilla/layout/forms/nsListControlFrame.cpp b/mozilla/layout/forms/nsListControlFrame.cpp index 0fbda31ccdd..b26a500b157 100644 --- a/mozilla/layout/forms/nsListControlFrame.cpp +++ b/mozilla/layout/forms/nsListControlFrame.cpp @@ -123,6 +123,8 @@ nsListControlFrame::nsListControlFrame() //--------------------------------------------------------- nsListControlFrame::~nsListControlFrame() { + nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); + // if list is dropped down // make sure it gets rolled up if (IsInDropDownMode()) { @@ -286,7 +288,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { -#ifdef DEBUG_rodsXXX +#ifdef DEBUG_rods printf("nsListControlFrame::Reflow Reason: "); switch (aReflowState.reason) { case eReflowReason_Initial:printf("eReflowReason_Initial\n");break; @@ -355,6 +357,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext, mHasBeenInitialized = PR_TRUE; InitSelectionCache(-1); // Reset sel cache so as not to send event Reset(mPresContext); +#if 1 nsCOMPtr cmd; nsresult rv = NS_NewHTMLReflowCommand(getter_AddRefs(cmd), this, nsIReflowCommand::StyleChanged); if (NS_FAILED(rv)) { return rv; } @@ -368,10 +371,18 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext, rv = shell->AppendReflowCommand(cmd); // must do this next line regardless of result of AppendReflowCommand shell->ExitReflowLock(PR_TRUE); +#else + if (mParent) { + nsCOMPtr shell; + nsresult rv = mPresContext->GetShell(getter_AddRefs(shell)); + mState |= NS_FRAME_IS_DIRTY; + mParent->ReflowDirtyChild(shell, (nsIFrame*) this); + } +#endif } } -#if 1 +#if 0 nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext, aDesiredSize, aReflowState, aStatus); if (NS_SUCCEEDED(skiprv)) { @@ -416,6 +427,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext, // Add the list frame as a child of the form if (IsInDropDownMode() == PR_FALSE && !mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this)); } @@ -1943,6 +1955,17 @@ nsListControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex) Reset(aPresContext); // this sets mSelectedIndex to the defaulted selection wasReset = PR_TRUE; } + +#if DEBUG_rods + { + nsAutoString text = "No Value"; + nsresult rv = option->GetLabel(text); + if (NS_CONTENT_ATTR_NOT_THERE == rv || 0 == text.Length()) { + option->GetText(text); + } + printf("this %p Index: %d [%s] CB: %p\n", this, aIndex, text.ToNewCString(), mComboboxFrame); //leaks + } +#endif } } @@ -2468,6 +2491,30 @@ void nsListControlFrame::ResetSelectedItem() } } +//---------------------------------------------------------------------- +// helper +//---------------------------------------------------------------------- +PRBool +nsListControlFrame::IsLeftButton(nsIDOMEvent* aMouseEvent) +{ + // only allow selection with the left button + nsCOMPtr mouseEvent = do_QueryInterface(aMouseEvent); + if (mouseEvent) { + PRUint16 whichButton; + if (NS_SUCCEEDED(mouseEvent->GetButton(&whichButton))) { + if (whichButton != 1) { + aMouseEvent->PreventDefault(); + aMouseEvent->PreventCapture(); + aMouseEvent->PreventBubble(); + return PR_FALSE; + } else { + return PR_TRUE; + } + } + } + return PR_FALSE; +} + //---------------------------------------------------------------------- // nsIDOMMouseListener //---------------------------------------------------------------------- @@ -2479,6 +2526,11 @@ nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent) return NS_OK; } + // only allow selection with the left button + if (!IsLeftButton(aMouseEvent)) { + return NS_ERROR_FAILURE; // means consume event + } + // Check to see if the disabled option was clicked on // NS_ERROR_FAILURE is returned is it isn't over an option PRBool optionIsDisabled; @@ -2512,7 +2564,11 @@ nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent) UpdateSelection(PR_TRUE, PR_FALSE, mContent); } - return NS_OK; + aMouseEvent->PreventDefault(); + aMouseEvent->PreventCapture(); + aMouseEvent->PreventBubble(); + return NS_ERROR_FAILURE; + //return NS_OK; } //--------------------------------------------------------- @@ -2579,6 +2635,11 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent) return NS_OK; } + // only allow selection with the left button + if (!IsLeftButton(aMouseEvent)) { + return NS_ERROR_FAILURE; // means consume event + } + // Check to see if the disabled option was clicked on // NS_ERROR_FAILURE is returned is it isn't over an option PRBool optionIsDisabled; @@ -2673,7 +2734,11 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent) } } } - return NS_OK; + aMouseEvent->PreventDefault(); + aMouseEvent->PreventCapture(); + aMouseEvent->PreventBubble(); + return NS_ERROR_FAILURE; //consumes event + //return NS_OK; } //---------------------------------------------------------------------- diff --git a/mozilla/layout/forms/nsListControlFrame.h b/mozilla/layout/forms/nsListControlFrame.h index 8ae637d8697..d17e78ccb28 100644 --- a/mozilla/layout/forms/nsListControlFrame.h +++ b/mozilla/layout/forms/nsListControlFrame.h @@ -217,6 +217,7 @@ protected: PRBool HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2); void HandleListSelection(nsIDOMEvent * aDOMEvent); PRInt32 GetSelectedIndexFromFrame(nsIFrame *aHitFrame); + PRBool IsLeftButton(nsIDOMEvent* aMouseEvent); // onChange detection nsresult InitSelectionCache(PRInt32 aLength); diff --git a/mozilla/layout/forms/nsTextControlFrame.cpp b/mozilla/layout/forms/nsTextControlFrame.cpp index ee48bfd8915..804e77d7836 100644 --- a/mozilla/layout/forms/nsTextControlFrame.cpp +++ b/mozilla/layout/forms/nsTextControlFrame.cpp @@ -30,7 +30,6 @@ #include "nsIHTMLContent.h" #include "nsHTMLIIDs.h" #include "nsITextWidget.h" -#include "nsITextAreaWidget.h" #include "nsWidgetsCID.h" #include "nsSize.h" #include "nsString.h" diff --git a/mozilla/layout/html/forms/src/makefile.win b/mozilla/layout/html/forms/src/makefile.win index e8985ef5897..cf0b6f1404f 100644 --- a/mozilla/layout/html/forms/src/makefile.win +++ b/mozilla/layout/html/forms/src/makefile.win @@ -34,13 +34,8 @@ CPPSRCS= \ nsListControlFrame.cpp \ nsFormFrame.cpp \ nsFormControlFrame.cpp \ - nsButtonControlFrame.cpp \ - nsCheckboxControlFrame.cpp \ nsFileControlFrame.cpp \ - nsRadioControlFrame.cpp \ - nsTextControlFrame.cpp \ nsGfxTextControlFrame.cpp \ - nsTextControlFrame.cpp \ nsFieldSetFrame.cpp \ nsLegendFrame.cpp \ nsHTMLButtonControlFrame.cpp \ @@ -51,7 +46,6 @@ CPPSRCS= \ nsGfxCheckboxControlFrame.cpp \ nsGfxRadioControlFrame.cpp \ nsGfxAutoTextControlFrame.cpp \ - nsNativeFormControlFrame.cpp \ nsRadioControlGroup.cpp CPP_OBJS= \ @@ -61,11 +55,7 @@ CPP_OBJS= \ .\$(OBJDIR)\nsListControlFrame.obj \ .\$(OBJDIR)\nsFormFrame.obj \ .\$(OBJDIR)\nsFormControlFrame.obj \ - .\$(OBJDIR)\nsButtonControlFrame.obj \ - .\$(OBJDIR)\nsCheckboxControlFrame.obj \ .\$(OBJDIR)\nsFileControlFrame.obj \ - .\$(OBJDIR)\nsRadioControlFrame.obj \ - .\$(OBJDIR)\nsTextControlFrame.obj \ .\$(OBJDIR)\nsGfxTextControlFrame.obj \ .\$(OBJDIR)\nsFieldSetFrame.obj \ .\$(OBJDIR)\nsLegendFrame.obj \ @@ -77,7 +67,6 @@ CPP_OBJS= \ .\$(OBJDIR)\nsGfxCheckboxControlFrame.obj \ .\$(OBJDIR)\nsGfxRadioControlFrame.obj \ .\$(OBJDIR)\nsGfxAutoTextControlFrame.obj \ - .\$(OBJDIR)\nsNativeFormControlFrame.obj \ .\$(OBJDIR)\nsRadioControlGroup.obj diff --git a/mozilla/layout/html/forms/src/nsCheckboxControlFrame.h b/mozilla/layout/html/forms/src/nsCheckboxControlFrame.h index c6d6d491fc3..489f3c6d469 100644 --- a/mozilla/layout/html/forms/src/nsCheckboxControlFrame.h +++ b/mozilla/layout/html/forms/src/nsCheckboxControlFrame.h @@ -22,7 +22,7 @@ #ifndef nsCheckboxControlFrame_h___ #define nsCheckboxControlFrame_h___ -#include "nsNativeFormControlFrame.h" +#include "nsFormControlFrame.h" #include "nsIStatefulFrame.h" class nsIPresState; @@ -47,7 +47,7 @@ class nsIPresState; // become checked since "mixed" doesn't exist on normal checkboxes. // -class nsCheckboxControlFrame : public nsNativeFormControlFrame, +class nsCheckboxControlFrame : public nsFormControlFrame, public nsIStatefulFrame { public: diff --git a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp index d12709f7f36..062ca5fd144 100644 --- a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp @@ -132,6 +132,8 @@ nsComboboxControlFrame::~nsComboboxControlFrame() NS_IF_RELEASE(mPresContext); NS_IF_RELEASE(mDisplayContent); NS_IF_RELEASE(mButtonContent); + + nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); } //-------------------------------------------------------------- @@ -265,9 +267,7 @@ nsComboboxControlFrame::Reset(nsIPresContext* aPresContext) } void -nsComboboxControlFrame::PostCreateWidget(nsIPresContext* aPresContext, - nscoord& aWidth, - nscoord& aHeight) +nsComboboxControlFrame::InitializeControl(nsIPresContext* aPresContext) { Reset(aPresContext); } @@ -724,6 +724,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*,this)); } @@ -912,6 +913,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, #else // DO_OLD_REFLOW #ifdef DEBUG_rods +nsComboboxControlFrame * pCB = nsnull; static int myCounter = 0; #endif @@ -922,7 +924,8 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, nsReflowStatus& aStatus) { #ifdef DEBUG_rods - printf("****** nsComboboxControlFrame::Reflow %d Reason: ", myCounter++); + //if (pCB) { + printf("%p ****** nsComboboxControlFrame::Reflow %d Reason: ", this, myCounter++); switch (aReflowState.reason) { case eReflowReason_Initial: printf("eReflowReason_Initial\n");break; @@ -933,6 +936,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, break; case eReflowReason_StyleChange:printf("eReflowReason_StyleChange\n");break; } + //} #endif #if 0 @@ -993,7 +997,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, // but it does seems to go into this code. } else { if (targetFrame != dropdownFrame) { +#ifdef DEBUG_rods printf("+++++++++++++++++++++++\n"); +#endif rv = nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); displayFrame->GetRect(displayRect); buttonFrame->GetRect(buttonRect); @@ -1001,14 +1007,34 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, buttonRect.height = displayRect.height; buttonFrame->SetRect(aPresContext, buttonRect); aStatus = NS_FRAME_COMPLETE; +#ifdef DEBUG_rods printf("--> W: %d H: %d\n", aDesiredSize.width, aDesiredSize.height); +#endif return rv; } else { #if 0 + nsRect dropdownRect; + dropdownFrame->GetRect(dropdownRect); nsHTMLReflowMetrics dropdownDesiredSize(aDesiredSize); ReflowComboChildFrame(dropdownFrame, aPresContext, dropdownDesiredSize, firstPassState, - aStatus, firstPassState.availableWidth, firstPassState.availableHeight); - return NS_OK; + aStatus, dropdownRect.width, dropdownRect.height); + nsCOMPtr context; + targetFrame->GetStyleContext(getter_AddRefs(context)); + const nsStyleDisplay* disp = (const nsStyleDisplay*)context->GetStyleData(eStyleStruct_Display); + printf("IsVisible %s\n", disp->mVisible == NS_STYLE_VISIBILITY_VISIBLE?"yes":"No"); + //if (disp->mVisible == NS_STYLE_VISIBILITY_VISIBLE) { + nsRect rect; + GetRect(rect); + aDesiredSize.width = rect.width;// + borderPadding.left + borderPadding.right; + aDesiredSize.height = rect.height;// + borderPadding.top + borderPadding.bottom; + aDesiredSize.ascent = aDesiredSize.height; + aDesiredSize.descent = 0; + dropdownRect.width = rect.width; + dropdownFrame->SetRect(aPresContext, dropdownRect); + printf("Skipping out.........................."); + aStatus = NS_FRAME_COMPLETE; + return NS_OK; + //} #endif } } @@ -1035,10 +1061,15 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, dx->GetCanonicalPixelScale(scale); scrollbarWidth = NSIntPixelsToTwips(info.mSize, p2t*scale); } +#ifdef DEBUG_rods printf("UNC %d AV %d \n", firstPassState.mComputedWidth,firstPassState.availableWidth); +#endif //Set the desired size for the button and display frame if (NS_UNCONSTRAINEDSIZE == firstPassState.mComputedWidth) { +#ifdef DEBUG_rods printf("=====================================\n"); +#endif + // A width has not been specified for the select so size the display area to // match the width of the longest item in the drop-down list. The dropdown // list has already been reflowed and sized to shrink around its contents above. @@ -1077,7 +1108,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, dspBorderPadding.SizeTo(0, 0, 0, 0); dspSpacing->CalcBorderPaddingFor(displayFrame, dspBorderPadding); +#ifdef DEBUG_rods printf("W: %d\n", dropdownRect.width-size.width+dspBorderPadding.left+dspBorderPadding.right); +#endif // Set width of display to match width of the drop down SetChildFrameSize(displayFrame, dropdownRect.width-size.width+dspBorderPadding.left+dspBorderPadding.right, size.height+dspBorderPadding.top+dspBorderPadding.bottom); @@ -1103,7 +1136,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, } } else { +#ifdef DEBUG_rods printf("*************************************\n"); +#endif // for debug ------- PRInt32 length = 0; mListControlFrame->GetNumberOfOptions(&length); @@ -1129,7 +1164,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, // nsAreaFrame::Reflow adds in the border and padding so we need to remove it //displayWidth -= borderPadding.left + borderPadding.right; +#ifdef DEBUG_rods printf("WW: %d\n", displayWidth); +#endif // Set the displayFrame to match the displayWidth computed above if (displayWidth >= 0) { SetChildFrameSize(displayFrame, displayWidth, size.height); @@ -1146,7 +1183,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, buttonRect.height = displayRect.height; buttonFrame->SetRect(aPresContext, buttonRect); displayFrame->SetRect(aPresContext, displayRect); +#ifdef DEBUG_rods printf("DW: %d\n", aDesiredSize.width); +#endif // nsAreaFrame::Reflow adds in the border and padding so we need to remove it // XXX rods - this hould not be subtracted in //aDesiredSize.width += borderPadding.left + borderPadding.right; @@ -1156,6 +1195,8 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, } aDesiredSize.width = firstPassState.mComputedWidth + borderPadding.left + borderPadding.right; aDesiredSize.height = firstPassState.mComputedHeight + borderPadding.top + borderPadding.bottom; + aDesiredSize.ascent = aDesiredSize.height; + aDesiredSize.descent = 0; } // Set the max element size to be the same as the desired element size. @@ -1164,18 +1205,15 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.maxElementSize->height = aDesiredSize.height; } - nsRect absoluteTwips; - nsRect absolutePixels; - GetAbsoluteFramePosition(aPresContext, this, absoluteTwips, absolutePixels); - PositionDropdown(aPresContext, aDesiredSize.height, absoluteTwips, absolutePixels); - aStatus = NS_FRAME_COMPLETE; #if 0 COMPARE_QUIRK_SIZE("nsComboboxControlFrame", 127, 22) #endif nsFormControlFrame::SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize); +#ifdef DEBUG_rods printf("--> W: %d H: %d\n", aDesiredSize.width, aDesiredSize.height); +#endif return rv; } @@ -1422,6 +1460,7 @@ nsComboboxControlFrame::SelectionChanged() } if (shouldSetValue) { rv = htmlContent->SetHTMLAttribute(nsHTMLAtoms::value, mTextStr, PR_TRUE); +#if 1 if (NS_SUCCEEDED(rv)) { nsIFrame* displayFrame = GetDisplayFrame(mPresContext); @@ -1439,6 +1478,15 @@ nsComboboxControlFrame::SelectionChanged() NS_RELEASE(cmd); } } +#else + if (mParent) { + nsCOMPtr shell; + rv = mPresContext->GetShell(getter_AddRefs(shell)); + mState |= NS_FRAME_IS_DIRTY; + mParent->ReflowDirtyChild(shell, (nsIFrame*) this); + } + +#endif } } } @@ -1467,12 +1515,19 @@ nsComboboxControlFrame::DoneAddingContent(PRBool aIsDone) NS_IMETHODIMP nsComboboxControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex) { +#ifdef DEBUG_rodsXXX + if (!pCB) pCB = this; +#endif + nsISelectControlFrame* listFrame = nsnull; nsIFrame* dropdownFrame = GetDropdownFrame(); nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame), (void**)&listFrame); if (NS_SUCCEEDED(rv) && listFrame) { rv = listFrame->AddOption(aPresContext, aIndex); + PRInt32 index; + mListControlFrame->GetSelectedIndex(&index); + UpdateSelection(PR_FALSE, PR_TRUE, index); NS_RELEASE(listFrame); } // If we added the first option, we might need to select it. diff --git a/mozilla/layout/html/forms/src/nsComboboxControlFrame.h b/mozilla/layout/html/forms/src/nsComboboxControlFrame.h index 781bfab81e3..4359a810c32 100644 --- a/mozilla/layout/html/forms/src/nsComboboxControlFrame.h +++ b/mozilla/layout/html/forms/src/nsComboboxControlFrame.h @@ -35,8 +35,6 @@ #include "nsIRollupListener.h" #include "nsIPresState.h" -class nsButtonControlFrame; -class nsTextControlFrame; class nsFormFrame; class nsIView; class nsStyleContext; @@ -109,9 +107,7 @@ public: NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue); void SetFocus(PRBool aOn, PRBool aRepaint); void ScrollIntoView(nsIPresContext* aPresContext); - virtual void PostCreateWidget(nsIPresContext* aPresContext, - nscoord& aWidth, - nscoord& aHeight); + virtual void InitializeControl(nsIPresContext* aPresContext); virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter); virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; } virtual void Reset(nsIPresContext* aPresContext); diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp index 3bf49fa1a11..e7940b39b3d 100644 --- a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp @@ -22,9 +22,7 @@ #include "nsFileControlFrame.h" #include "nsFormFrame.h" -#include "nsButtonControlFrame.h" -#include "nsTextControlFrame.h" -#include "nsNativeTextControlFrame.h" // XXX: remove when frame construction is done properly +#include "nsGfxTextControlFrame.h" #include "nsIContent.h" #include "prtypes.h" #include "nsIAtom.h" @@ -312,7 +310,7 @@ nsFileControlFrame::SetInitialChildList(nsIPresContext* aPresContext, * frame constuctor create the frame and its implementation. So we are given the text * node from the constructor and we find it in our tree. */ -nsTextControlFrame* +nsGfxTextControlFrame* nsFileControlFrame::GetTextControlFrame(nsIPresContext* aPresContext, nsIFrame* aStart) { // find the text control frame. @@ -331,13 +329,13 @@ nsFileControlFrame::GetTextControlFrame(nsIPresContext* aPresContext, nsIFrame* value.ToUpperCase(); nsString txt("TEXT"); if (value == txt) { - return (nsTextControlFrame*)childFrame; + return (nsGfxTextControlFrame*)childFrame; } } } // if not continue looking - nsTextControlFrame* frame = GetTextControlFrame(aPresContext, childFrame); + nsGfxTextControlFrame* frame = GetTextControlFrame(aPresContext, childFrame); if (frame) return frame; diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.h b/mozilla/layout/html/forms/src/nsFileControlFrame.h index c90cf974c43..6f2b9260d63 100644 --- a/mozilla/layout/html/forms/src/nsFileControlFrame.h +++ b/mozilla/layout/html/forms/src/nsFileControlFrame.h @@ -30,8 +30,7 @@ #include "nsIStatefulFrame.h" class nsIPresState; -class nsButtonControlFrame; -class nsTextControlFrame; +class nsGfxTextControlFrame; class nsFormFrame; class nsISupportsArray; class nsIHTMLContent; @@ -176,7 +175,7 @@ protected: virtual PRIntn GetSkipSides() const; - nsTextControlFrame* mTextFrame; + nsGfxTextControlFrame* mTextFrame; nsFormFrame* mFormFrame; nsIHTMLContent* mTextContent; nsString* mCachedState; @@ -184,7 +183,7 @@ protected: nsIPresContext* mPresContext; // weak reference private: - nsTextControlFrame* GetTextControlFrame(nsIPresContext* aPresContext, + nsGfxTextControlFrame* GetTextControlFrame(nsIPresContext* aPresContext, nsIFrame* aStart); NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; } diff --git a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp index 8017cca428c..dba52d5f230 100644 --- a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp @@ -54,6 +54,11 @@ #include "nsStyleUtil.h" #include "nsINameSpaceManager.h" #include "nsIDOMHTMLInputElement.h" +#include "nsIDOMHTMLLabelElement.h" +#include "nsIDOMHTMLTextAreaElement.h" +#include "nsIDOMHTMLLegendElement.h" +#include "nsIDOMHTMLButtonElement.h" +#include "nsIEventStateManager.h" static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID); @@ -87,6 +92,7 @@ nsFormControlFrame::~nsFormControlFrame() mFormFrame->RemoveRadioControlFrame(this); mFormFrame = nsnull; } + RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); } // Frames are not refcounted, no need to AddRef @@ -302,42 +308,29 @@ nsFormControlFrame::Reflow(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { + if (!mDidInit) { + mPresContext = aPresContext; + InitializeControl(aPresContext); + mDidInit = PR_TRUE; + } + // add ourself as an nsIFormControlFrame if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this)); } + nsresult skiprv = SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext, aDesiredSize, aReflowState, aStatus); if (NS_SUCCEEDED(skiprv)) { return skiprv; } - nsWidgetRendering mode; - aPresContext->GetWidgetRenderingMode(&mode); - if (eWidgetRendering_Native == mode) { - GetDesiredSize(aPresContext, aReflowState, aDesiredSize, mWidgetSize); - - if (!mDidInit) { - PostCreateWidget(aPresContext, aDesiredSize.width, aDesiredSize.height); - mDidInit = PR_TRUE; - } - aDesiredSize.ascent = aDesiredSize.height; - aDesiredSize.descent = 0; - - } else { - nsresult rv = nsLeafFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); - if (!mDidInit) { - //GetDesiredSize(aPresContext, aReflowState, aDesiredSize); - PostCreateWidget(aPresContext, aDesiredSize.width, aDesiredSize.height); - mDidInit = PR_TRUE; - } - return rv; - } + nsresult rv = nsLeafFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); aStatus = NS_FRAME_COMPLETE; SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize); - return NS_OK; + return rv; } @@ -347,9 +340,72 @@ nsFormControlFrame::GetWidgetInitData(nsIPresContext* aPresContext) return nsnull; } -void -nsFormControlFrame::PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWidth, nscoord& aHeight) + +nsresult +nsFormControlFrame::RegUnRegAccessKey(nsIPresContext* aPresContext, nsIFrame * aFrame, PRBool aDoReg) { +#if 0 + NS_ASSERTION(aPresContext, "aPresContext is NULL in RegUnRegAccessKey!"); + NS_ASSERTION(aFrame, "aFrame is NULL in RegUnRegAccessKey!"); + + nsresult rv = NS_ERROR_FAILURE; + nsAutoString accessKey; + + if (aFrame != nsnull) { + nsCOMPtr content; + if (NS_SUCCEEDED(aFrame->GetContent(getter_AddRefs(content)))) { +#if 1 + PRInt32 nameSpaceID; + content->GetNameSpaceID(nameSpaceID); + nsAutoString resultValue; + rv = content->GetAttribute(nameSpaceID, nsHTMLAtoms::accesskey, accessKey); +#else + nsCOMPtr inputElement(do_QueryInterface(content)); + if (inputElement) { + rv = inputElement->GetAccessKey(accessKey); + } else { + nsCOMPtr textarea(do_QueryInterface(content)); + if (textarea) { + rv = textarea->GetAccessKey(accessKey); + } else { + nsCOMPtr label(do_QueryInterface(content)); + if (label) { + rv = label->GetAccessKey(accessKey); + } else { + nsCOMPtr legend(do_QueryInterface(content)); + if (legend) { + rv = legend->GetAccessKey(accessKey); + } else { + nsCOMPtr btn(do_QueryInterface(content)); + if (btn) { + rv = btn->GetAccessKey(accessKey); + } + } + } + } + } +#endif + } + } + + if (NS_CONTENT_ATTR_NOT_THERE != rv) { + nsCOMPtr stateManager; + if (NS_SUCCEEDED(aPresContext->GetEventStateManager(getter_AddRefs(stateManager)))) { + if (aDoReg) { + return stateManager->RegisterAccessKey(aFrame, (PRUint32)accessKey.First()); + } else { + return stateManager->UnregisterAccessKey(aFrame); + } + } + } +#endif + return NS_ERROR_FAILURE; +} + +void +nsFormControlFrame::InitializeControl(nsIPresContext* aPresContext) +{ + RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); } void diff --git a/mozilla/layout/html/forms/src/nsFormControlFrame.h b/mozilla/layout/html/forms/src/nsFormControlFrame.h index 23fd9988058..f5b8a139f4b 100644 --- a/mozilla/layout/html/forms/src/nsFormControlFrame.h +++ b/mozilla/layout/html/forms/src/nsFormControlFrame.h @@ -31,11 +31,14 @@ #include "nsLeafFrame.h" #include "nsCoord.h" #include "nsIStyleContext.h" +#include "nsIPresContext.h" +#include "nsCOMPtr.h" class nsIView; class nsIPresContext; class nsStyleCoord; class nsFormFrame; +class nsIFocusableContent; #define CSS_NOTSET -1 #define ATTR_NOTSET -1 @@ -152,11 +155,9 @@ public: virtual void ControlChanged(nsIPresContext* aPresContext) {} /** - * Perform opertations after the widget associated with this frame has been - * created. + * Chance to Initialize to a defualt value */ - virtual void PostCreateWidget(nsIPresContext* aPresContext, - nscoord& aWidth, nscoord& aHeight); + virtual void InitializeControl(nsIPresContext* aPresContext); virtual void SetFocus(PRBool aOn = PR_TRUE, PRBool aRepaint = PR_FALSE); virtual void ScrollIntoView(nsIPresContext* aPresContext); @@ -221,6 +222,8 @@ public: nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus); + // AccessKey Helper function + static nsresult RegUnRegAccessKey(nsIPresContext* aPresContext, nsIFrame * aFrame, PRBool aDoReg); protected: @@ -301,6 +304,8 @@ protected: nscoord mSuggestedWidth; nscoord mSuggestedHeight; + nsCOMPtr mPresContext; + // Reflow Optimization nsSize mCacheSize; nsSize mCachedMaxElementSize; diff --git a/mozilla/layout/html/forms/src/nsFormControlHelper.cpp b/mozilla/layout/html/forms/src/nsFormControlHelper.cpp index bb3614c0055..dc24f6195e7 100644 --- a/mozilla/layout/html/forms/src/nsFormControlHelper.cpp +++ b/mozilla/layout/html/forms/src/nsFormControlHelper.cpp @@ -453,7 +453,7 @@ nsFormControlHelper::CalculateSize (nsIPresContext* aPresContext, // need to set charWidth and aDesiredSize.height charWidth = GetTextSize(aPresContext, aFrame, 1, aDesiredSize, aRendContext); col = (col <= 0) ? 15 : col; // XXX why a default of 15 pixels, why hide it - // XXX this conflicts with a default of 20 found in nsTextControlFrame. + // XXX this conflicts with a default of 20 found in nsGfxTextControlFrame. aDesiredSize.width = NSIntPixelsToTwips(col, p2t); } else { col = (col <= 0) ? 1 : col; // XXX why a default of 1 char, why hide it diff --git a/mozilla/layout/html/forms/src/nsFormFrame.cpp b/mozilla/layout/html/forms/src/nsFormFrame.cpp index 25158bbac94..274efb8c3b5 100644 --- a/mozilla/layout/html/forms/src/nsFormFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFormFrame.cpp @@ -66,8 +66,7 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); #include "nsIDocument.h" #include "nsILinkHandler.h" -#include "nsRadioControlFrame.h" -#include "nsIRadioButton.h" +#include "nsGfxRadioControlFrame.h" #include "nsDocument.h" #include "nsIDOMHTMLFormElement.h" #include "nsIDOMNSHTMLFormElement.h" @@ -84,6 +83,7 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); // Get base target for submission #include "nsIHTMLContent.h" +#include "nsIDOMHTMLInputElement.h" #include "net.h" #include "xp_file.h" @@ -333,6 +333,32 @@ void nsFormFrame::RemoveFormControlFrame(nsIFormControlFrame& aFrame) mFormControls.RemoveElement(&aFrame); } +NS_IMETHODIMP +nsFormFrame::RemoveFrame(nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame) +{ + nsresult rv = NS_OK; + + nsIFormControlFrame* fcFrame = nsnull; + nsresult result = aOldFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame); + if ((NS_OK == result) || (nsnull != fcFrame)) { + PRInt32 type; + fcFrame->GetType(&type); + if (NS_FORM_INPUT_RADIO == type) { + nsRadioControlGroup * group; + nsAutoString name; + nsresult rv = GetRadioInfo(fcFrame, name, group); + if (NS_SUCCEEDED(rv) && nsnull != group) { + DoDefaultSelection(aPresContext, group, (nsGfxRadioControlFrame*)fcFrame); + } + } + } + + return nsBlockFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame); +} + nsresult nsFormFrame::GetRadioInfo(nsIFormControlFrame* aFrame, nsString& aName, nsRadioControlGroup *& aGroup) @@ -359,6 +385,57 @@ nsresult nsFormFrame::GetRadioInfo(nsIFormControlFrame* aFrame, return NS_ERROR_FAILURE; } +void nsFormFrame::DoDefaultSelection(nsIPresContext* aPresContext, + nsRadioControlGroup * aGroup, + nsGfxRadioControlFrame * aRadioToIgnore) +{ + // If in standard mode, then a radio group MUST default + // to the first item in the group (it must be selected) + nsCompatibility mode; + aPresContext->GetCompatibilityMode(&mode); + if (eCompatibility_Standard == mode) { + // first find out if any have a default selection + PRInt32 i; + PRInt32 numItems = aGroup->GetNumRadios(); + PRBool oneIsSelected = PR_FALSE; + for (i=0;iGetRadioAt(i); + nsCOMPtr content; + radioBtn->GetContent(getter_AddRefs(content)); + if (content) { + nsCOMPtr input(do_QueryInterface(content)); + if (input) { + input->GetDefaultChecked(&oneIsSelected); + } + } + } + + // if there isn't a default selcted radio then + // select the firdst one in the group. + // if aRadioToIgnore is not null then it is being deleted + // so don't select that item, select the next one if there is one. + if (!oneIsSelected && numItems > 0) { + nsGfxRadioControlFrame * radioBtn = (nsGfxRadioControlFrame*) aGroup->GetRadioAt(0); + if (aRadioToIgnore != nsnull && aRadioToIgnore == radioBtn) { + if (numItems == 1) { + return; + } + radioBtn = (nsGfxRadioControlFrame*) aGroup->GetRadioAt(1); + } + nsCOMPtr content; + radioBtn->GetContent(getter_AddRefs(content)); + if (content) { + nsCOMPtr input(do_QueryInterface(content)); + if (input) { + input->SetChecked(PR_TRUE); + OnRadioChecked(aPresContext, *radioBtn, PR_TRUE); + } + } + } + } +} + + void nsFormFrame::AddFormControlFrame(nsIPresContext* aPresContext, nsIFormControlFrame& aFrame) { mFormControls.AppendElement(&aFrame); @@ -381,7 +458,7 @@ void nsFormFrame::AddFormControlFrame(nsIPresContext* aPresContext, nsIFormContr // radio group processing if (NS_FORM_INPUT_RADIO == type) { - nsRadioControlFrame* radioFrame = (nsRadioControlFrame*)&aFrame; + nsGfxRadioControlFrame* radioFrame = (nsGfxRadioControlFrame*)&aFrame; // gets the name of the radio group and the group nsRadioControlGroup * group; nsAutoString name; @@ -401,6 +478,7 @@ void nsFormFrame::AddFormControlFrame(nsIPresContext* aPresContext, nsIFormContr radioFrame->SetChecked(aPresContext, PR_FALSE, PR_TRUE); } } + DoDefaultSelection(aPresContext, group); } } @@ -411,7 +489,7 @@ void nsFormFrame::RemoveRadioControlFrame(nsIFormControlFrame * aFrame) // radio group processing if (NS_FORM_INPUT_RADIO == type) { - nsRadioControlFrame* radioFrame = (nsRadioControlFrame*)aFrame; + nsGfxRadioControlFrame* radioFrame = (nsGfxRadioControlFrame*)aFrame; // gets the name of the radio group and the group nsRadioControlGroup * group; nsAutoString name; @@ -423,7 +501,7 @@ void nsFormFrame::RemoveRadioControlFrame(nsIFormControlFrame * aFrame) } void -nsFormFrame::OnRadioChecked(nsIPresContext* aPresContext, nsRadioControlFrame& aControl, PRBool aChecked) +nsFormFrame::OnRadioChecked(nsIPresContext* aPresContext, nsGfxRadioControlFrame& aControl, PRBool aChecked) { nsString radioName; aControl.GetName(&radioName); @@ -437,7 +515,7 @@ nsFormFrame::OnRadioChecked(nsIPresContext* aPresContext, nsRadioControlFrame& a nsRadioControlGroup* group = (nsRadioControlGroup *) mRadioGroups.ElementAt(j); nsString groupName; group->GetName(groupName); - nsRadioControlFrame* checkedRadio = group->GetCheckedRadio(); + nsGfxRadioControlFrame* checkedRadio = group->GetCheckedRadio(); if (groupName.Equals(radioName)) { if (aChecked) { if (&aControl != checkedRadio) { diff --git a/mozilla/layout/html/forms/src/nsFormFrame.h b/mozilla/layout/html/forms/src/nsFormFrame.h index dd4507fdd05..2dcf0a2463d 100644 --- a/mozilla/layout/html/forms/src/nsFormFrame.h +++ b/mozilla/layout/html/forms/src/nsFormFrame.h @@ -34,7 +34,7 @@ class nsIFrame; class nsIPresContext; struct nsHTMLReflowState; class nsFormControlFrame; -class nsRadioControlFrame; +class nsGfxRadioControlFrame; class nsIFormControlFrame; class nsIDOMHTMLFormElement; class nsIDocument; @@ -52,6 +52,11 @@ public: NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); + NS_IMETHOD RemoveFrame(nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame); + // nsIFormManager NS_IMETHOD OnReset(nsIPresContext* aPresContext); @@ -60,7 +65,7 @@ public: // other methods - void OnRadioChecked(nsIPresContext* aPresContext, nsRadioControlFrame& aRadio, PRBool aChecked = PR_TRUE); + void OnRadioChecked(nsIPresContext* aPresContext, nsGfxRadioControlFrame& aRadio, PRBool aChecked = PR_TRUE); void AddFormControlFrame(nsIPresContext* aPresContext, nsIFormControlFrame& aFrame); static void AddFormControlFrame(nsIPresContext* aPresContext, nsIFrame& aFrame); @@ -93,6 +98,10 @@ protected: NS_IMETHOD_(nsrefcnt) Release(void); void RemoveRadioGroups(); + void DoDefaultSelection(nsIPresContext* aPresContext, + nsRadioControlGroup * aGroup, + nsGfxRadioControlFrame * aRadioToIgnore = nsnull); + nsresult ProcessValue(nsIFormProcessor& aFormProcessor, nsIFormControlFrame* aFrameControl, const nsString& aName, nsString& aNewValue); nsresult ProcessAsURLEncoded(nsIFormProcessor* aFormProcessor, PRBool aIsPost, nsString& aData, nsIFormControlFrame* aFrame); nsresult ProcessAsMultipart(nsIFormProcessor* aFormProcessor, nsIFileSpec*& aMultipartDataFile, nsIFormControlFrame* aFrame); diff --git a/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp b/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp index adbea904cac..653af3cc93c 100644 --- a/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp @@ -332,7 +332,7 @@ nsGfxButtonControlFrame::Reflow(nsIPresContext* aPresContext, nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this)); } -#if 1 +#if 0 nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext, aDesiredSize, aReflowState, aStatus); @@ -362,6 +362,12 @@ nsGfxButtonControlFrame::Reflow(nsIPresContext* aPresContext, aPresContext->GetCompatibilityMode(&mode); if (mode == eCompatibility_NavQuirks) { + // nsHTMLButtonControlFrame::Reflow registers it for Standard Mode + // and sets up mPresContext + if (eReflowReason_Initial == aReflowState.reason) { + mPresContext = aPresContext; + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); + } // Do NavQuirks Sizing and layout rv = DoNavQuirksReflow(aPresContext, aDesiredSize, aReflowState, aStatus); } else { diff --git a/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp b/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp index 135aaa523b0..423eac39b71 100644 --- a/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp @@ -27,9 +27,12 @@ #include "nsFormFrame.h" #include "nsIFormControl.h" #include "nsIContent.h" -#include "nsWidgetsCID.h" #include "nsIComponentManager.h" +#include "nsHTMLAtoms.h" +#include "nsINameSpaceManager.h" +#include "nsIPresState.h" +//------------------------------------------------------------ nsresult NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) { @@ -46,18 +49,156 @@ NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) } +//------------------------------------------------------------ // Initialize GFX-rendered state nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame() : mChecked(eOff) { } +//---------------------------------------------------------------------- +// nsISupports +//---------------------------------------------------------------------- +// Frames are not refcounted, no need to AddRef +NS_IMETHODIMP +nsGfxCheckboxControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) +{ + NS_ASSERTION(aInstancePtr, "QueryInterface requires a non-NULL destination!"); + if ( !aInstancePtr ) + return NS_ERROR_NULL_POINTER; + if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void*)(nsIStatefulFrame*) this; + return NS_OK; + } + return nsFormControlFrame::QueryInterface(aIID, aInstancePtr); +} +//------------------------------------------------------------ +// +// Init +// +// We need to override this in order to see if we're a tristate checkbox. +// +NS_IMETHODIMP +nsGfxCheckboxControlFrame::Init(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aContext, + nsIFrame* aPrevInFlow) +{ + nsFormControlFrame::Init ( aPresContext, aContent, aParent, aContext, aPrevInFlow ); + + // figure out if we're a tristate at the start. This may change later on once + // we've been running for a while, so more code is in AttributeChanged() to pick + // that up. Regardless, we need this check when initializing. + nsAutoString value; + nsresult res = mContent->GetAttribute ( kNameSpaceID_None, GetTristateAtom(), value ); + if ( res == NS_CONTENT_ATTR_HAS_VALUE ) + mIsTristate = PR_TRUE; + + // give the attribute a default value so it's always present, if we're a tristate + if ( IsTristateCheckbox() ) + mContent->SetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), "0", PR_FALSE ); + + return NS_OK; +} + +//------------------------------------------------------------ +// +// GetTristateAtom [static] +// +// Use a lazily instantiated static initialization scheme to create an atom that +// represents the attribute set when this should be a tri-state checkbox. +// +// Does NOT addref! +// +nsIAtom* +nsGfxCheckboxControlFrame :: GetTristateAtom ( ) +{ + return nsHTMLAtoms::moz_tristate; +} + +//------------------------------------------------------------ +// +// GetTristateValueAtom [static] +// +// Use a lazily instantiated static initialization scheme to create an atom that +// represents the attribute that holds the value when the button is a tri-state (since +// we can't use "checked"). +// +// Does NOT addref! +// +nsIAtom* +nsGfxCheckboxControlFrame :: GetTristateValueAtom ( ) +{ + return nsHTMLAtoms::moz_tristatevalue; +} + +//------------------------------------------------------------ +// +// AttributeChanged +// +// Override to check for the attribute that determines if we're a normal or a +// tristate checkbox. If we notice a switch from one to the other, we need +// to adjust the proper attributes in the content model accordingly. +// +// Also, since the value of a tri-state is kept in a separate attribute (we +// can't use "checked" because it's a boolean), we have to notice it changing +// here. +// +NS_IMETHODIMP +nsGfxCheckboxControlFrame::AttributeChanged(nsIPresContext* aPresContext, + nsIContent* aChild, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aHint) +{ + if ( aAttribute == GetTristateAtom() ) { + nsAutoString value; + nsresult res = mContent->GetAttribute ( kNameSpaceID_None, GetTristateAtom(), value ); + PRBool isNowTristate = (res == NS_CONTENT_ATTR_HAS_VALUE); + if ( isNowTristate != mIsTristate ) + SwitchModesWithEmergencyBrake(aPresContext, isNowTristate); + } + else if ( aAttribute == GetTristateValueAtom() ) { + // ignore this change if we're not a tri-state checkbox + if ( IsTristateCheckbox() ) { + nsAutoString value; + nsresult res = mContent->GetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), value ); + if ( res == NS_CONTENT_ATTR_HAS_VALUE ) + SetCheckboxControlFrameState(aPresContext, value); + } + } + else + return nsFormControlFrame::AttributeChanged(aPresContext, aChild, aNameSpaceID, aAttribute, aHint); + + return NS_OK; +} + +//------------------------------------------------------------ +// +// InitializeControl +// +// Set the default checked state of the checkbox. +// +void +nsGfxCheckboxControlFrame::InitializeControl(nsIPresContext* aPresContext) +{ + nsFormControlFrame::InitializeControl(aPresContext); + + PRBool checked = PR_FALSE; + nsresult result = GetDefaultCheckState(&checked); + if (NS_CONTENT_ATTR_HAS_VALUE == result) { + SetCheckboxState (aPresContext, checked ? eOn : eOff ); + } +} + +//------------------------------------------------------------ void nsGfxCheckboxControlFrame::PaintCheckBox(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsFramePaintLayer aWhichLayer) + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) { aRenderingContext.PushState(); @@ -111,6 +252,7 @@ nsGfxCheckboxControlFrame::PaintCheckBox(nsIPresContext* aPresContext, } +//------------------------------------------------------------ // // PaintMixedMark // @@ -155,6 +297,7 @@ nsGfxCheckboxControlFrame::PaintMixedMark ( nsIRenderingContext& aRenderingConte } // PaintMixedMark +//------------------------------------------------------------ NS_METHOD nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -167,7 +310,7 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext, return NS_OK; // Paint the background - Inherited::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { // Paint the checkmark PaintCheckBox(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); @@ -176,20 +319,232 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext, } -nsCheckboxControlFrame::CheckState -nsGfxCheckboxControlFrame :: GetCheckboxState ( ) +//------------------------------------------------------------ +nsGfxCheckboxControlFrame::CheckState +nsGfxCheckboxControlFrame::GetCheckboxState ( ) { return mChecked; } +//------------------------------------------------------------ void -nsGfxCheckboxControlFrame :: SetCheckboxState (nsIPresContext* aPresContext, - nsCheckboxControlFrame::CheckState aValue ) +nsGfxCheckboxControlFrame::SetCheckboxState (nsIPresContext* aPresContext, + nsGfxCheckboxControlFrame::CheckState aValue ) { mChecked = aValue; nsFormControlHelper::ForceDrawFrame(aPresContext, this); } +//------------------------------------------------------------ +void nsGfxCheckboxControlFrame::GetCheckboxControlFrameState(nsString& aValue) +{ + CheckStateToString(GetCheckboxState(), aValue); +} + + +//------------------------------------------------------------ +void nsGfxCheckboxControlFrame::SetCheckboxControlFrameState(nsIPresContext* aPresContext, + const nsString& aValue) +{ + CheckState state = StringToCheckState(aValue); + SetCheckboxState(aPresContext, state); +} + +//------------------------------------------------------------ +NS_IMETHODIMP nsGfxCheckboxControlFrame::SetProperty(nsIPresContext* aPresContext, + nsIAtom* aName, + const nsString& aValue) +{ + if (nsHTMLAtoms::checked == aName) + SetCheckboxControlFrameState(aPresContext, aValue); + else + return nsFormControlFrame::SetProperty(aPresContext, aName, aValue); + + return NS_OK; +} + + +//------------------------------------------------------------ +NS_IMETHODIMP nsGfxCheckboxControlFrame::GetProperty(nsIAtom* aName, nsString& aValue) +{ + if (nsHTMLAtoms::checked == aName) + GetCheckboxControlFrameState(aValue); + else + return nsFormControlFrame::GetProperty(aName, aValue); + + return NS_OK; +} + +//------------------------------------------------------------ +PRInt32 +nsGfxCheckboxControlFrame::GetMaxNumValues() +{ + return 1; +} + +//------------------------------------------------------------ +PRBool +nsGfxCheckboxControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, + nsString* aValues, nsString* aNames) +{ + nsAutoString name; + nsresult nameResult = GetName(&name); + if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_HAS_VALUE != nameResult)) { + return PR_FALSE; + } + + PRBool result = PR_TRUE; + CheckState state = GetCheckboxState(); + + nsAutoString value; + nsresult valueResult = GetValue(&value); + + if (eOn != state) { + result = PR_FALSE; + } else { + if (NS_CONTENT_ATTR_HAS_VALUE != valueResult) { + aValues[0] = "on"; + } else { + aValues[0] = value; + } + aNames[0] = name; + aNumValues = 1; + } + + return result; +} + +//------------------------------------------------------------ +void +nsGfxCheckboxControlFrame::Reset(nsIPresContext* aPresContext) +{ + PRBool checked; + GetDefaultCheckState(&checked); + SetCheckboxState (aPresContext, checked ? eOn : eOff ); +} + + +//------------------------------------------------------------ +// +// CheckStateToString +// +// Converts from a CheckState to a string +// +void +nsGfxCheckboxControlFrame::CheckStateToString ( CheckState inState, nsString& outStateAsString ) +{ + switch ( inState ) { + case eOn: + outStateAsString = NS_STRING_TRUE; + break; + + case eOff: + outStateAsString = NS_STRING_FALSE; + break; + + case eMixed: + outStateAsString = "2"; + break; + } +} // CheckStateToString + + +//------------------------------------------------------------ +// +// StringToCheckState +// +// Converts from a string to a CheckState enum +// +nsGfxCheckboxControlFrame::CheckState +nsGfxCheckboxControlFrame::StringToCheckState ( const nsString & aStateAsString ) +{ + if ( aStateAsString == NS_STRING_TRUE ) + return eOn; + else if ( aStateAsString == NS_STRING_FALSE ) + return eOff; + + // not true and not false means mixed + return eMixed; + +} // StringToCheckState + + +//------------------------------------------------------------ +// +// SwitchModesWithEmergencyBrake +// +// Since we use an attribute to decide if we're a tristate box or not, this can change +// at any time. Since we have to use separate attributes to store the values depending +// on the mode, we have to convert from one to the other. +// +void +nsGfxCheckboxControlFrame::SwitchModesWithEmergencyBrake ( nsIPresContext* aPresContext, + PRBool inIsNowTristate ) +{ + if ( inIsNowTristate ) { + // we were a normal checkbox, and now we're a tristate. That means that the + // state of the checkbox was in "checked" and needs to be copied over into + // our parallel attribute. + nsAutoString value; + CheckStateToString ( GetCheckboxState(), value ); + mContent->SetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), value, PR_FALSE ); + } + else { + // we were a tri-state checkbox, and now we're a normal checkbox. The current + // state is already up to date (because it's always up to date). We just have + // to make sure it's not mixed. If it is, just set it to checked. Remove our + // parallel attribute so that we're nice and HTML4 compliant. + if ( GetCheckboxState() == eMixed ) + SetCheckboxState(aPresContext, eOn); + mContent->UnsetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), PR_FALSE ); + } + + // switch! + mIsTristate = inIsNowTristate; + +} // SwitchModesWithEmergencyBrake + +//---------------------------------------------------------------------- +// nsIStatefulFrame +//---------------------------------------------------------------------- +NS_IMETHODIMP nsGfxCheckboxControlFrame::GetStateType(nsIPresContext* aPresContext, + nsIStatefulFrame::StateType* aStateType) +{ + *aStateType=nsIStatefulFrame::eCheckboxType; + return NS_OK; +} + +NS_IMETHODIMP nsGfxCheckboxControlFrame::SaveState(nsIPresContext* aPresContext, + nsIPresState** aState) +{ + // Construct a pres state. + NS_NewPresState(aState); // The addref happens here. + + // This string will hold a single item, whether or not we're checked. + nsAutoString stateString; + GetCheckboxControlFrameState(stateString); + (*aState)->SetStateProperty("checked", stateString); + + return NS_OK; +} + +NS_IMETHODIMP nsGfxCheckboxControlFrame::RestoreState(nsIPresContext* aPresContext, + nsIPresState* aState) +{ + if (!mDidInit) { + mPresContext = aPresContext; + InitializeControl(aPresContext); + mDidInit = PR_TRUE; + } + nsAutoString string; + aState->GetStateProperty("checked", string); + SetCheckboxControlFrameState(aPresContext, string); + return NS_OK; +} + +//------------------------------------------------------------ +// Extra Debug Methods +//------------------------------------------------------------ #ifdef DEBUG_rodsXXX NS_IMETHODIMP nsGfxCheckboxControlFrame::Reflow(nsIPresContext* aPresContext, @@ -197,7 +552,7 @@ nsGfxCheckboxControlFrame::Reflow(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { - nsresult rv = nsNativeFormControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); + nsresult rv = nsFormControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); COMPARE_QUIRK_SIZE("nsGfxCheckboxControlFrame", 13, 13) return rv; diff --git a/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.h b/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.h index 588deb65d03..c227a02159a 100644 --- a/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.h +++ b/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.h @@ -22,13 +22,13 @@ #ifndef nsGfxCheckboxControlFrame_h___ #define nsGfxCheckboxControlFrame_h___ -#include "nsCheckboxControlFrame.h" +#include "nsFormControlFrame.h" +#include "nsIStatefulFrame.h" -class nsGfxCheckboxControlFrame : public nsCheckboxControlFrame { -private: - typedef nsCheckboxControlFrame Inherited; - +class nsGfxCheckboxControlFrame : public nsFormControlFrame, + public nsIStatefulFrame +{ public: nsGfxCheckboxControlFrame(); @@ -37,17 +37,43 @@ public: return MakeFrameName("CheckboxControl", aResult); } #endif + // this should be protected, but VC6 is lame. + enum CheckState { eOff, eOn, eMixed } ; - // overrides base class HandleEvent to do nothing - // events are handled by the DOM - NS_IMETHOD HandleEvent(nsIPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) { return NS_OK; } + NS_IMETHOD Init(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aContext, + nsIFrame* aPrevInFlow) ; + + NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext, + nsIContent* aChild, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aHint) ; NS_IMETHOD Paint(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer); + + void InitializeControl(nsIPresContext* aPresContext); + + // nsIFormControlFrame + NS_IMETHOD SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsString& aValue); + NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue); + virtual void Reset(nsIPresContext* aPresContext); + virtual PRInt32 GetMaxNumValues(); + virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, + nsString* aValues, nsString* aNames); + + // nsIStatefulFrame + NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + NS_IMETHOD GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType); + NS_IMETHOD SaveState(nsIPresContext* aPresContext, nsIPresState** aState); + NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState); + + #ifdef DEBUG_rodsXXX NS_IMETHOD Reflow(nsIPresContext* aCX, nsHTMLReflowMetrics& aDesiredSize, @@ -56,8 +82,35 @@ public: #endif protected: - virtual CheckState GetCheckboxState(); - virtual void SetCheckboxState(nsIPresContext* aPresContext, CheckState aValue); + + // native/gfx implementations need to implement needs. + CheckState GetCheckboxState(); + void SetCheckboxState(nsIPresContext* aPresContext, CheckState aValue); + + // Utility methods for implementing SetProperty/GetProperty + void SetCheckboxControlFrameState(nsIPresContext* aPresContext, + const nsString& aValue); + void GetCheckboxControlFrameState(nsString& aValue); + + // utility routine for converting from DOM values to internal enum + void CheckStateToString ( CheckState inState, nsString& outStateAsString ) ; + CheckState StringToCheckState ( const nsString & aStateAsString ) ; + + // figure out if we're a tri-state checkbox. + PRBool IsTristateCheckbox ( ) const { return mIsTristate; } + + // we just became a tri-state, or we just lost tri-state status. fix up + // the attributes for the new mode. + void SwitchModesWithEmergencyBrake ( nsIPresContext* aPresContext, + PRBool inIsNowTristate ) ; + + // for tri-state checkbox. meaningless for normal HTML + PRBool mIsTristate; + + static nsIAtom* GetTristateAtom() ; + static nsIAtom* GetTristateValueAtom() ; + +protected: virtual void PaintCheckBox(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -68,7 +121,11 @@ protected: //GFX-rendered state variables CheckState mChecked; - + +private: + NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; } + NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; } + }; #endif diff --git a/mozilla/layout/html/forms/src/nsGfxListControlFrame.cpp b/mozilla/layout/html/forms/src/nsGfxListControlFrame.cpp index 94fa011eee9..3c044ce848c 100644 --- a/mozilla/layout/html/forms/src/nsGfxListControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsGfxListControlFrame.cpp @@ -125,6 +125,8 @@ nsGfxListControlFrame::nsGfxListControlFrame() //--------------------------------------------------------- nsGfxListControlFrame::~nsGfxListControlFrame() { + nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); + // if list is dropped down // make sure it gets rolled up if (IsInDropDownMode()) { @@ -375,6 +377,7 @@ nsGfxListControlFrame::Reflow(nsIPresContext* aPresContext, // Add the list frame as a child of the form if (IsInDropDownMode() == PR_FALSE && !mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this)); } @@ -583,8 +586,8 @@ nsGfxListControlFrame::Reflow(nsIPresContext* aPresContext, // for the list frame and use that as the max/minimum size for the contents if (visibleHeight == 0) { nsCOMPtr fontMet; - nsFormControlHelper::GetFrameFontFM(aPresContext, this, getter_AddRefs(fontMet)); - if (fontMet) { + nsresult res = nsFormControlHelper::GetFrameFontFM(aPresContext, this, getter_AddRefs(fontMet)); + if (NS_SUCCEEDED(res) && fontMet) { aReflowState.rendContext->SetFont(fontMet); fontMet->GetHeight(visibleHeight); mMaxHeight = visibleHeight; @@ -654,8 +657,7 @@ NS_IMETHODIMP nsGfxListControlFrame::GetFont(nsIPresContext* aPresContext, const nsFont*& aFont) { - nsFormControlHelper::GetFont(this, aPresContext, mStyleContext, aFont); - return NS_OK; + return nsFormControlHelper::GetFont(this, aPresContext, mStyleContext, aFont); } @@ -1459,10 +1461,7 @@ nsGfxListControlFrame::SetContentSelected(PRInt32 aIndex, PRBool aSelected) if (aSelected) { DisplaySelected(content); // Now that it is selected scroll to it - nsCOMPtr content(do_QueryInterface(content)); - if (content) { - ScrollToFrame(content); - } + ScrollToFrame(content); } else { DisplayDeselected(content); } diff --git a/mozilla/layout/html/forms/src/nsGfxListControlFrame.h b/mozilla/layout/html/forms/src/nsGfxListControlFrame.h index ea8240770a3..927e75bf52f 100644 --- a/mozilla/layout/html/forms/src/nsGfxListControlFrame.h +++ b/mozilla/layout/html/forms/src/nsGfxListControlFrame.h @@ -89,7 +89,7 @@ public: NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue); NS_IMETHOD GetMultiple(PRBool* aResult, nsIDOMHTMLSelectElement* aSelect = nsnull); NS_IMETHOD GetFont(nsIPresContext* aPresContext, - const nsFont*& aFont); + const nsFont*& aFont); NS_IMETHOD GetFormContent(nsIContent*& aContent) const; virtual void SetFocus(PRBool aOn = PR_TRUE, PRBool aRepaint = PR_FALSE); diff --git a/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.cpp b/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.cpp index 04073d8cf0e..e005f53b162 100644 --- a/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.cpp @@ -21,7 +21,6 @@ */ #include "nsGfxRadioControlFrame.h" -#include "nsIRadioButton.h" #include "nsHTMLAtoms.h" #include "nsHTMLParts.h" #include "nsFormFrame.h" @@ -31,6 +30,8 @@ #include "nsIComponentManager.h" #include "nsCOMPtr.h" #include "nsCSSRendering.h" +#include "nsIPresState.h" +#include "nsINameSpaceManager.h" nsresult @@ -57,11 +58,31 @@ nsGfxRadioControlFrame::nsGfxRadioControlFrame() nsGfxRadioControlFrame::~nsGfxRadioControlFrame() { - NS_IF_RELEASE(mRadioButtonFaceStyle); + NS_IF_RELEASE(mRadioButtonFaceStyle); } -//-------------------------------------------------------------- +// Frames are not refcounted, no need to AddRef +NS_IMETHODIMP +nsGfxRadioControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) +{ + NS_PRECONDITION(0 != aInstancePtr, "null ptr"); + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(NS_GET_IID(nsIRadioControlFrame))) { + *aInstancePtr = (void*) ((nsIRadioControlFrame*) this); + return NS_OK; + } + if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void*) ((nsIStatefulFrame*) this); + return NS_OK; + } + + return nsFormControlFrame::QueryInterface(aIID, aInstancePtr); +} + +//-------------------------------------------------------------- NS_IMETHODIMP nsGfxRadioControlFrame::GetAdditionalStyleContext(PRInt32 aIndex, nsIStyleContext** aStyleContext) const @@ -82,6 +103,7 @@ nsGfxRadioControlFrame::GetAdditionalStyleContext(PRInt32 aIndex, return NS_OK; } +//-------------------------------------------------------------- NS_IMETHODIMP nsGfxRadioControlFrame::SetAdditionalStyleContext(PRInt32 aIndex, nsIStyleContext* aStyleContext) @@ -99,7 +121,69 @@ nsGfxRadioControlFrame::SetAdditionalStyleContext(PRInt32 aIndex, return NS_OK; } +//-------------------------------------------------------------- +NS_IMETHODIMP nsGfxRadioControlFrame::SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsString& aValue) +{ + if (nsHTMLAtoms::checked == aName) { + PRBool state = (aValue == NS_STRING_TRUE) ? PR_TRUE : PR_FALSE; + SetRadioState(aPresContext, state); + if (mFormFrame) { + mFormFrame->OnRadioChecked(aPresContext, *this, state); + } + } + else { + return nsFormControlFrame::SetProperty(aPresContext, aName, aValue); + } + + return NS_OK; +} + +//-------------------------------------------------------------- +NS_IMETHODIMP nsGfxRadioControlFrame::GetProperty(nsIAtom* aName, nsString& aValue) +{ + // Return the value of the property from the widget it is not null. + // If is null, assume the widget is GFX-rendered and return a member variable instead. + + if (nsHTMLAtoms::checked == aName) { + nsFormControlHelper::GetBoolString(GetRadioState(), aValue); + } else { + return nsFormControlFrame::GetProperty(aName, aValue); + } + + return NS_OK; +} + +//-------------------------------------------------------------- +PRBool +nsGfxRadioControlFrame::GetChecked(PRBool aGetInitialValue) +{ + PRBool checked = PR_FALSE; + if (PR_TRUE == aGetInitialValue) { + GetDefaultCheckState(&checked); + } + else { + GetCurrentCheckState(&checked); + } + return(checked); +} + +//-------------------------------------------------------------- +void +nsGfxRadioControlFrame::SetChecked(nsIPresContext* aPresContext, PRBool aValue, PRBool aSetInitialValue) +{ + if (aSetInitialValue) { + if (aValue) { + mContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::checked, nsAutoString("1"), PR_FALSE); // XXX should be "empty" value + } else { + mContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::checked, nsAutoString("0"), PR_FALSE); + } + } + + SetRadioState(aPresContext, aValue); +} + +//-------------------------------------------------------------- NS_IMETHODIMP nsGfxRadioControlFrame::SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioButtonFaceStyleContext) { @@ -108,6 +192,47 @@ nsGfxRadioControlFrame::SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioBu return NS_OK; } +//-------------------------------------------------------------- +PRBool +nsGfxRadioControlFrame::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; + } + + PRBool state = GetRadioState(); + + if(PR_TRUE != state) { + return PR_FALSE; + } + + nsAutoString value; + result = GetValue(&value); + + if (NS_CONTENT_ATTR_HAS_VALUE == result) { + aValues[0] = value; + } else { + aValues[0] = "on"; + } + aNames[0] = name; + aNumValues = 1; + + return PR_TRUE; +} + +//-------------------------------------------------------------- +void +nsGfxRadioControlFrame::Reset(nsIPresContext* aPresContext) +{ + PRBool checked = PR_TRUE; + GetDefaultCheckState(&checked); + SetCurrentCheckState(checked); +} + +//-------------------------------------------------------------- void nsGfxRadioControlFrame::PaintRadioButton(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -141,6 +266,7 @@ nsGfxRadioControlFrame::PaintRadioButton(nsIPresContext* aPresContext, } } +//-------------------------------------------------------------- NS_METHOD nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -153,7 +279,7 @@ nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext, return NS_OK; // Paint the background - Inherited::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { PaintRadioButton(aPresContext, aRenderingContext, aDirtyRect); @@ -162,17 +288,79 @@ nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext, } +//-------------------------------------------------------------- PRBool nsGfxRadioControlFrame::GetRadioState() { return mChecked; } +//-------------------------------------------------------------- void nsGfxRadioControlFrame::SetRadioState(nsIPresContext* aPresContext, PRBool aValue) { mChecked = aValue; nsFormControlHelper::ForceDrawFrame(aPresContext, this); } +void +nsGfxRadioControlFrame::InitializeControl(nsIPresContext* aPresContext) +{ + nsFormControlFrame::InitializeControl(aPresContext); + + // set the widget to the initial state + PRBool checked = PR_FALSE; + nsresult result = GetDefaultCheckState(&checked); + if (NS_CONTENT_ATTR_HAS_VALUE == result) { + SetRadioState(aPresContext, checked); + } +} + +//---------------------------------------------------------------------- +// nsIStatefulFrame +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsGfxRadioControlFrame::GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType) +{ + *aStateType = nsIStatefulFrame::eRadioType; + return NS_OK; +} + +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsGfxRadioControlFrame::SaveState(nsIPresContext* aPresContext, nsIPresState** aState) +{ + // Construct a pres state. + NS_NewPresState(aState); // The addref happens here. + + // This string will hold a single item, whether or not we're checked. + nsAutoString stateString; + nsFormControlHelper::GetBoolString(GetRadioState(), stateString); + (*aState)->SetStateProperty("checked", stateString); + + return NS_OK; +} + + + +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsGfxRadioControlFrame::RestoreState(nsIPresContext* aPresContext, nsIPresState* aState) +{ + if (!mDidInit) { + mPresContext = aPresContext; + InitializeControl(aPresContext); + mDidInit = PR_TRUE; + } + nsAutoString string; + aState->GetStateProperty("checked", string); + PRBool state = (string == NS_STRING_TRUE) ? PR_TRUE : PR_FALSE; + SetRadioState(aPresContext, state); + return NS_OK; +} + + +//---------------------------------------------------------------------- +// Extra Debug Helper Methods +//---------------------------------------------------------------------- #ifdef DEBUG_rodsXXX NS_IMETHODIMP nsGfxRadioControlFrame::Reflow(nsIPresContext* aPresContext, diff --git a/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.h b/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.h index 73ac07ce117..e40ab27e3f8 100644 --- a/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.h +++ b/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.h @@ -23,25 +23,36 @@ #ifndef nsGfxRadioControlFrame_h___ #define nsGfxRadioControlFrame_h___ -#include "nsRadioControlFrame.h" +#include "nsFormControlFrame.h" +#include "nsIStatefulFrame.h" +#include "nsIRadioControlFrame.h" // nsGfxRadioControlFrame #define NS_GFX_RADIO_CONTROL_FRAME_FACE_CONTEXT_INDEX 0 // for additional style contexts #define NS_GFX_RADIO_CONTROL_FRAME_LAST_CONTEXT_INDEX 0 -class nsGfxRadioControlFrame : public nsRadioControlFrame +class nsGfxRadioControlFrame : public nsFormControlFrame, + public nsIStatefulFrame, + public nsIRadioControlFrame + { private: - typedef nsRadioControlFrame Inherited; public: nsGfxRadioControlFrame(); ~nsGfxRadioControlFrame(); //nsIRadioControlFrame methods + NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); NS_IMETHOD SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioButtonFaceStyleContext); + + virtual PRBool GetChecked(PRBool aGetInitialValue); + virtual void SetChecked(nsIPresContext* aPresContext, PRBool aValue, PRBool aSetInitialValue); + + void InitializeControl(nsIPresContext* aPresContext); + NS_IMETHOD GetAdditionalStyleContext(PRInt32 aIndex, nsIStyleContext** aStyleContext) const; NS_IMETHOD SetAdditionalStyleContext(PRInt32 aIndex, @@ -67,6 +78,21 @@ public: nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); + virtual PRInt32 GetMaxNumValues() { return 1; } + + virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, + nsString* aValues, nsString* aNames); + virtual void Reset(nsIPresContext* aPresContext); + + // nsIFormControlFrame + NS_IMETHOD SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsString& aValue); + NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue); + + //nsIStatefulFrame + NS_IMETHOD GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType); + NS_IMETHOD SaveState(nsIPresContext* aPresContext, nsIPresState** aState); + NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState); + ///XXX: End o the temporary methods #ifdef DEBUG_rodsXXX NS_IMETHOD Reflow(nsIPresContext* aCX, diff --git a/mozilla/layout/html/forms/src/nsGfxTextControlFrame.cpp b/mozilla/layout/html/forms/src/nsGfxTextControlFrame.cpp index 9a599c5906b..1caa005a774 100644 --- a/mozilla/layout/html/forms/src/nsGfxTextControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsGfxTextControlFrame.cpp @@ -31,7 +31,6 @@ #include "nsIHTMLContent.h" #include "nsHTMLIIDs.h" #include "nsITextWidget.h" -#include "nsITextAreaWidget.h" #include "nsWidgetsCID.h" #include "nsSize.h" #include "nsString.h" @@ -81,6 +80,7 @@ #include "nsIPresShell.h" #include "nsIEventStateManager.h" #include "nsStyleUtil.h" +#include "nsLinebreakConverter.h" // for anonymous content and frames #include "nsHTMLParts.h" @@ -100,9 +100,7 @@ static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID); static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID); static NS_DEFINE_IID(kTextCID, NS_TEXTFIELD_CID); -static NS_DEFINE_IID(kTextAreaCID, NS_TEXTAREA_CID); static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID); -static NS_DEFINE_IID(kITextAreaWidgetIID, NS_ITEXTAREAWIDGET_IID); static NS_DEFINE_IID(kIDOMHTMLTextAreaElementIID, NS_IDOMHTMLTEXTAREAELEMENT_IID); static NS_DEFINE_IID(kIDOMHTMLInputElementIID, NS_IDOMHTMLINPUTELEMENT_IID); @@ -189,12 +187,17 @@ nsGfxTextControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) NS_PRECONDITION(0 != aInstancePtr, "null ptr"); if (NULL == aInstancePtr) { return NS_ERROR_NULL_POINTER; + } else if (aIID.Equals(NS_GET_IID(nsIGfxTextControlFrame))) { *aInstancePtr = (void*)(nsIGfxTextControlFrame*) this; + return NS_OK; + + } else if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) { + *aInstancePtr = (void*)(nsIStatefulFrame*) this; return NS_OK; } - return nsTextControlFrame::QueryInterface(aIID, aInstancePtr); + return nsFormControlFrame::QueryInterface(aIID, aInstancePtr); } NS_IMETHODIMP @@ -205,7 +208,7 @@ nsGfxTextControlFrame::Init(nsIPresContext* aPresContext, nsIFrame* aPrevInFlow) { mFramePresContext = aPresContext; - return (nsTextControlFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow)); + return nsFormControlFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); } NS_IMETHODIMP @@ -333,6 +336,8 @@ nsGfxTextControlFrame::nsGfxTextControlFrame() nsGfxTextControlFrame::~nsGfxTextControlFrame() { + nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); + nsresult result; if (mDisplayFrame) { mFrameConstructor->RemoveMappingsForFrameSubtree(mFramePresContext, @@ -1080,6 +1085,12 @@ void nsGfxTextControlFrame::CalcSizeOfSubDocInTwips(const nsMargin &aBorder, aSubBounds.height = (aFrameSize.height - (aBorder.top + aPadding.top + aBorder.bottom + aPadding.bottom)); } +PRInt32 +nsGfxTextControlFrame::GetMaxNumValues() +{ + return 1; +} + PRBool nsGfxTextControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, nsString* aValues, nsString* aNames) @@ -1990,6 +2001,8 @@ nsGfxTextControlFrame::Reflow(nsIPresContext* aPresContext, // add ourself as an nsIFormControlFrame if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { + mPresContext = aPresContext; + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this)); } @@ -2991,7 +3004,7 @@ nsGfxTextControlFrame::GetAdditionalChildListName(PRInt32 aIndex, return NS_OK; } - return nsTextControlFrame::GetAdditionalChildListName(aIndex, aListName); + return nsLeafFrame::GetAdditionalChildListName(aIndex, aListName); } NS_IMETHODIMP @@ -3004,7 +3017,7 @@ nsGfxTextControlFrame::FirstChild(nsIPresContext* aPresContext, return NS_OK; } - return nsTextControlFrame::FirstChild(aPresContext, aListName, aFirstChild); + return nsLeafFrame::FirstChild(aPresContext, aListName, aFirstChild); } NS_IMETHODIMP @@ -3015,7 +3028,58 @@ nsGfxTextControlFrame::Destroy(nsIPresContext* aPresContext) mDisplayFrame->Destroy(aPresContext); mDisplayFrame=nsnull; } - return nsTextControlFrame::Destroy(aPresContext); + return nsLeafFrame::Destroy(aPresContext); +} +//---------------------------------------------------------------------- +// nsIStatefulFrame +//---------------------------------------------------------------------- +NS_IMETHODIMP +nsGfxTextControlFrame::GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType) +{ + *aStateType = nsIStatefulFrame::eTextType; + return NS_OK; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::SaveState(nsIPresContext* aPresContext, nsIPresState** aState) +{ + // Construct a pres state. + NS_NewPresState(aState); // The addref happens here. + + nsAutoString theString; + nsresult res = GetProperty(nsHTMLAtoms::value, theString); + if (NS_SUCCEEDED(res)) { + char* chars = theString.ToNewCString(); + if (chars) { + + // GetProperty returns platform-native line breaks. We must convert + // these to content line breaks. + char* newChars = nsLinebreakConverter::ConvertLineBreaks(chars, + nsLinebreakConverter::eLinebreakPlatform, nsLinebreakConverter::eLinebreakContent); + if (newChars) { + nsCRT::free(chars); + chars = newChars; + } + + (*aState)->SetStateProperty("value", nsAutoString(chars)); + + nsCRT::free(chars); + } else { + res = NS_ERROR_OUT_OF_MEMORY; + } + } + + (*aState)->SetStateProperty("value", theString); + return res; +} + +NS_IMETHODIMP +nsGfxTextControlFrame::RestoreState(nsIPresContext* aPresContext, nsIPresState* aState) +{ + nsAutoString stateString; + aState->GetStateProperty("value", stateString); + nsresult res = SetProperty(aPresContext, nsHTMLAtoms::value, stateString); + return res; } #ifdef NS_DEBUG diff --git a/mozilla/layout/html/forms/src/nsGfxTextControlFrame.h b/mozilla/layout/html/forms/src/nsGfxTextControlFrame.h index 81b28ab0e6b..ed7063c5eae 100644 --- a/mozilla/layout/html/forms/src/nsGfxTextControlFrame.h +++ b/mozilla/layout/html/forms/src/nsGfxTextControlFrame.h @@ -27,7 +27,6 @@ #include "nsCOMPtr.h" #include "nsCWeakReference.h" #include "nsFormControlFrame.h" -#include "nsTextControlFrame.h" #include "nsIDocumentLoaderObserver.h" #include "nsIEditor.h" #include "nsIDocumentObserver.h" @@ -46,6 +45,8 @@ #include "nsIWebShell.h" #include "nsIViewManager.h" +#include "nsIStatefulFrame.h" + #include "nsCSSFrameConstructor.h" class nsIFrame; @@ -377,7 +378,8 @@ protected: * and attaches an editor to the subdocument. ******************************************************************************/ -class nsGfxTextControlFrame : public nsTextControlFrame, +class nsGfxTextControlFrame : public nsFormControlFrame, + public nsIStatefulFrame, public nsIGfxTextControlFrame { private: @@ -420,9 +422,6 @@ public: NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue); virtual void SetFocus(PRBool aOn = PR_TRUE, PRBool aRepaint = PR_FALSE); virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext* aPresContext); - virtual void PostCreateWidget(nsIPresContext* aPresContext, - nscoord& aWidth, - nscoord& aHeight) {}; /** handler for attribute changes to mContent */ NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext, @@ -451,6 +450,7 @@ public: virtual void EnterPressed(nsIPresContext* aPresContext) ; + virtual PRInt32 GetMaxNumValues(); virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, nsString* aValues, nsString* aNames); virtual void Reset(nsIPresContext* aPresContext); @@ -509,7 +509,14 @@ public: NS_IMETHOD GetWebShell(nsIWebShell **aWebShell); NS_IMETHOD SetInnerFocus(); + //nsIStatefulFrame + NS_IMETHOD GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType); + NS_IMETHOD SaveState(nsIPresContext* aPresContext, nsIPresState** aState); + NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState); + + protected: + PRInt32 GetDefaultColumnWidth() const { return (PRInt32)(20); } // this was DEFAULT_PIXEL_WIDTH /** calculate the inner region of the text control (size - border and padding) in pixels */ virtual void CalcSizeOfSubDocInTwips(const nsMargin &aBorder, diff --git a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp index e4d3a18f7c9..e67c837e849 100644 --- a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp @@ -92,6 +92,7 @@ nsHTMLButtonControlFrame::nsHTMLButtonControlFrame() nsHTMLButtonControlFrame::~nsHTMLButtonControlFrame() { + nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); if (mFormFrame) { mFormFrame->RemoveFormControlFrame(*this); mFormFrame = nsnull; @@ -513,15 +514,18 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext* aPresContext, nsReflowStatus& aStatus) { if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { + mPresContext = aPresContext; + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this)); } +#if 0 nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext, aDesiredSize, aReflowState, aStatus); if (NS_SUCCEEDED(skiprv)) { return skiprv; } - +#endif // XXX remove the following when the reflow state is fixed ButtonHack((nsHTMLReflowState&)aReflowState, "html4 button"); @@ -662,10 +666,12 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext* aPresContext, //aDesiredSize.width += aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right; //aDesiredSize.height += aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom; +#if 1 //adjust our max element size, if necessary if (aDesiredSize.maxElementSize) { aDesiredSize.AddBorderPaddingToMaxElementSize(aReflowState.mComputedBorderPadding); } +#endif aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.descent = 0; @@ -684,11 +690,10 @@ nsHTMLButtonControlFrame::GetSkipSides() const } NS_IMETHODIMP -nsHTMLButtonControlFrame::GetFont(nsIPresContext* aPresContext, - const nsFont*& aFont) +nsHTMLButtonControlFrame::GetFont(nsIPresContext* aPresContext, + const nsFont*& aFont) { - nsFormControlHelper::GetFont(this, aPresContext, mStyleContext, aFont); - return NS_OK; + return nsFormControlHelper::GetFont(this, aPresContext, mStyleContext, aFont); } NS_IMETHODIMP diff --git a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.h b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.h index 4c902e08dd0..84ea27d4f86 100644 --- a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.h +++ b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.h @@ -156,6 +156,8 @@ protected: PRBool mDidInit; nsButtonFrameRenderer mRenderer; + nsCOMPtr mPresContext; + //Resize Reflow OpitmizationSize; nsSize mCacheSize; nsSize mCachedMaxElementSize; diff --git a/mozilla/layout/html/forms/src/nsImageControlFrame.cpp b/mozilla/layout/html/forms/src/nsImageControlFrame.cpp index 9f6ec1af23f..378216ed8bb 100644 --- a/mozilla/layout/html/forms/src/nsImageControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsImageControlFrame.cpp @@ -46,6 +46,7 @@ #include "nsIHTMLAttributes.h" #include "nsGenericHTMLElement.h" #include "nsFormFrame.h" +#include "nsFormControlFrame.h" //Enumeration of possible mouse states used to detect mouse clicks /*enum nsMouseState { @@ -145,6 +146,8 @@ protected: nsCursor mPreviousCursor; nsRect mTranslatedRect; PRBool mGotFocus; + + nsCOMPtr mPresContext; }; @@ -160,6 +163,8 @@ nsImageControlFrame::nsImageControlFrame() nsImageControlFrame::~nsImageControlFrame() { + nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); + if (mFormFrame) { mFormFrame->RemoveFormControlFrame(*this); mFormFrame = nsnull; @@ -255,6 +260,8 @@ nsImageControlFrame::Reflow(nsIPresContext* aPresContext, nsReflowStatus& aStatus) { if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { + mPresContext = aPresContext; + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); // add ourself as an nsIFormControlFrame nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this)); } diff --git a/mozilla/layout/html/forms/src/nsLabelFrame.cpp b/mozilla/layout/html/forms/src/nsLabelFrame.cpp index 159e7abd5db..e02e72416f7 100644 --- a/mozilla/layout/html/forms/src/nsLabelFrame.cpp +++ b/mozilla/layout/html/forms/src/nsLabelFrame.cpp @@ -54,18 +54,10 @@ #include "nsIDocument.h" #include "nsIHTMLDocument.h" #include "nsIDOMHTMLAnchorElement.h" +#include "nsFormControlFrame.h" #include "nsIFocusableContent.h" -//Enumeration of possible mouse states used to detect mouse clicks -enum nsMouseState { - eMouseNone, - eMouseEnter, - eMouseExit, - eMouseDown, - eMouseUp -}; - static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID); static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID); static NS_DEFINE_IID(kViewCID, NS_VIEW_CID); @@ -78,6 +70,7 @@ class nsLabelFrame : public nsHTMLContainerFrame { public: nsLabelFrame(); + virtual ~nsLabelFrame(); NS_IMETHOD Init(nsIPresContext* aPresContext, nsIContent* aContent, @@ -127,6 +120,8 @@ protected: PRBool mControlIsInside; nsIFormControlFrame* mControlFrame; nsRect mTranslatedRect; + + nsCOMPtr mPresContext; }; nsresult @@ -155,6 +150,11 @@ nsLabelFrame::nsLabelFrame() mTranslatedRect = nsRect(0,0,0,0); } +nsLabelFrame::~nsLabelFrame() +{ + nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); +} + void nsLabelFrame::GetTranslatedRect(nsIPresContext* aPresContext, nsRect& aRect) { @@ -541,7 +541,10 @@ nsLabelFrame::Reflow(nsIPresContext* aPresContext, aReflowState.reflowCommand->GetNext(nextFrame); NS_ASSERTION(nextFrame == mFrames.FirstChild(), "unexpected next reflow command frame"); } - } + } else if (eReflowReason_Initial == aReflowState.reason) { + mPresContext = aPresContext; + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); + } // XXX remove the following when the reflow state is fixed LabelHack((nsHTMLReflowState&)aReflowState, "BUG - label"); diff --git a/mozilla/layout/html/forms/src/nsLegendFrame.cpp b/mozilla/layout/html/forms/src/nsLegendFrame.cpp index 17146e4e349..dec875b4bcf 100644 --- a/mozilla/layout/html/forms/src/nsLegendFrame.cpp +++ b/mozilla/layout/html/forms/src/nsLegendFrame.cpp @@ -30,7 +30,6 @@ #include "nsIFrame.h" #include "nsISupports.h" #include "nsIAtom.h" -#include "nsIPresContext.h" #include "nsIHTMLContent.h" #include "nsHTMLIIDs.h" #include "nsHTMLParts.h" @@ -39,6 +38,7 @@ #include "nsStyleConsts.h" #include "nsStyleUtil.h" #include "nsFont.h" +#include "nsFormControlFrame.h" static NS_DEFINE_IID(kLegendFrameCID, NS_LEGEND_FRAME_CID); static NS_DEFINE_IID(kIDOMHTMLLegendElementIID, NS_IDOMHTMLLEGENDELEMENT_IID); @@ -63,6 +63,11 @@ nsLegendFrame::nsLegendFrame() { } +nsLegendFrame::~nsLegendFrame() +{ + nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); +} + // Frames are not refcounted, no need to AddRef NS_IMETHODIMP nsLegendFrame::QueryInterface(REFNSIID aIID, void** aInstancePtrResult) @@ -78,6 +83,20 @@ nsLegendFrame::QueryInterface(REFNSIID aIID, void** aInstancePtrResult) return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtrResult); } +NS_IMETHODIMP +nsLegendFrame::Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (eReflowReason_Initial == aReflowState.reason) { + mPresContext = aPresContext; + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); + } + return nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); +} + + PRInt32 nsLegendFrame::GetAlign() { PRInt32 intValue = NS_STYLE_TEXT_ALIGN_LEFT; diff --git a/mozilla/layout/html/forms/src/nsLegendFrame.h b/mozilla/layout/html/forms/src/nsLegendFrame.h index 6401d24caa4..5538435740c 100644 --- a/mozilla/layout/html/forms/src/nsLegendFrame.h +++ b/mozilla/layout/html/forms/src/nsLegendFrame.h @@ -24,6 +24,9 @@ #define nsLegendFrame_h___ #include "nsAreaFrame.h" +#include "nsIPresContext.h" +#include "nsCOMPtr.h" + class nsIContent; class nsIFrame; class nsIPresContext; @@ -38,14 +41,23 @@ class nsLegendFrame : public nsAreaFrame { public: nsLegendFrame(); + virtual ~nsLegendFrame(); NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + NS_IMETHOD Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus); + + #ifdef NS_DEBUG NS_IMETHOD GetFrameName(nsString& aResult) const; #endif PRInt32 GetAlign(); + + nsCOMPtr mPresContext; }; diff --git a/mozilla/layout/html/forms/src/nsListControlFrame.cpp b/mozilla/layout/html/forms/src/nsListControlFrame.cpp index 0fbda31ccdd..b26a500b157 100644 --- a/mozilla/layout/html/forms/src/nsListControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsListControlFrame.cpp @@ -123,6 +123,8 @@ nsListControlFrame::nsListControlFrame() //--------------------------------------------------------- nsListControlFrame::~nsListControlFrame() { + nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE); + // if list is dropped down // make sure it gets rolled up if (IsInDropDownMode()) { @@ -286,7 +288,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { -#ifdef DEBUG_rodsXXX +#ifdef DEBUG_rods printf("nsListControlFrame::Reflow Reason: "); switch (aReflowState.reason) { case eReflowReason_Initial:printf("eReflowReason_Initial\n");break; @@ -355,6 +357,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext, mHasBeenInitialized = PR_TRUE; InitSelectionCache(-1); // Reset sel cache so as not to send event Reset(mPresContext); +#if 1 nsCOMPtr cmd; nsresult rv = NS_NewHTMLReflowCommand(getter_AddRefs(cmd), this, nsIReflowCommand::StyleChanged); if (NS_FAILED(rv)) { return rv; } @@ -368,10 +371,18 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext, rv = shell->AppendReflowCommand(cmd); // must do this next line regardless of result of AppendReflowCommand shell->ExitReflowLock(PR_TRUE); +#else + if (mParent) { + nsCOMPtr shell; + nsresult rv = mPresContext->GetShell(getter_AddRefs(shell)); + mState |= NS_FRAME_IS_DIRTY; + mParent->ReflowDirtyChild(shell, (nsIFrame*) this); + } +#endif } } -#if 1 +#if 0 nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext, aDesiredSize, aReflowState, aStatus); if (NS_SUCCEEDED(skiprv)) { @@ -416,6 +427,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext, // Add the list frame as a child of the form if (IsInDropDownMode() == PR_FALSE && !mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { + nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE); nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this)); } @@ -1943,6 +1955,17 @@ nsListControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex) Reset(aPresContext); // this sets mSelectedIndex to the defaulted selection wasReset = PR_TRUE; } + +#if DEBUG_rods + { + nsAutoString text = "No Value"; + nsresult rv = option->GetLabel(text); + if (NS_CONTENT_ATTR_NOT_THERE == rv || 0 == text.Length()) { + option->GetText(text); + } + printf("this %p Index: %d [%s] CB: %p\n", this, aIndex, text.ToNewCString(), mComboboxFrame); //leaks + } +#endif } } @@ -2468,6 +2491,30 @@ void nsListControlFrame::ResetSelectedItem() } } +//---------------------------------------------------------------------- +// helper +//---------------------------------------------------------------------- +PRBool +nsListControlFrame::IsLeftButton(nsIDOMEvent* aMouseEvent) +{ + // only allow selection with the left button + nsCOMPtr mouseEvent = do_QueryInterface(aMouseEvent); + if (mouseEvent) { + PRUint16 whichButton; + if (NS_SUCCEEDED(mouseEvent->GetButton(&whichButton))) { + if (whichButton != 1) { + aMouseEvent->PreventDefault(); + aMouseEvent->PreventCapture(); + aMouseEvent->PreventBubble(); + return PR_FALSE; + } else { + return PR_TRUE; + } + } + } + return PR_FALSE; +} + //---------------------------------------------------------------------- // nsIDOMMouseListener //---------------------------------------------------------------------- @@ -2479,6 +2526,11 @@ nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent) return NS_OK; } + // only allow selection with the left button + if (!IsLeftButton(aMouseEvent)) { + return NS_ERROR_FAILURE; // means consume event + } + // Check to see if the disabled option was clicked on // NS_ERROR_FAILURE is returned is it isn't over an option PRBool optionIsDisabled; @@ -2512,7 +2564,11 @@ nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent) UpdateSelection(PR_TRUE, PR_FALSE, mContent); } - return NS_OK; + aMouseEvent->PreventDefault(); + aMouseEvent->PreventCapture(); + aMouseEvent->PreventBubble(); + return NS_ERROR_FAILURE; + //return NS_OK; } //--------------------------------------------------------- @@ -2579,6 +2635,11 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent) return NS_OK; } + // only allow selection with the left button + if (!IsLeftButton(aMouseEvent)) { + return NS_ERROR_FAILURE; // means consume event + } + // Check to see if the disabled option was clicked on // NS_ERROR_FAILURE is returned is it isn't over an option PRBool optionIsDisabled; @@ -2673,7 +2734,11 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent) } } } - return NS_OK; + aMouseEvent->PreventDefault(); + aMouseEvent->PreventCapture(); + aMouseEvent->PreventBubble(); + return NS_ERROR_FAILURE; //consumes event + //return NS_OK; } //---------------------------------------------------------------------- diff --git a/mozilla/layout/html/forms/src/nsListControlFrame.h b/mozilla/layout/html/forms/src/nsListControlFrame.h index 8ae637d8697..d17e78ccb28 100644 --- a/mozilla/layout/html/forms/src/nsListControlFrame.h +++ b/mozilla/layout/html/forms/src/nsListControlFrame.h @@ -217,6 +217,7 @@ protected: PRBool HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2); void HandleListSelection(nsIDOMEvent * aDOMEvent); PRInt32 GetSelectedIndexFromFrame(nsIFrame *aHitFrame); + PRBool IsLeftButton(nsIDOMEvent* aMouseEvent); // onChange detection nsresult InitSelectionCache(PRInt32 aLength); diff --git a/mozilla/layout/html/forms/src/nsRadioControlFrame.h b/mozilla/layout/html/forms/src/nsRadioControlFrame.h index 6403f17a2c0..5751e4e095c 100644 --- a/mozilla/layout/html/forms/src/nsRadioControlFrame.h +++ b/mozilla/layout/html/forms/src/nsRadioControlFrame.h @@ -70,8 +70,6 @@ public: virtual void Reset(nsIPresContext* aPresContext); virtual const nsIID& GetCID(); - virtual const nsIID& GetIID(); - // // 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. diff --git a/mozilla/layout/html/forms/src/nsRadioControlGroup.cpp b/mozilla/layout/html/forms/src/nsRadioControlGroup.cpp index 0a43e1b8070..5f83ae73bab 100644 --- a/mozilla/layout/html/forms/src/nsRadioControlGroup.cpp +++ b/mozilla/layout/html/forms/src/nsRadioControlGroup.cpp @@ -38,20 +38,20 @@ nsRadioControlGroup::GetRadioCount() const return mRadios.Count(); } -nsRadioControlFrame* +nsGfxRadioControlFrame* nsRadioControlGroup::GetRadioAt(PRInt32 aIndex) const { - return (nsRadioControlFrame*) mRadios.ElementAt(aIndex); + return (nsGfxRadioControlFrame*) mRadios.ElementAt(aIndex); } PRBool -nsRadioControlGroup::AddRadio(nsRadioControlFrame* aRadio) +nsRadioControlGroup::AddRadio(nsGfxRadioControlFrame* aRadio) { return mRadios.AppendElement(aRadio); } PRBool -nsRadioControlGroup::RemoveRadio(nsRadioControlFrame* aRadio) +nsRadioControlGroup::RemoveRadio(nsGfxRadioControlFrame* aRadio) { if (aRadio == mCheckedRadio) { mCheckedRadio = nsnull; @@ -59,14 +59,14 @@ nsRadioControlGroup::RemoveRadio(nsRadioControlFrame* aRadio) return mRadios.RemoveElement(aRadio); } -nsRadioControlFrame* +nsGfxRadioControlFrame* nsRadioControlGroup::GetCheckedRadio() { return mCheckedRadio; } void -nsRadioControlGroup::SetCheckedRadio(nsRadioControlFrame* aRadio) +nsRadioControlGroup::SetCheckedRadio(nsGfxRadioControlFrame* aRadio) { mCheckedRadio = aRadio; } diff --git a/mozilla/layout/html/forms/src/nsRadioControlGroup.h b/mozilla/layout/html/forms/src/nsRadioControlGroup.h index f41040463eb..e5fe4070004 100644 --- a/mozilla/layout/html/forms/src/nsRadioControlGroup.h +++ b/mozilla/layout/html/forms/src/nsRadioControlGroup.h @@ -23,7 +23,7 @@ #ifndef nsRadioControlGroup_h___ #define nsRadioControlGroup_h___ -#include "nsRadioControlFrame.h" +#include "nsGfxRadioControlFrame.h" class nsRadioControlGroup @@ -32,19 +32,21 @@ public: nsRadioControlGroup(nsString& aName); virtual ~nsRadioControlGroup(); - PRBool AddRadio(nsRadioControlFrame* aRadio); + PRBool AddRadio(nsGfxRadioControlFrame* aRadio); PRInt32 GetRadioCount() const; - nsRadioControlFrame* GetRadioAt(PRInt32 aIndex) const; - PRBool RemoveRadio(nsRadioControlFrame* aRadio); + nsGfxRadioControlFrame* GetRadioAt(PRInt32 aIndex) const; + PRInt32 GetNumRadios() const { return mRadios.Count(); } - nsRadioControlFrame* GetCheckedRadio(); - void SetCheckedRadio(nsRadioControlFrame* aRadio); + PRBool RemoveRadio(nsGfxRadioControlFrame* aRadio); + + nsGfxRadioControlFrame* GetCheckedRadio(); + void SetCheckedRadio(nsGfxRadioControlFrame* aRadio); void GetName(nsString& aNameResult) const; protected: nsString mName; nsVoidArray mRadios; - nsRadioControlFrame* mCheckedRadio; + nsGfxRadioControlFrame* mCheckedRadio; }; diff --git a/mozilla/layout/html/forms/src/nsTextControlFrame.cpp b/mozilla/layout/html/forms/src/nsTextControlFrame.cpp index ee48bfd8915..804e77d7836 100644 --- a/mozilla/layout/html/forms/src/nsTextControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsTextControlFrame.cpp @@ -30,7 +30,6 @@ #include "nsIHTMLContent.h" #include "nsHTMLIIDs.h" #include "nsITextWidget.h" -#include "nsITextAreaWidget.h" #include "nsWidgetsCID.h" #include "nsSize.h" #include "nsString.h"