Move checkbox state to content (bug 108307). r=rods, sr=jst

This commit is contained in:
jkeiser%netscape.com 2002-01-24 19:04:55 +00:00
Родитель 84ad1383ae
Коммит 57b832743d
10 изменённых файлов: 231 добавлений и 883 удалений

Просмотреть файл

@ -311,9 +311,6 @@ HTML_ATOM(wrappedFramePseudo, ":wrapped-frame")
HTML_ATOM(zindex, "zindex")
HTML_ATOM(z_index, "z-index")
HTML_ATOM(moz_tristate, "moz-tristate")
HTML_ATOM(moz_tristatevalue, "moz-tristatevalue")
#ifdef DEBUG
HTML_ATOM(iform, "IForm")
HTML_ATOM(form_control_list, "FormControlList")

Просмотреть файл

@ -167,6 +167,10 @@ public:
|| mType == NS_FORM_INPUT_HIDDEN)) {
Reset();
}
if (aName == nsHTMLAtoms::checked && !mCheckedChanged
&& (mType == NS_FORM_INPUT_CHECKBOX || mType == NS_FORM_INPUT_RADIO)) {
Reset();
}
return rv;
}
NS_IMETHOD SetAttr(nsINodeInfo* aNodeInfo, const nsAReadableString& aValue,
@ -180,7 +184,10 @@ public:
nsresult rv = nsGenericHTMLLeafElement::UnsetAttr(aNameSpaceID,
aAttribute,
aNotify);
if (aAttribute == nsHTMLAtoms::value) {
if (aAttribute == nsHTMLAtoms::value && !mValueChanged) {
Reset();
}
if (aAttribute == nsHTMLAtoms::checked && !mCheckedChanged) {
Reset();
}
return rv;
@ -216,12 +223,16 @@ protected:
return tmp.EqualsIgnoreCase("image");
}
void FireOnChange();
nsCOMPtr<nsIControllers> mControllers;
PRInt8 mType;
PRPackedBool mSkipFocusEvent;
PRPackedBool mHandlingClick;
PRPackedBool mValueChanged;
PRPackedBool mCheckedChanged;
PRPackedBool mChecked;
char* mValue;
};
@ -261,6 +272,8 @@ nsHTMLInputElement::nsHTMLInputElement()
mHandlingClick = PR_FALSE;
mValueChanged = PR_FALSE;
mValue = nsnull;
mCheckedChanged = PR_FALSE;
mChecked = PR_FALSE;
}
nsHTMLInputElement::~nsHTMLInputElement()
@ -355,20 +368,15 @@ nsHTMLInputElement::GetDefaultChecked(PRBool* aDefaultChecked)
NS_IMETHODIMP
nsHTMLInputElement::SetDefaultChecked(PRBool aDefaultChecked)
{
nsresult rv = NS_OK;
nsHTMLValue empty(eHTMLUnit_Empty);
nsresult rv;
if (aDefaultChecked) {
rv = SetHTMLAttribute(nsHTMLAtoms::checked, empty, PR_TRUE);
} else {
if (aDefaultChecked) {
rv = SetAttr(kNameSpaceID_HTML, nsHTMLAtoms::checked,
NS_LITERAL_STRING(""), PR_TRUE);
} else {
rv = UnsetAttr(kNameSpaceID_HTML, nsHTMLAtoms::checked, PR_TRUE);
}
if (NS_SUCCEEDED(rv)) {
//When setting DefaultChecked, we must also reset Checked (DOM Errata)
SetChecked(aDefaultChecked);
}
return rv;
}
@ -560,35 +568,45 @@ nsHTMLInputElement::SetValueChanged(PRBool aValueChanged)
}
NS_IMETHODIMP
nsHTMLInputElement::GetChecked(PRBool* aValue)
nsHTMLInputElement::GetChecked(PRBool* aChecked)
{
nsAutoString value(NS_LITERAL_STRING("0"));
PRInt32 type;
GetType(&type);
if (type == NS_FORM_INPUT_RADIO) {
nsAutoString value(NS_LITERAL_STRING("0"));
// No need to flush here, if there's no frame created for this input
// yet, we know our own checked state.
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
// No need to flush here, if there's no frame created for this input
// yet, we know our own checked state.
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
if (formControlFrame) {
formControlFrame->GetProperty(nsHTMLAtoms::checked, value);
}
else {
// Retrieve the presentation state instead.
nsCOMPtr<nsIPresState> presState;
GetPrimaryPresState(this, getter_AddRefs(presState));
if (formControlFrame) {
formControlFrame->GetProperty(nsHTMLAtoms::checked, value);
}
else {
// Retrieve the presentation state instead.
nsCOMPtr<nsIPresState> presState;
GetPrimaryPresState(this, getter_AddRefs(presState));
// Obtain the value property from the presentation state.
if (presState) {
presState->GetStateProperty(NS_LITERAL_STRING("checked"), value);
// Obtain the value property from the presentation state.
if (presState) {
presState->GetStateProperty(NS_LITERAL_STRING("checked"), value);
}
}
if (value.Equals(NS_LITERAL_STRING("1"))) {
*aChecked = PR_TRUE;
} else {
*aChecked = PR_FALSE;
}
} else {
if (!mCheckedChanged) {
GetDefaultChecked(aChecked);
} else {
*aChecked = mChecked;
}
}
if (value.Equals(NS_LITERAL_STRING("1"))) {
*aValue = PR_TRUE;
} else {
*aValue = PR_FALSE;
}
return NS_OK;
return NS_OK;
}
void
@ -608,71 +626,78 @@ nsHTMLInputElement::SetPresStateChecked(nsIHTMLContent * aHTMLContent,
NS_IMETHODIMP
nsHTMLInputElement::SetChecked(PRBool aValue)
{
// First check to see if the new value is the same as our current value.
// If so, then return.
PRBool checked = PR_TRUE;
GetChecked(&checked);
if (checked == aValue) {
return NS_OK;
}
mCheckedChanged = PR_TRUE;
// Since the value is changing, send out an onchange event (bug 23571)
nsCOMPtr<nsIPresContext> presContext;
GetPresContext(this, getter_AddRefs(presContext));
//
// Set the value
//
mChecked = aValue;
//
// Notify the frame
//
// No need to flush here since if there's no frame for this input at
// this point we don't care about creating one, once it's created
// the frame will do the right thing.
PRInt32 type;
GetType(&type);
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
if (formControlFrame) {
// the value is being toggled
nsAutoString val; val.AssignWithConversion(aValue ? "1" : "0");
nsCOMPtr<nsIPresContext> presContext;
GetPresContext(this, getter_AddRefs(presContext));
formControlFrame->SetProperty(presContext, nsHTMLAtoms::checked, val);
if (type == NS_FORM_INPUT_CHECKBOX) {
nsICheckboxControlFrame* checkboxFrame = nsnull;
CallQueryInterface(formControlFrame, &checkboxFrame);
if (checkboxFrame) {
checkboxFrame->OnChecked(presContext, aValue);
}
} else if (type == NS_FORM_INPUT_RADIO) {
// the value is being toggled
nsAutoString val; val.AssignWithConversion(aValue ? "1" : "0");
formControlFrame->SetProperty(presContext, nsHTMLAtoms::checked, val);
}
}
else {
else if (type == NS_FORM_INPUT_RADIO) {
SetPresStateChecked(this, aValue);
PRInt32 type;
GetType(&type);
if (type == NS_FORM_INPUT_RADIO) {
nsAutoString name;
GetName(name);
nsAutoString name;
GetName(name);
nsCOMPtr<nsIDOMHTMLFormElement> formElement;
if (NS_SUCCEEDED(GetForm(getter_AddRefs(formElement))) && formElement) {
nsCOMPtr<nsIDOMHTMLCollection> controls;
nsCOMPtr<nsIDOMHTMLFormElement> formElement;
if (NS_SUCCEEDED(GetForm(getter_AddRefs(formElement))) && formElement) {
nsCOMPtr<nsIDOMHTMLCollection> controls;
nsresult rv = formElement->GetElements(getter_AddRefs(controls));
nsresult rv = formElement->GetElements(getter_AddRefs(controls));
if (controls) {
PRUint32 numControls;
if (controls) {
PRUint32 numControls;
controls->GetLength(&numControls);
controls->GetLength(&numControls);
for (PRUint32 i = 0; i < numControls; i++) {
nsCOMPtr<nsIDOMNode> elementNode;
for (PRUint32 i = 0; i < numControls; i++) {
nsCOMPtr<nsIDOMNode> elementNode;
controls->Item(i, getter_AddRefs(elementNode));
controls->Item(i, getter_AddRefs(elementNode));
if (elementNode) {
nsCOMPtr<nsIDOMHTMLInputElement>
inputElement(do_QueryInterface(elementNode));
if (elementNode) {
nsCOMPtr<nsIDOMHTMLInputElement>
inputElement(do_QueryInterface(elementNode));
if (inputElement && inputElement.get() !=
NS_STATIC_CAST(nsIDOMHTMLInputElement *, this)) {
nsAutoString childName;
if (inputElement && inputElement.get() !=
NS_STATIC_CAST(nsIDOMHTMLInputElement *, this)) {
nsAutoString childName;
rv = inputElement->GetName(childName);
rv = inputElement->GetName(childName);
if (NS_SUCCEEDED(rv)) {
if (name == childName) {
nsCOMPtr<nsIHTMLContent>
htmlContent(do_QueryInterface(inputElement));
if (NS_SUCCEEDED(rv)) {
if (name == childName) {
nsCOMPtr<nsIHTMLContent>
htmlContent(do_QueryInterface(inputElement));
SetPresStateChecked(htmlContent, PR_FALSE);
}
SetPresStateChecked(htmlContent, PR_FALSE);
}
}
}
@ -682,13 +707,22 @@ nsHTMLInputElement::SetChecked(PRBool aValue)
}
}
return NS_OK;
}
void
nsHTMLInputElement::FireOnChange()
{
//
// Since the value is changing, send out an onchange event (bug 23571)
//
nsCOMPtr<nsIPresContext> presContext;
GetPresContext(this, getter_AddRefs(presContext));
nsEventStatus status = nsEventStatus_eIgnore;
nsEvent event;
event.eventStructType = NS_EVENT;
event.message = NS_FORM_CHANGE;
HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
return NS_OK;
}
NS_IMETHODIMP
@ -1094,6 +1128,7 @@ nsHTMLInputElement::HandleDOMEvent(nsIPresContext* aPresContext,
PRBool checked;
GetChecked(&checked);
SetChecked(!checked);
FireOnChange();
// Fire an event to notify accessibility
#ifdef ACCESSIBILITY
FireEventForAccessibility( aPresContext, NS_LITERAL_STRING("CheckboxStateChange"));
@ -1115,6 +1150,7 @@ nsHTMLInputElement::HandleDOMEvent(nsIPresContext* aPresContext,
}
}
SetChecked(PR_TRUE);
FireOnChange();
// Fire an event to notify accessibility
#ifdef ACCESSIBILITY
if ( selectedRadiobtn != this ) {
@ -1743,7 +1779,6 @@ nsHTMLInputElement::Reset()
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
// Seems like a dumb idea to reset image.
switch (type) {
case NS_FORM_INPUT_CHECKBOX:
case NS_FORM_INPUT_RADIO:
@ -1751,6 +1786,7 @@ nsHTMLInputElement::Reset()
PRBool resetVal;
GetDefaultChecked(&resetVal);
rv = SetChecked(resetVal);
mCheckedChanged = PR_FALSE;
break;
}
case NS_FORM_INPUT_HIDDEN:

Просмотреть файл

@ -311,9 +311,6 @@ HTML_ATOM(wrappedFramePseudo, ":wrapped-frame")
HTML_ATOM(zindex, "zindex")
HTML_ATOM(z_index, "z-index")
HTML_ATOM(moz_tristate, "moz-tristate")
HTML_ATOM(moz_tristatevalue, "moz-tristatevalue")
#ifdef DEBUG
HTML_ATOM(iform, "IForm")
HTML_ATOM(form_control_list, "FormControlList")

Просмотреть файл

@ -76,8 +76,7 @@ NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
//------------------------------------------------------------
// Initialize GFX-rendered state
nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame()
: mChecked(eOff),
mCheckButtonFaceStyle(nsnull)
: mCheckButtonFaceStyle(nsnull)
{
}
@ -131,35 +130,6 @@ nsGfxCheckboxControlFrame::SetCheckboxFaceStyleContext(nsIStyleContext *aCheckbo
return NS_OK;
}
//------------------------------------------------------------
//
// 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->GetAttr ( 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->SetAttr ( kNameSpaceID_None, GetTristateValueAtom(), NS_LITERAL_STRING("0"), PR_FALSE );
return NS_OK;
}
//--------------------------------------------------------------
NS_IMETHODIMP
@ -204,115 +174,14 @@ nsGfxCheckboxControlFrame::SetAdditionalStyleContext(PRInt32 aIndex,
//------------------------------------------------------------
//
// 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 aModType,
PRInt32 aHint)
nsGfxCheckboxControlFrame::OnChecked(nsIPresContext* aPresContext,
PRBool aChecked)
{
if ( aAttribute == GetTristateAtom() ) {
nsAutoString value;
nsresult res = mContent->GetAttr ( 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->GetAttr ( kNameSpaceID_None, GetTristateValueAtom(), value );
if ( res == NS_CONTENT_ATTR_HAS_VALUE )
SetCheckboxControlFrameState(aPresContext, value);
}
}
else
return nsFormControlFrame::AttributeChanged(aPresContext, aChild, aNameSpaceID, aAttribute, aModType, aHint);
return NS_OK;
nsFormControlHelper::ForceDrawFrame(aPresContext, this);
return aChecked;
}
//------------------------------------------------------------
//
// InitializeControl
//
// Set the default checked state of the checkbox.
//
void
nsGfxCheckboxControlFrame::InitializeControl(nsIPresContext* aPresContext)
{
nsFormControlFrame::InitializeControl(aPresContext);
// Only reset on init if this is the primary shell
// Temporary workaround until checkbox state is in content
nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell));
if (!presShell) return;
nsCOMPtr<nsIDocument> doc;
presShell->GetDocument(getter_AddRefs(doc));
if (!doc) return;
nsCOMPtr<nsIPresShell> primaryPresShell;
doc->GetShellAt(0, getter_AddRefs(primaryPresShell));
if (!primaryPresShell) return;
if (presShell.get() == primaryPresShell.get()) {
// Reset the value
// XXX We set the checkbox directly in the frame, because
// content fires onChange :(
PRBool checked = PR_FALSE;
nsresult rv = GetDefaultCheckState(&checked);
if (NS_CONTENT_ATTR_HAS_VALUE == rv) {
SetCheckboxState (aPresContext, checked ? eOn : eOff );
}
}
}
//------------------------------------------------------------
void
@ -336,33 +205,9 @@ nsGfxCheckboxControlFrame::PaintCheckBox(nsIPresContext* aPresContext,
mStyleContext->GetStyleData(eStyleStruct_Color);
aRenderingContext.SetColor(color->mColor);
if ( IsTristateCheckbox() ) {
// Get current checked state through content model.
// XXX this won't work under printing. does that matter???
CheckState checked = GetCheckboxState();
switch ( checked ) {
case eOn:
nsFormControlHelper::PaintCheckMark(aRenderingContext, p2t, checkRect);
break;
case eMixed:
PaintMixedMark(aRenderingContext, p2t, checkRect);
break;
// no special drawing otherwise
default:
break;
} // case of value of checkbox
} else {
// Get current checked state through content model.
// XXX: This is very inefficient, but it is necessary in the case of printing.
// During printing the Paint is called but the actual state of the checkbox
// is in a frame in presentation shell 0.
PRBool checked = PR_FALSE;
GetCurrentCheckState(&checked);
if ( checked ) {
nsFormControlHelper::PaintCheckMark(aRenderingContext, p2t, checkRect);
}
// Get current checked state through content model.
if ( GetCheckboxState() ) {
nsFormControlHelper::PaintCheckMark(aRenderingContext, p2t, checkRect);
}
PRBool clip;
@ -370,51 +215,6 @@ nsGfxCheckboxControlFrame::PaintCheckBox(nsIPresContext* aPresContext,
}
//------------------------------------------------------------
//
// PaintMixedMark
//
// Like nsFormControlHelper::PaintCheckMark(), but paints the horizontal "mixed"
// bar inside the box. Only used for tri-state checkboxes.
//
void
nsGfxCheckboxControlFrame::PaintMixedMark ( nsIRenderingContext& aRenderingContext,
float aPixelsToTwips, const nsRect& aRect)
{
const PRUint32 checkpoints = 4;
const PRUint32 checksize = 6; //This is value is determined by added 2 units to the end
//of the 7X& pixel rectangle below to provide some white space
//around the checkmark when it is rendered.
// Points come from the coordinates on a 7X7 pixels
// box with 0,0 at the lower left.
nscoord checkedPolygonDef[] = { 1,2, 5,2, 5,4, 1,4 };
// Location of the center point of the checkmark
const PRUint32 centerx = 3;
const PRUint32 centery = 3;
nsPoint checkedPolygon[checkpoints];
PRUint32 defIndex = 0;
PRUint32 polyIndex = 0;
// Scale the checkmark based on the smallest dimension
PRUint32 size = aRect.width / checksize;
if (aRect.height < aRect.width)
size = aRect.height / checksize;
// Center and offset each point in the polygon definition.
for (defIndex = 0; defIndex < (checkpoints * 2); defIndex++) {
checkedPolygon[polyIndex].x = nscoord((((checkedPolygonDef[defIndex]) - centerx) * (size)) + (aRect.width / 2) + aRect.x);
defIndex++;
checkedPolygon[polyIndex].y = nscoord((((checkedPolygonDef[defIndex]) - centery) * (size)) + (aRect.height / 2) + aRect.y);
polyIndex++;
}
aRenderingContext.FillPolygon(checkedPolygon, checkpoints);
} // PaintMixedMark
//------------------------------------------------------------
NS_METHOD
nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
@ -432,8 +232,8 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
nsresult rv = nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
PRBool doDefaultPainting = PR_TRUE;
// Paint the checkmark
if (nsnull != mCheckButtonFaceStyle && GetCheckboxState() == eOn) {
// Paint the checkmark
if (!mCheckButtonFaceStyle && GetCheckboxState()) {
const nsStyleBackground* myColor = (const nsStyleBackground*)
mCheckButtonFaceStyle->GetStyleData(eStyleStruct_Background);
@ -466,61 +266,43 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
}
//------------------------------------------------------------
nsGfxCheckboxControlFrame::CheckState
PRBool
nsGfxCheckboxControlFrame::GetCheckboxState ( )
{
return mChecked;
nsCOMPtr<nsIDOMHTMLInputElement> elem(do_QueryInterface(mContent));
PRBool retval = PR_FALSE;
elem->GetChecked(&retval);
return retval;
}
//------------------------------------------------------------
void
void
nsGfxCheckboxControlFrame::SetCheckboxState (nsIPresContext* aPresContext,
nsGfxCheckboxControlFrame::CheckState aValue )
PRBool aValue )
{
mChecked = aValue;
nsFormControlHelper::ForceDrawFrame(aPresContext, this);
nsCOMPtr<nsIDOMHTMLInputElement> elem(do_QueryInterface(mContent));
elem->SetChecked(aValue);
}
//------------------------------------------------------------
void nsGfxCheckboxControlFrame::GetCheckboxControlFrameState(nsAWritableString& aValue)
void
nsGfxCheckboxControlFrame::GetCheckboxControlFrameState (
nsAWritableString& aValue )
{
CheckStateToString(GetCheckboxState(), aValue);
}
//------------------------------------------------------------
void nsGfxCheckboxControlFrame::SetCheckboxControlFrameState(nsIPresContext* aPresContext,
const nsAReadableString& aValue)
void
nsGfxCheckboxControlFrame::SetCheckboxControlFrameState (
nsIPresContext* aPresContext,
const nsAReadableString& aValue )
{
CheckState state = StringToCheckState(aValue);
PRBool state = StringToCheckState(aValue);
SetCheckboxState(aPresContext, state);
}
//------------------------------------------------------------
NS_IMETHODIMP nsGfxCheckboxControlFrame::SetProperty(nsIPresContext* aPresContext,
nsIAtom* aName,
const nsAReadableString& aValue)
{
if (nsHTMLAtoms::checked == aName)
SetCheckboxControlFrameState(aPresContext, aValue);
else
return nsFormControlFrame::SetProperty(aPresContext, aName, aValue);
return NS_OK;
}
//------------------------------------------------------------
NS_IMETHODIMP nsGfxCheckboxControlFrame::GetProperty(nsIAtom* aName, nsAWritableString& aValue)
{
if (nsHTMLAtoms::checked == aName)
GetCheckboxControlFrameState(aValue);
else
return nsFormControlFrame::GetProperty(aName, aValue);
return NS_OK;
}
//------------------------------------------------------------
//
@ -529,20 +311,14 @@ NS_IMETHODIMP nsGfxCheckboxControlFrame::GetProperty(nsIAtom* aName, nsAWritable
// Converts from a CheckState to a string
//
void
nsGfxCheckboxControlFrame::CheckStateToString ( CheckState inState, nsAWritableString& outStateAsString )
nsGfxCheckboxControlFrame::CheckStateToString (
PRBool inState,
nsAWritableString& outStateAsString )
{
switch ( inState ) {
case eOn:
outStateAsString.Assign(NS_STRING_TRUE);
break;
case eOff:
outStateAsString.Assign(NS_STRING_FALSE);
break;
case eMixed:
outStateAsString.Assign(NS_LITERAL_STRING("2"));
break;
if (inState) {
outStateAsString.Assign(NS_STRING_TRUE);
} else {
outStateAsString.Assign(NS_STRING_FALSE);
}
} // CheckStateToString
@ -553,55 +329,13 @@ nsGfxCheckboxControlFrame::CheckStateToString ( CheckState inState, nsAWritableS
//
// Converts from a string to a CheckState enum
//
nsGfxCheckboxControlFrame::CheckState
PRBool
nsGfxCheckboxControlFrame::StringToCheckState ( const nsAReadableString & aStateAsString )
{
if ( aStateAsString.Equals(NS_STRING_TRUE) )
return eOn;
else if ( aStateAsString.Equals(NS_STRING_FALSE) )
return eOff;
// not true and not false means mixed
return eMixed;
return aStateAsString.Equals(NS_STRING_TRUE);
} // 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->SetAttr ( 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->UnsetAttr ( kNameSpaceID_None, GetTristateValueAtom(), PR_FALSE );
}
// switch!
mIsTristate = inIsNowTristate;
} // SwitchModesWithEmergencyBrake
//----------------------------------------------------------------------
// nsIStatefulFrame
//----------------------------------------------------------------------
@ -615,15 +349,14 @@ NS_IMETHODIMP nsGfxCheckboxControlFrame::SaveState(nsIPresContext* aPresContext,
return NS_OK;
}
CheckState stateCheck = GetCheckboxState();
PRBool stateCheck = GetCheckboxState();
PRBool defaultStateBool = PR_FALSE;
nsresult res = GetDefaultCheckState(&defaultStateBool);
// Compare to default value, and only save if needed (Bug 62713)
// eOn/eOff comparisons used to handle 'mixed' state (alway save)
if (!(NS_CONTENT_ATTR_HAS_VALUE == res &&
((eOn == stateCheck && defaultStateBool) ||
(eOff == stateCheck && !defaultStateBool)))) {
((stateCheck && defaultStateBool) ||
(!stateCheck && !defaultStateBool)))) {
// Get the value string
nsAutoString stateString;

Просмотреть файл

@ -66,21 +66,6 @@ public:
return MakeFrameName(NS_LITERAL_STRING("CheckboxControl"), aResult);
}
#endif
// this should be protected, but VC6 is lame.
enum CheckState { eOff, eOn, eMixed } ;
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 aModType,
PRInt32 aHint) ;
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -93,10 +78,9 @@ public:
#endif
//nsICheckboxControlFrame methods
//nsICheckboxControlFrame methods
NS_IMETHOD SetCheckboxFaceStyleContext(nsIStyleContext *aCheckboxFaceStyleContext);
void InitializeControl(nsIPresContext* aPresContext);
NS_IMETHOD OnChecked(nsIPresContext* aPresContext, PRBool aChecked);
NS_IMETHOD GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const;
@ -104,8 +88,6 @@ public:
nsIStyleContext* aStyleContext);
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsAReadableString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsAWritableString& aValue);
NS_IMETHOD OnContentReset();
// nsIStatefulFrame
@ -121,14 +103,18 @@ public:
nsReflowStatus& aStatus);
#endif
NS_IMETHOD GetChecked(PRBool* aIsChecked) { *aIsChecked = (GetCheckboxState() == eOn); return NS_OK; }
NS_IMETHOD SetChecked(nsIPresContext* aPresContext, PRBool aIsChecked) { SetCheckboxState(aPresContext, aIsChecked ? eOn : eOff); return NS_OK; }
NS_IMETHOD GetChecked(PRBool* aIsChecked) {
*aIsChecked = GetCheckboxState(); return NS_OK;
}
NS_IMETHOD SetChecked(nsIPresContext* aPresContext, PRBool aIsChecked) {
SetCheckboxState(aPresContext, aIsChecked); return NS_OK;
}
protected:
// native/gfx implementations need to implement needs.
CheckState GetCheckboxState();
void SetCheckboxState(nsIPresContext* aPresContext, CheckState aValue);
PRBool GetCheckboxState();
void SetCheckboxState(nsIPresContext* aPresContext, PRBool aValue);
// Utility methods for implementing SetProperty/GetProperty
void SetCheckboxControlFrameState(nsIPresContext* aPresContext,
@ -136,22 +122,8 @@ protected:
void GetCheckboxControlFrameState(nsAWritableString& aValue);
// utility routine for converting from DOM values to internal enum
void CheckStateToString ( CheckState inState, nsAWritableString& outStateAsString ) ;
CheckState StringToCheckState ( const nsAReadableString & 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() ;
void CheckStateToString(PRBool inState, nsAWritableString& outStateAsString) ;
PRBool StringToCheckState(const nsAReadableString & aStateAsString) ;
protected:
@ -159,12 +131,9 @@ protected:
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
virtual void PaintMixedMark(nsIRenderingContext& aRenderingContext,
float aPixelsToTwips, const nsRect& aRect) ;
//GFX-rendered state variables
PRBool mInClickEvent;
CheckState mChecked;
nsIStyleContext* mCheckButtonFaceStyle;
private:

Просмотреть файл

@ -40,6 +40,7 @@
#include "nsISupports.h"
class nsIStyleContext;
class nsIPresContext;
// IID for the nsICheckControlFrame class
// {401347ED-0101-11d4-9706-0060B0FB9956}
@ -58,10 +59,14 @@ public:
/**
* Sets the Pseudo Style Contexts for the Check button
*
*/
NS_IMETHOD SetCheckboxFaceStyleContext(nsIStyleContext *aCheckboxFaceStyleContext) = 0;
NS_IMETHOD SetCheckboxFaceStyleContext(
nsIStyleContext* aCheckboxFaceStyleContext) = 0;
/**
* Called by content when checkbox "checked" changes
*/
NS_IMETHOD OnChecked(nsIPresContext* aPresContext, PRBool aChecked) = 0;
};
#endif

Просмотреть файл

@ -40,6 +40,7 @@
#include "nsISupports.h"
class nsIStyleContext;
class nsIPresContext;
// IID for the nsICheckControlFrame class
// {401347ED-0101-11d4-9706-0060B0FB9956}
@ -58,10 +59,14 @@ public:
/**
* Sets the Pseudo Style Contexts for the Check button
*
*/
NS_IMETHOD SetCheckboxFaceStyleContext(nsIStyleContext *aCheckboxFaceStyleContext) = 0;
NS_IMETHOD SetCheckboxFaceStyleContext(
nsIStyleContext* aCheckboxFaceStyleContext) = 0;
/**
* Called by content when checkbox "checked" changes
*/
NS_IMETHOD OnChecked(nsIPresContext* aPresContext, PRBool aChecked) = 0;
};
#endif

Просмотреть файл

@ -76,8 +76,7 @@ NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
//------------------------------------------------------------
// Initialize GFX-rendered state
nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame()
: mChecked(eOff),
mCheckButtonFaceStyle(nsnull)
: mCheckButtonFaceStyle(nsnull)
{
}
@ -131,35 +130,6 @@ nsGfxCheckboxControlFrame::SetCheckboxFaceStyleContext(nsIStyleContext *aCheckbo
return NS_OK;
}
//------------------------------------------------------------
//
// 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->GetAttr ( 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->SetAttr ( kNameSpaceID_None, GetTristateValueAtom(), NS_LITERAL_STRING("0"), PR_FALSE );
return NS_OK;
}
//--------------------------------------------------------------
NS_IMETHODIMP
@ -204,115 +174,14 @@ nsGfxCheckboxControlFrame::SetAdditionalStyleContext(PRInt32 aIndex,
//------------------------------------------------------------
//
// 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 aModType,
PRInt32 aHint)
nsGfxCheckboxControlFrame::OnChecked(nsIPresContext* aPresContext,
PRBool aChecked)
{
if ( aAttribute == GetTristateAtom() ) {
nsAutoString value;
nsresult res = mContent->GetAttr ( 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->GetAttr ( kNameSpaceID_None, GetTristateValueAtom(), value );
if ( res == NS_CONTENT_ATTR_HAS_VALUE )
SetCheckboxControlFrameState(aPresContext, value);
}
}
else
return nsFormControlFrame::AttributeChanged(aPresContext, aChild, aNameSpaceID, aAttribute, aModType, aHint);
return NS_OK;
nsFormControlHelper::ForceDrawFrame(aPresContext, this);
return aChecked;
}
//------------------------------------------------------------
//
// InitializeControl
//
// Set the default checked state of the checkbox.
//
void
nsGfxCheckboxControlFrame::InitializeControl(nsIPresContext* aPresContext)
{
nsFormControlFrame::InitializeControl(aPresContext);
// Only reset on init if this is the primary shell
// Temporary workaround until checkbox state is in content
nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell));
if (!presShell) return;
nsCOMPtr<nsIDocument> doc;
presShell->GetDocument(getter_AddRefs(doc));
if (!doc) return;
nsCOMPtr<nsIPresShell> primaryPresShell;
doc->GetShellAt(0, getter_AddRefs(primaryPresShell));
if (!primaryPresShell) return;
if (presShell.get() == primaryPresShell.get()) {
// Reset the value
// XXX We set the checkbox directly in the frame, because
// content fires onChange :(
PRBool checked = PR_FALSE;
nsresult rv = GetDefaultCheckState(&checked);
if (NS_CONTENT_ATTR_HAS_VALUE == rv) {
SetCheckboxState (aPresContext, checked ? eOn : eOff );
}
}
}
//------------------------------------------------------------
void
@ -336,33 +205,9 @@ nsGfxCheckboxControlFrame::PaintCheckBox(nsIPresContext* aPresContext,
mStyleContext->GetStyleData(eStyleStruct_Color);
aRenderingContext.SetColor(color->mColor);
if ( IsTristateCheckbox() ) {
// Get current checked state through content model.
// XXX this won't work under printing. does that matter???
CheckState checked = GetCheckboxState();
switch ( checked ) {
case eOn:
nsFormControlHelper::PaintCheckMark(aRenderingContext, p2t, checkRect);
break;
case eMixed:
PaintMixedMark(aRenderingContext, p2t, checkRect);
break;
// no special drawing otherwise
default:
break;
} // case of value of checkbox
} else {
// Get current checked state through content model.
// XXX: This is very inefficient, but it is necessary in the case of printing.
// During printing the Paint is called but the actual state of the checkbox
// is in a frame in presentation shell 0.
PRBool checked = PR_FALSE;
GetCurrentCheckState(&checked);
if ( checked ) {
nsFormControlHelper::PaintCheckMark(aRenderingContext, p2t, checkRect);
}
// Get current checked state through content model.
if ( GetCheckboxState() ) {
nsFormControlHelper::PaintCheckMark(aRenderingContext, p2t, checkRect);
}
PRBool clip;
@ -370,51 +215,6 @@ nsGfxCheckboxControlFrame::PaintCheckBox(nsIPresContext* aPresContext,
}
//------------------------------------------------------------
//
// PaintMixedMark
//
// Like nsFormControlHelper::PaintCheckMark(), but paints the horizontal "mixed"
// bar inside the box. Only used for tri-state checkboxes.
//
void
nsGfxCheckboxControlFrame::PaintMixedMark ( nsIRenderingContext& aRenderingContext,
float aPixelsToTwips, const nsRect& aRect)
{
const PRUint32 checkpoints = 4;
const PRUint32 checksize = 6; //This is value is determined by added 2 units to the end
//of the 7X& pixel rectangle below to provide some white space
//around the checkmark when it is rendered.
// Points come from the coordinates on a 7X7 pixels
// box with 0,0 at the lower left.
nscoord checkedPolygonDef[] = { 1,2, 5,2, 5,4, 1,4 };
// Location of the center point of the checkmark
const PRUint32 centerx = 3;
const PRUint32 centery = 3;
nsPoint checkedPolygon[checkpoints];
PRUint32 defIndex = 0;
PRUint32 polyIndex = 0;
// Scale the checkmark based on the smallest dimension
PRUint32 size = aRect.width / checksize;
if (aRect.height < aRect.width)
size = aRect.height / checksize;
// Center and offset each point in the polygon definition.
for (defIndex = 0; defIndex < (checkpoints * 2); defIndex++) {
checkedPolygon[polyIndex].x = nscoord((((checkedPolygonDef[defIndex]) - centerx) * (size)) + (aRect.width / 2) + aRect.x);
defIndex++;
checkedPolygon[polyIndex].y = nscoord((((checkedPolygonDef[defIndex]) - centery) * (size)) + (aRect.height / 2) + aRect.y);
polyIndex++;
}
aRenderingContext.FillPolygon(checkedPolygon, checkpoints);
} // PaintMixedMark
//------------------------------------------------------------
NS_METHOD
nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
@ -432,8 +232,8 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
nsresult rv = nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
PRBool doDefaultPainting = PR_TRUE;
// Paint the checkmark
if (nsnull != mCheckButtonFaceStyle && GetCheckboxState() == eOn) {
// Paint the checkmark
if (!mCheckButtonFaceStyle && GetCheckboxState()) {
const nsStyleBackground* myColor = (const nsStyleBackground*)
mCheckButtonFaceStyle->GetStyleData(eStyleStruct_Background);
@ -466,61 +266,43 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
}
//------------------------------------------------------------
nsGfxCheckboxControlFrame::CheckState
PRBool
nsGfxCheckboxControlFrame::GetCheckboxState ( )
{
return mChecked;
nsCOMPtr<nsIDOMHTMLInputElement> elem(do_QueryInterface(mContent));
PRBool retval = PR_FALSE;
elem->GetChecked(&retval);
return retval;
}
//------------------------------------------------------------
void
void
nsGfxCheckboxControlFrame::SetCheckboxState (nsIPresContext* aPresContext,
nsGfxCheckboxControlFrame::CheckState aValue )
PRBool aValue )
{
mChecked = aValue;
nsFormControlHelper::ForceDrawFrame(aPresContext, this);
nsCOMPtr<nsIDOMHTMLInputElement> elem(do_QueryInterface(mContent));
elem->SetChecked(aValue);
}
//------------------------------------------------------------
void nsGfxCheckboxControlFrame::GetCheckboxControlFrameState(nsAWritableString& aValue)
void
nsGfxCheckboxControlFrame::GetCheckboxControlFrameState (
nsAWritableString& aValue )
{
CheckStateToString(GetCheckboxState(), aValue);
}
//------------------------------------------------------------
void nsGfxCheckboxControlFrame::SetCheckboxControlFrameState(nsIPresContext* aPresContext,
const nsAReadableString& aValue)
void
nsGfxCheckboxControlFrame::SetCheckboxControlFrameState (
nsIPresContext* aPresContext,
const nsAReadableString& aValue )
{
CheckState state = StringToCheckState(aValue);
PRBool state = StringToCheckState(aValue);
SetCheckboxState(aPresContext, state);
}
//------------------------------------------------------------
NS_IMETHODIMP nsGfxCheckboxControlFrame::SetProperty(nsIPresContext* aPresContext,
nsIAtom* aName,
const nsAReadableString& aValue)
{
if (nsHTMLAtoms::checked == aName)
SetCheckboxControlFrameState(aPresContext, aValue);
else
return nsFormControlFrame::SetProperty(aPresContext, aName, aValue);
return NS_OK;
}
//------------------------------------------------------------
NS_IMETHODIMP nsGfxCheckboxControlFrame::GetProperty(nsIAtom* aName, nsAWritableString& aValue)
{
if (nsHTMLAtoms::checked == aName)
GetCheckboxControlFrameState(aValue);
else
return nsFormControlFrame::GetProperty(aName, aValue);
return NS_OK;
}
//------------------------------------------------------------
//
@ -529,20 +311,14 @@ NS_IMETHODIMP nsGfxCheckboxControlFrame::GetProperty(nsIAtom* aName, nsAWritable
// Converts from a CheckState to a string
//
void
nsGfxCheckboxControlFrame::CheckStateToString ( CheckState inState, nsAWritableString& outStateAsString )
nsGfxCheckboxControlFrame::CheckStateToString (
PRBool inState,
nsAWritableString& outStateAsString )
{
switch ( inState ) {
case eOn:
outStateAsString.Assign(NS_STRING_TRUE);
break;
case eOff:
outStateAsString.Assign(NS_STRING_FALSE);
break;
case eMixed:
outStateAsString.Assign(NS_LITERAL_STRING("2"));
break;
if (inState) {
outStateAsString.Assign(NS_STRING_TRUE);
} else {
outStateAsString.Assign(NS_STRING_FALSE);
}
} // CheckStateToString
@ -553,55 +329,13 @@ nsGfxCheckboxControlFrame::CheckStateToString ( CheckState inState, nsAWritableS
//
// Converts from a string to a CheckState enum
//
nsGfxCheckboxControlFrame::CheckState
PRBool
nsGfxCheckboxControlFrame::StringToCheckState ( const nsAReadableString & aStateAsString )
{
if ( aStateAsString.Equals(NS_STRING_TRUE) )
return eOn;
else if ( aStateAsString.Equals(NS_STRING_FALSE) )
return eOff;
// not true and not false means mixed
return eMixed;
return aStateAsString.Equals(NS_STRING_TRUE);
} // 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->SetAttr ( 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->UnsetAttr ( kNameSpaceID_None, GetTristateValueAtom(), PR_FALSE );
}
// switch!
mIsTristate = inIsNowTristate;
} // SwitchModesWithEmergencyBrake
//----------------------------------------------------------------------
// nsIStatefulFrame
//----------------------------------------------------------------------
@ -615,15 +349,14 @@ NS_IMETHODIMP nsGfxCheckboxControlFrame::SaveState(nsIPresContext* aPresContext,
return NS_OK;
}
CheckState stateCheck = GetCheckboxState();
PRBool stateCheck = GetCheckboxState();
PRBool defaultStateBool = PR_FALSE;
nsresult res = GetDefaultCheckState(&defaultStateBool);
// Compare to default value, and only save if needed (Bug 62713)
// eOn/eOff comparisons used to handle 'mixed' state (alway save)
if (!(NS_CONTENT_ATTR_HAS_VALUE == res &&
((eOn == stateCheck && defaultStateBool) ||
(eOff == stateCheck && !defaultStateBool)))) {
((stateCheck && defaultStateBool) ||
(!stateCheck && !defaultStateBool)))) {
// Get the value string
nsAutoString stateString;

Просмотреть файл

@ -66,21 +66,6 @@ public:
return MakeFrameName(NS_LITERAL_STRING("CheckboxControl"), aResult);
}
#endif
// this should be protected, but VC6 is lame.
enum CheckState { eOff, eOn, eMixed } ;
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 aModType,
PRInt32 aHint) ;
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -93,10 +78,9 @@ public:
#endif
//nsICheckboxControlFrame methods
//nsICheckboxControlFrame methods
NS_IMETHOD SetCheckboxFaceStyleContext(nsIStyleContext *aCheckboxFaceStyleContext);
void InitializeControl(nsIPresContext* aPresContext);
NS_IMETHOD OnChecked(nsIPresContext* aPresContext, PRBool aChecked);
NS_IMETHOD GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const;
@ -104,8 +88,6 @@ public:
nsIStyleContext* aStyleContext);
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsAReadableString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsAWritableString& aValue);
NS_IMETHOD OnContentReset();
// nsIStatefulFrame
@ -121,14 +103,18 @@ public:
nsReflowStatus& aStatus);
#endif
NS_IMETHOD GetChecked(PRBool* aIsChecked) { *aIsChecked = (GetCheckboxState() == eOn); return NS_OK; }
NS_IMETHOD SetChecked(nsIPresContext* aPresContext, PRBool aIsChecked) { SetCheckboxState(aPresContext, aIsChecked ? eOn : eOff); return NS_OK; }
NS_IMETHOD GetChecked(PRBool* aIsChecked) {
*aIsChecked = GetCheckboxState(); return NS_OK;
}
NS_IMETHOD SetChecked(nsIPresContext* aPresContext, PRBool aIsChecked) {
SetCheckboxState(aPresContext, aIsChecked); return NS_OK;
}
protected:
// native/gfx implementations need to implement needs.
CheckState GetCheckboxState();
void SetCheckboxState(nsIPresContext* aPresContext, CheckState aValue);
PRBool GetCheckboxState();
void SetCheckboxState(nsIPresContext* aPresContext, PRBool aValue);
// Utility methods for implementing SetProperty/GetProperty
void SetCheckboxControlFrameState(nsIPresContext* aPresContext,
@ -136,22 +122,8 @@ protected:
void GetCheckboxControlFrameState(nsAWritableString& aValue);
// utility routine for converting from DOM values to internal enum
void CheckStateToString ( CheckState inState, nsAWritableString& outStateAsString ) ;
CheckState StringToCheckState ( const nsAReadableString & 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() ;
void CheckStateToString(PRBool inState, nsAWritableString& outStateAsString) ;
PRBool StringToCheckState(const nsAReadableString & aStateAsString) ;
protected:
@ -159,12 +131,9 @@ protected:
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
virtual void PaintMixedMark(nsIRenderingContext& aRenderingContext,
float aPixelsToTwips, const nsRect& aRect) ;
//GFX-rendered state variables
PRBool mInClickEvent;
CheckState mChecked;
nsIStyleContext* mCheckButtonFaceStyle;
private:

Просмотреть файл

@ -1,96 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://navigator/skin/navigator.css" type="text/css"?>
<?xml-stylesheet href="chrome://communicator/skin/bookmarks/bookmarks.css" type="text/css"?>
<!DOCTYPE window>
<window style="overflow: auto" xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" orient="vertical"
onload="">
<html:h1>TriStateCheckbox Test 1</html:h1>
<html:script>
function MakeOneTriState()
{
var tsbox = document.getElementById("normal");
tsbox.setAttribute("moz-tristate", "1");
}
function MakeTwoNormal()
{
var tsbox = document.getElementById("tristate");
tsbox.removeAttribute("moz-tristate");
}
function setTwoToMixed()
{
var tsbox = document.getElementById("tristate");
tsbox.setAttribute("moz-tristatevalue", "2");
}
function dumpTwoValue()
{
var tsbox = document.getElementById("tristate");
dump ( "value of button two is " + tsbox.getAttribute("moz-tristatevalue") + "\n" );
}
function dumpOneValue()
{
var tsbox = document.getElementById("normal");
dump ( "value of button one is " + tsbox.getAttribute("moz-tristatevalue") + "\n" );
}
function disableTwo()
{
var tsbox = document.getElementById("tristate");
tsbox.disabled = true;
}
function enableTwo()
{
var tsbox = document.getElementById("tristate");
tsbox.disabled = false;
}
</html:script>
<html:h3>
This is a tri-state checkbox test. The first checkbox should only act like a
normal two-state checkbox. The last one should behave like a tri-state.
</html:h3>
<html:div>
<html:hr/>
</html:div>
<html:label>
<html:input type="checkbox" id="normal"/>Button One (Normal)
</html:label>
<html:label>
<html:input type="checkbox" moz-tristate="1" id="tristate"/>Button Two (Tristate)
</html:label>
<html:label>
<html:input type="checkbox" style="moz-tristate: 1;" id="foop"/>Button Three (Tristate set by css)
</html:label>
<html:button onclick="MakeOneTriState()">Change Mode On Button One</html:button>
<html:button onclick="MakeTwoNormal()">Change Mode On Button Two</html:button>
<html:div>
<html:hr/>
</html:div>
<html:button onclick="setTwoToMixed()">Set Two To Mixed</html:button>
<html:button onclick="dumpOneValue()">Dump Value of Button One</html:button>
<html:button onclick="dumpTwoValue()">Dump Value of Button Two</html:button>
<html:div>
<html:hr/>
</html:div>
<html:button onclick="disableTwo()">Disable Button Two</html:button>
<html:button onclick="enableTwo()">Enable Button Two</html:button>
</window>