зеркало из https://github.com/mozilla/pjs.git
Move checkbox state to content (bug 108307). r=rods, sr=jst
This commit is contained in:
Родитель
84ad1383ae
Коммит
57b832743d
|
@ -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>
|
Загрузка…
Ссылка в новой задаче