зеркало из 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(zindex, "zindex")
|
||||||
HTML_ATOM(z_index, "z-index")
|
HTML_ATOM(z_index, "z-index")
|
||||||
|
|
||||||
HTML_ATOM(moz_tristate, "moz-tristate")
|
|
||||||
HTML_ATOM(moz_tristatevalue, "moz-tristatevalue")
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
HTML_ATOM(iform, "IForm")
|
HTML_ATOM(iform, "IForm")
|
||||||
HTML_ATOM(form_control_list, "FormControlList")
|
HTML_ATOM(form_control_list, "FormControlList")
|
||||||
|
|
|
@ -167,6 +167,10 @@ public:
|
||||||
|| mType == NS_FORM_INPUT_HIDDEN)) {
|
|| mType == NS_FORM_INPUT_HIDDEN)) {
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
if (aName == nsHTMLAtoms::checked && !mCheckedChanged
|
||||||
|
&& (mType == NS_FORM_INPUT_CHECKBOX || mType == NS_FORM_INPUT_RADIO)) {
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
NS_IMETHOD SetAttr(nsINodeInfo* aNodeInfo, const nsAReadableString& aValue,
|
NS_IMETHOD SetAttr(nsINodeInfo* aNodeInfo, const nsAReadableString& aValue,
|
||||||
|
@ -180,7 +184,10 @@ public:
|
||||||
nsresult rv = nsGenericHTMLLeafElement::UnsetAttr(aNameSpaceID,
|
nsresult rv = nsGenericHTMLLeafElement::UnsetAttr(aNameSpaceID,
|
||||||
aAttribute,
|
aAttribute,
|
||||||
aNotify);
|
aNotify);
|
||||||
if (aAttribute == nsHTMLAtoms::value) {
|
if (aAttribute == nsHTMLAtoms::value && !mValueChanged) {
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
if (aAttribute == nsHTMLAtoms::checked && !mCheckedChanged) {
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -216,12 +223,16 @@ protected:
|
||||||
return tmp.EqualsIgnoreCase("image");
|
return tmp.EqualsIgnoreCase("image");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FireOnChange();
|
||||||
|
|
||||||
nsCOMPtr<nsIControllers> mControllers;
|
nsCOMPtr<nsIControllers> mControllers;
|
||||||
|
|
||||||
PRInt8 mType;
|
PRInt8 mType;
|
||||||
PRPackedBool mSkipFocusEvent;
|
PRPackedBool mSkipFocusEvent;
|
||||||
PRPackedBool mHandlingClick;
|
PRPackedBool mHandlingClick;
|
||||||
PRPackedBool mValueChanged;
|
PRPackedBool mValueChanged;
|
||||||
|
PRPackedBool mCheckedChanged;
|
||||||
|
PRPackedBool mChecked;
|
||||||
char* mValue;
|
char* mValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -261,6 +272,8 @@ nsHTMLInputElement::nsHTMLInputElement()
|
||||||
mHandlingClick = PR_FALSE;
|
mHandlingClick = PR_FALSE;
|
||||||
mValueChanged = PR_FALSE;
|
mValueChanged = PR_FALSE;
|
||||||
mValue = nsnull;
|
mValue = nsnull;
|
||||||
|
mCheckedChanged = PR_FALSE;
|
||||||
|
mChecked = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsHTMLInputElement::~nsHTMLInputElement()
|
nsHTMLInputElement::~nsHTMLInputElement()
|
||||||
|
@ -355,20 +368,15 @@ nsHTMLInputElement::GetDefaultChecked(PRBool* aDefaultChecked)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLInputElement::SetDefaultChecked(PRBool aDefaultChecked)
|
nsHTMLInputElement::SetDefaultChecked(PRBool aDefaultChecked)
|
||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
nsresult rv;
|
||||||
nsHTMLValue empty(eHTMLUnit_Empty);
|
|
||||||
|
|
||||||
if (aDefaultChecked) {
|
if (aDefaultChecked) {
|
||||||
rv = SetHTMLAttribute(nsHTMLAtoms::checked, empty, PR_TRUE);
|
rv = SetAttr(kNameSpaceID_HTML, nsHTMLAtoms::checked,
|
||||||
|
NS_LITERAL_STRING(""), PR_TRUE);
|
||||||
} else {
|
} else {
|
||||||
rv = UnsetAttr(kNameSpaceID_HTML, nsHTMLAtoms::checked, PR_TRUE);
|
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;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -560,32 +568,42 @@ nsHTMLInputElement::SetValueChanged(PRBool aValueChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
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
|
// No need to flush here, if there's no frame created for this input
|
||||||
// yet, we know our own checked state.
|
// yet, we know our own checked state.
|
||||||
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
||||||
|
|
||||||
if (formControlFrame) {
|
if (formControlFrame) {
|
||||||
formControlFrame->GetProperty(nsHTMLAtoms::checked, value);
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
// Retrieve the presentation state instead.
|
||||||
|
nsCOMPtr<nsIPresState> presState;
|
||||||
|
GetPrimaryPresState(this, getter_AddRefs(presState));
|
||||||
|
|
||||||
if (value.Equals(NS_LITERAL_STRING("1"))) {
|
// Obtain the value property from the presentation state.
|
||||||
*aValue = PR_TRUE;
|
if (presState) {
|
||||||
|
presState->GetStateProperty(NS_LITERAL_STRING("checked"), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.Equals(NS_LITERAL_STRING("1"))) {
|
||||||
|
*aChecked = PR_TRUE;
|
||||||
|
} else {
|
||||||
|
*aChecked = PR_FALSE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
*aValue = PR_FALSE;
|
if (!mCheckedChanged) {
|
||||||
|
GetDefaultChecked(aChecked);
|
||||||
|
} else {
|
||||||
|
*aChecked = mChecked;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -608,71 +626,78 @@ nsHTMLInputElement::SetPresStateChecked(nsIHTMLContent * aHTMLContent,
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLInputElement::SetChecked(PRBool aValue)
|
nsHTMLInputElement::SetChecked(PRBool aValue)
|
||||||
{
|
{
|
||||||
// First check to see if the new value is the same as our current value.
|
mCheckedChanged = PR_TRUE;
|
||||||
// If so, then return.
|
|
||||||
PRBool checked = PR_TRUE;
|
|
||||||
GetChecked(&checked);
|
|
||||||
if (checked == aValue) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since the value is changing, send out an onchange event (bug 23571)
|
//
|
||||||
nsCOMPtr<nsIPresContext> presContext;
|
// Set the value
|
||||||
GetPresContext(this, getter_AddRefs(presContext));
|
//
|
||||||
|
mChecked = aValue;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Notify the frame
|
||||||
|
//
|
||||||
// No need to flush here since if there's no frame for this input at
|
// 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
|
// this point we don't care about creating one, once it's created
|
||||||
// the frame will do the right thing.
|
// the frame will do the right thing.
|
||||||
|
PRInt32 type;
|
||||||
|
GetType(&type);
|
||||||
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
||||||
|
|
||||||
if (formControlFrame) {
|
if (formControlFrame) {
|
||||||
// the value is being toggled
|
nsCOMPtr<nsIPresContext> presContext;
|
||||||
nsAutoString val; val.AssignWithConversion(aValue ? "1" : "0");
|
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);
|
SetPresStateChecked(this, aValue);
|
||||||
|
|
||||||
PRInt32 type;
|
nsAutoString name;
|
||||||
GetType(&type);
|
GetName(name);
|
||||||
if (type == NS_FORM_INPUT_RADIO) {
|
|
||||||
nsAutoString name;
|
|
||||||
GetName(name);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMHTMLFormElement> formElement;
|
nsCOMPtr<nsIDOMHTMLFormElement> formElement;
|
||||||
if (NS_SUCCEEDED(GetForm(getter_AddRefs(formElement))) && formElement) {
|
if (NS_SUCCEEDED(GetForm(getter_AddRefs(formElement))) && formElement) {
|
||||||
nsCOMPtr<nsIDOMHTMLCollection> controls;
|
nsCOMPtr<nsIDOMHTMLCollection> controls;
|
||||||
|
|
||||||
nsresult rv = formElement->GetElements(getter_AddRefs(controls));
|
nsresult rv = formElement->GetElements(getter_AddRefs(controls));
|
||||||
|
|
||||||
if (controls) {
|
if (controls) {
|
||||||
PRUint32 numControls;
|
PRUint32 numControls;
|
||||||
|
|
||||||
controls->GetLength(&numControls);
|
controls->GetLength(&numControls);
|
||||||
|
|
||||||
for (PRUint32 i = 0; i < numControls; i++) {
|
for (PRUint32 i = 0; i < numControls; i++) {
|
||||||
nsCOMPtr<nsIDOMNode> elementNode;
|
nsCOMPtr<nsIDOMNode> elementNode;
|
||||||
|
|
||||||
controls->Item(i, getter_AddRefs(elementNode));
|
controls->Item(i, getter_AddRefs(elementNode));
|
||||||
|
|
||||||
if (elementNode) {
|
if (elementNode) {
|
||||||
nsCOMPtr<nsIDOMHTMLInputElement>
|
nsCOMPtr<nsIDOMHTMLInputElement>
|
||||||
inputElement(do_QueryInterface(elementNode));
|
inputElement(do_QueryInterface(elementNode));
|
||||||
|
|
||||||
if (inputElement && inputElement.get() !=
|
if (inputElement && inputElement.get() !=
|
||||||
NS_STATIC_CAST(nsIDOMHTMLInputElement *, this)) {
|
NS_STATIC_CAST(nsIDOMHTMLInputElement *, this)) {
|
||||||
nsAutoString childName;
|
nsAutoString childName;
|
||||||
|
|
||||||
rv = inputElement->GetName(childName);
|
rv = inputElement->GetName(childName);
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
if (name == childName) {
|
if (name == childName) {
|
||||||
nsCOMPtr<nsIHTMLContent>
|
nsCOMPtr<nsIHTMLContent>
|
||||||
htmlContent(do_QueryInterface(inputElement));
|
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;
|
nsEventStatus status = nsEventStatus_eIgnore;
|
||||||
nsEvent event;
|
nsEvent event;
|
||||||
event.eventStructType = NS_EVENT;
|
event.eventStructType = NS_EVENT;
|
||||||
event.message = NS_FORM_CHANGE;
|
event.message = NS_FORM_CHANGE;
|
||||||
HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -1094,6 +1128,7 @@ nsHTMLInputElement::HandleDOMEvent(nsIPresContext* aPresContext,
|
||||||
PRBool checked;
|
PRBool checked;
|
||||||
GetChecked(&checked);
|
GetChecked(&checked);
|
||||||
SetChecked(!checked);
|
SetChecked(!checked);
|
||||||
|
FireOnChange();
|
||||||
// Fire an event to notify accessibility
|
// Fire an event to notify accessibility
|
||||||
#ifdef ACCESSIBILITY
|
#ifdef ACCESSIBILITY
|
||||||
FireEventForAccessibility( aPresContext, NS_LITERAL_STRING("CheckboxStateChange"));
|
FireEventForAccessibility( aPresContext, NS_LITERAL_STRING("CheckboxStateChange"));
|
||||||
|
@ -1115,6 +1150,7 @@ nsHTMLInputElement::HandleDOMEvent(nsIPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetChecked(PR_TRUE);
|
SetChecked(PR_TRUE);
|
||||||
|
FireOnChange();
|
||||||
// Fire an event to notify accessibility
|
// Fire an event to notify accessibility
|
||||||
#ifdef ACCESSIBILITY
|
#ifdef ACCESSIBILITY
|
||||||
if ( selectedRadiobtn != this ) {
|
if ( selectedRadiobtn != this ) {
|
||||||
|
@ -1743,7 +1779,6 @@ nsHTMLInputElement::Reset()
|
||||||
|
|
||||||
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
||||||
|
|
||||||
// Seems like a dumb idea to reset image.
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NS_FORM_INPUT_CHECKBOX:
|
case NS_FORM_INPUT_CHECKBOX:
|
||||||
case NS_FORM_INPUT_RADIO:
|
case NS_FORM_INPUT_RADIO:
|
||||||
|
@ -1751,6 +1786,7 @@ nsHTMLInputElement::Reset()
|
||||||
PRBool resetVal;
|
PRBool resetVal;
|
||||||
GetDefaultChecked(&resetVal);
|
GetDefaultChecked(&resetVal);
|
||||||
rv = SetChecked(resetVal);
|
rv = SetChecked(resetVal);
|
||||||
|
mCheckedChanged = PR_FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NS_FORM_INPUT_HIDDEN:
|
case NS_FORM_INPUT_HIDDEN:
|
||||||
|
|
|
@ -311,9 +311,6 @@ HTML_ATOM(wrappedFramePseudo, ":wrapped-frame")
|
||||||
HTML_ATOM(zindex, "zindex")
|
HTML_ATOM(zindex, "zindex")
|
||||||
HTML_ATOM(z_index, "z-index")
|
HTML_ATOM(z_index, "z-index")
|
||||||
|
|
||||||
HTML_ATOM(moz_tristate, "moz-tristate")
|
|
||||||
HTML_ATOM(moz_tristatevalue, "moz-tristatevalue")
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
HTML_ATOM(iform, "IForm")
|
HTML_ATOM(iform, "IForm")
|
||||||
HTML_ATOM(form_control_list, "FormControlList")
|
HTML_ATOM(form_control_list, "FormControlList")
|
||||||
|
|
|
@ -76,8 +76,7 @@ NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
// Initialize GFX-rendered state
|
// Initialize GFX-rendered state
|
||||||
nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame()
|
nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame()
|
||||||
: mChecked(eOff),
|
: mCheckButtonFaceStyle(nsnull)
|
||||||
mCheckButtonFaceStyle(nsnull)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,35 +130,6 @@ nsGfxCheckboxControlFrame::SetCheckboxFaceStyleContext(nsIStyleContext *aCheckbo
|
||||||
return NS_OK;
|
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
|
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
|
NS_IMETHODIMP
|
||||||
nsGfxCheckboxControlFrame::AttributeChanged(nsIPresContext* aPresContext,
|
nsGfxCheckboxControlFrame::OnChecked(nsIPresContext* aPresContext,
|
||||||
nsIContent* aChild,
|
PRBool aChecked)
|
||||||
PRInt32 aNameSpaceID,
|
|
||||||
nsIAtom* aAttribute,
|
|
||||||
PRInt32 aModType,
|
|
||||||
PRInt32 aHint)
|
|
||||||
{
|
{
|
||||||
if ( aAttribute == GetTristateAtom() ) {
|
nsFormControlHelper::ForceDrawFrame(aPresContext, this);
|
||||||
nsAutoString value;
|
return aChecked;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// 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
|
void
|
||||||
|
@ -336,33 +205,9 @@ nsGfxCheckboxControlFrame::PaintCheckBox(nsIPresContext* aPresContext,
|
||||||
mStyleContext->GetStyleData(eStyleStruct_Color);
|
mStyleContext->GetStyleData(eStyleStruct_Color);
|
||||||
aRenderingContext.SetColor(color->mColor);
|
aRenderingContext.SetColor(color->mColor);
|
||||||
|
|
||||||
if ( IsTristateCheckbox() ) {
|
// Get current checked state through content model.
|
||||||
// Get current checked state through content model.
|
if ( GetCheckboxState() ) {
|
||||||
// XXX this won't work under printing. does that matter???
|
nsFormControlHelper::PaintCheckMark(aRenderingContext, p2t, checkRect);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool clip;
|
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
|
NS_METHOD
|
||||||
nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
|
nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
|
||||||
|
@ -433,7 +233,7 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
|
||||||
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
|
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
|
||||||
PRBool doDefaultPainting = PR_TRUE;
|
PRBool doDefaultPainting = PR_TRUE;
|
||||||
// Paint the checkmark
|
// Paint the checkmark
|
||||||
if (nsnull != mCheckButtonFaceStyle && GetCheckboxState() == eOn) {
|
if (!mCheckButtonFaceStyle && GetCheckboxState()) {
|
||||||
const nsStyleBackground* myColor = (const nsStyleBackground*)
|
const nsStyleBackground* myColor = (const nsStyleBackground*)
|
||||||
mCheckButtonFaceStyle->GetStyleData(eStyleStruct_Background);
|
mCheckButtonFaceStyle->GetStyleData(eStyleStruct_Background);
|
||||||
|
|
||||||
|
@ -466,61 +266,43 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
nsGfxCheckboxControlFrame::CheckState
|
PRBool
|
||||||
nsGfxCheckboxControlFrame::GetCheckboxState ( )
|
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::SetCheckboxState (nsIPresContext* aPresContext,
|
||||||
nsGfxCheckboxControlFrame::CheckState aValue )
|
PRBool aValue )
|
||||||
{
|
{
|
||||||
mChecked = aValue;
|
nsCOMPtr<nsIDOMHTMLInputElement> elem(do_QueryInterface(mContent));
|
||||||
nsFormControlHelper::ForceDrawFrame(aPresContext, this);
|
elem->SetChecked(aValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
void nsGfxCheckboxControlFrame::GetCheckboxControlFrameState(nsAWritableString& aValue)
|
void
|
||||||
|
nsGfxCheckboxControlFrame::GetCheckboxControlFrameState (
|
||||||
|
nsAWritableString& aValue )
|
||||||
{
|
{
|
||||||
CheckStateToString(GetCheckboxState(), aValue);
|
CheckStateToString(GetCheckboxState(), aValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
void nsGfxCheckboxControlFrame::SetCheckboxControlFrameState(nsIPresContext* aPresContext,
|
void
|
||||||
const nsAReadableString& aValue)
|
nsGfxCheckboxControlFrame::SetCheckboxControlFrameState (
|
||||||
|
nsIPresContext* aPresContext,
|
||||||
|
const nsAReadableString& aValue )
|
||||||
{
|
{
|
||||||
CheckState state = StringToCheckState(aValue);
|
PRBool state = StringToCheckState(aValue);
|
||||||
SetCheckboxState(aPresContext, state);
|
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
|
// Converts from a CheckState to a string
|
||||||
//
|
//
|
||||||
void
|
void
|
||||||
nsGfxCheckboxControlFrame::CheckStateToString ( CheckState inState, nsAWritableString& outStateAsString )
|
nsGfxCheckboxControlFrame::CheckStateToString (
|
||||||
|
PRBool inState,
|
||||||
|
nsAWritableString& outStateAsString )
|
||||||
{
|
{
|
||||||
switch ( inState ) {
|
if (inState) {
|
||||||
case eOn:
|
outStateAsString.Assign(NS_STRING_TRUE);
|
||||||
outStateAsString.Assign(NS_STRING_TRUE);
|
} else {
|
||||||
break;
|
outStateAsString.Assign(NS_STRING_FALSE);
|
||||||
|
|
||||||
case eOff:
|
|
||||||
outStateAsString.Assign(NS_STRING_FALSE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case eMixed:
|
|
||||||
outStateAsString.Assign(NS_LITERAL_STRING("2"));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} // CheckStateToString
|
} // CheckStateToString
|
||||||
|
|
||||||
|
@ -553,55 +329,13 @@ nsGfxCheckboxControlFrame::CheckStateToString ( CheckState inState, nsAWritableS
|
||||||
//
|
//
|
||||||
// Converts from a string to a CheckState enum
|
// Converts from a string to a CheckState enum
|
||||||
//
|
//
|
||||||
nsGfxCheckboxControlFrame::CheckState
|
PRBool
|
||||||
nsGfxCheckboxControlFrame::StringToCheckState ( const nsAReadableString & aStateAsString )
|
nsGfxCheckboxControlFrame::StringToCheckState ( const nsAReadableString & aStateAsString )
|
||||||
{
|
{
|
||||||
if ( aStateAsString.Equals(NS_STRING_TRUE) )
|
return 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;
|
|
||||||
|
|
||||||
} // StringToCheckState
|
} // 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
|
// nsIStatefulFrame
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -615,15 +349,14 @@ NS_IMETHODIMP nsGfxCheckboxControlFrame::SaveState(nsIPresContext* aPresContext,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckState stateCheck = GetCheckboxState();
|
PRBool stateCheck = GetCheckboxState();
|
||||||
PRBool defaultStateBool = PR_FALSE;
|
PRBool defaultStateBool = PR_FALSE;
|
||||||
nsresult res = GetDefaultCheckState(&defaultStateBool);
|
nsresult res = GetDefaultCheckState(&defaultStateBool);
|
||||||
|
|
||||||
// Compare to default value, and only save if needed (Bug 62713)
|
// 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 &&
|
if (!(NS_CONTENT_ATTR_HAS_VALUE == res &&
|
||||||
((eOn == stateCheck && defaultStateBool) ||
|
((stateCheck && defaultStateBool) ||
|
||||||
(eOff == stateCheck && !defaultStateBool)))) {
|
(!stateCheck && !defaultStateBool)))) {
|
||||||
|
|
||||||
// Get the value string
|
// Get the value string
|
||||||
nsAutoString stateString;
|
nsAutoString stateString;
|
||||||
|
|
|
@ -66,21 +66,6 @@ public:
|
||||||
return MakeFrameName(NS_LITERAL_STRING("CheckboxControl"), aResult);
|
return MakeFrameName(NS_LITERAL_STRING("CheckboxControl"), aResult);
|
||||||
}
|
}
|
||||||
#endif
|
#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,
|
NS_IMETHOD Paint(nsIPresContext* aPresContext,
|
||||||
nsIRenderingContext& aRenderingContext,
|
nsIRenderingContext& aRenderingContext,
|
||||||
|
@ -93,10 +78,9 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//nsICheckboxControlFrame methods
|
//nsICheckboxControlFrame methods
|
||||||
NS_IMETHOD SetCheckboxFaceStyleContext(nsIStyleContext *aCheckboxFaceStyleContext);
|
NS_IMETHOD SetCheckboxFaceStyleContext(nsIStyleContext *aCheckboxFaceStyleContext);
|
||||||
|
NS_IMETHOD OnChecked(nsIPresContext* aPresContext, PRBool aChecked);
|
||||||
void InitializeControl(nsIPresContext* aPresContext);
|
|
||||||
|
|
||||||
NS_IMETHOD GetAdditionalStyleContext(PRInt32 aIndex,
|
NS_IMETHOD GetAdditionalStyleContext(PRInt32 aIndex,
|
||||||
nsIStyleContext** aStyleContext) const;
|
nsIStyleContext** aStyleContext) const;
|
||||||
|
@ -104,8 +88,6 @@ public:
|
||||||
nsIStyleContext* aStyleContext);
|
nsIStyleContext* aStyleContext);
|
||||||
|
|
||||||
// nsIFormControlFrame
|
// nsIFormControlFrame
|
||||||
NS_IMETHOD SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsAReadableString& aValue);
|
|
||||||
NS_IMETHOD GetProperty(nsIAtom* aName, nsAWritableString& aValue);
|
|
||||||
NS_IMETHOD OnContentReset();
|
NS_IMETHOD OnContentReset();
|
||||||
|
|
||||||
// nsIStatefulFrame
|
// nsIStatefulFrame
|
||||||
|
@ -121,14 +103,18 @@ public:
|
||||||
nsReflowStatus& aStatus);
|
nsReflowStatus& aStatus);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NS_IMETHOD GetChecked(PRBool* aIsChecked) { *aIsChecked = (GetCheckboxState() == eOn); return NS_OK; }
|
NS_IMETHOD GetChecked(PRBool* aIsChecked) {
|
||||||
NS_IMETHOD SetChecked(nsIPresContext* aPresContext, PRBool aIsChecked) { SetCheckboxState(aPresContext, aIsChecked ? eOn : eOff); return NS_OK; }
|
*aIsChecked = GetCheckboxState(); return NS_OK;
|
||||||
|
}
|
||||||
|
NS_IMETHOD SetChecked(nsIPresContext* aPresContext, PRBool aIsChecked) {
|
||||||
|
SetCheckboxState(aPresContext, aIsChecked); return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// native/gfx implementations need to implement needs.
|
// native/gfx implementations need to implement needs.
|
||||||
CheckState GetCheckboxState();
|
PRBool GetCheckboxState();
|
||||||
void SetCheckboxState(nsIPresContext* aPresContext, CheckState aValue);
|
void SetCheckboxState(nsIPresContext* aPresContext, PRBool aValue);
|
||||||
|
|
||||||
// Utility methods for implementing SetProperty/GetProperty
|
// Utility methods for implementing SetProperty/GetProperty
|
||||||
void SetCheckboxControlFrameState(nsIPresContext* aPresContext,
|
void SetCheckboxControlFrameState(nsIPresContext* aPresContext,
|
||||||
|
@ -136,22 +122,8 @@ protected:
|
||||||
void GetCheckboxControlFrameState(nsAWritableString& aValue);
|
void GetCheckboxControlFrameState(nsAWritableString& aValue);
|
||||||
|
|
||||||
// utility routine for converting from DOM values to internal enum
|
// utility routine for converting from DOM values to internal enum
|
||||||
void CheckStateToString ( CheckState inState, nsAWritableString& outStateAsString ) ;
|
void CheckStateToString(PRBool inState, nsAWritableString& outStateAsString) ;
|
||||||
CheckState StringToCheckState ( const nsAReadableString & aStateAsString ) ;
|
PRBool 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() ;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -159,12 +131,9 @@ protected:
|
||||||
nsIRenderingContext& aRenderingContext,
|
nsIRenderingContext& aRenderingContext,
|
||||||
const nsRect& aDirtyRect,
|
const nsRect& aDirtyRect,
|
||||||
nsFramePaintLayer aWhichLayer);
|
nsFramePaintLayer aWhichLayer);
|
||||||
virtual void PaintMixedMark(nsIRenderingContext& aRenderingContext,
|
|
||||||
float aPixelsToTwips, const nsRect& aRect) ;
|
|
||||||
|
|
||||||
//GFX-rendered state variables
|
//GFX-rendered state variables
|
||||||
PRBool mInClickEvent;
|
PRBool mInClickEvent;
|
||||||
CheckState mChecked;
|
|
||||||
nsIStyleContext* mCheckButtonFaceStyle;
|
nsIStyleContext* mCheckButtonFaceStyle;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
|
|
||||||
#include "nsISupports.h"
|
#include "nsISupports.h"
|
||||||
class nsIStyleContext;
|
class nsIStyleContext;
|
||||||
|
class nsIPresContext;
|
||||||
|
|
||||||
// IID for the nsICheckControlFrame class
|
// IID for the nsICheckControlFrame class
|
||||||
// {401347ED-0101-11d4-9706-0060B0FB9956}
|
// {401347ED-0101-11d4-9706-0060B0FB9956}
|
||||||
|
@ -58,10 +59,14 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the Pseudo Style Contexts for the Check button
|
* 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
|
#endif
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
|
|
||||||
#include "nsISupports.h"
|
#include "nsISupports.h"
|
||||||
class nsIStyleContext;
|
class nsIStyleContext;
|
||||||
|
class nsIPresContext;
|
||||||
|
|
||||||
// IID for the nsICheckControlFrame class
|
// IID for the nsICheckControlFrame class
|
||||||
// {401347ED-0101-11d4-9706-0060B0FB9956}
|
// {401347ED-0101-11d4-9706-0060B0FB9956}
|
||||||
|
@ -58,10 +59,14 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the Pseudo Style Contexts for the Check button
|
* 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
|
#endif
|
||||||
|
|
|
@ -76,8 +76,7 @@ NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
// Initialize GFX-rendered state
|
// Initialize GFX-rendered state
|
||||||
nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame()
|
nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame()
|
||||||
: mChecked(eOff),
|
: mCheckButtonFaceStyle(nsnull)
|
||||||
mCheckButtonFaceStyle(nsnull)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,35 +130,6 @@ nsGfxCheckboxControlFrame::SetCheckboxFaceStyleContext(nsIStyleContext *aCheckbo
|
||||||
return NS_OK;
|
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
|
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
|
NS_IMETHODIMP
|
||||||
nsGfxCheckboxControlFrame::AttributeChanged(nsIPresContext* aPresContext,
|
nsGfxCheckboxControlFrame::OnChecked(nsIPresContext* aPresContext,
|
||||||
nsIContent* aChild,
|
PRBool aChecked)
|
||||||
PRInt32 aNameSpaceID,
|
|
||||||
nsIAtom* aAttribute,
|
|
||||||
PRInt32 aModType,
|
|
||||||
PRInt32 aHint)
|
|
||||||
{
|
{
|
||||||
if ( aAttribute == GetTristateAtom() ) {
|
nsFormControlHelper::ForceDrawFrame(aPresContext, this);
|
||||||
nsAutoString value;
|
return aChecked;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// 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
|
void
|
||||||
|
@ -336,33 +205,9 @@ nsGfxCheckboxControlFrame::PaintCheckBox(nsIPresContext* aPresContext,
|
||||||
mStyleContext->GetStyleData(eStyleStruct_Color);
|
mStyleContext->GetStyleData(eStyleStruct_Color);
|
||||||
aRenderingContext.SetColor(color->mColor);
|
aRenderingContext.SetColor(color->mColor);
|
||||||
|
|
||||||
if ( IsTristateCheckbox() ) {
|
// Get current checked state through content model.
|
||||||
// Get current checked state through content model.
|
if ( GetCheckboxState() ) {
|
||||||
// XXX this won't work under printing. does that matter???
|
nsFormControlHelper::PaintCheckMark(aRenderingContext, p2t, checkRect);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool clip;
|
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
|
NS_METHOD
|
||||||
nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
|
nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
|
||||||
|
@ -433,7 +233,7 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
|
||||||
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
|
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
|
||||||
PRBool doDefaultPainting = PR_TRUE;
|
PRBool doDefaultPainting = PR_TRUE;
|
||||||
// Paint the checkmark
|
// Paint the checkmark
|
||||||
if (nsnull != mCheckButtonFaceStyle && GetCheckboxState() == eOn) {
|
if (!mCheckButtonFaceStyle && GetCheckboxState()) {
|
||||||
const nsStyleBackground* myColor = (const nsStyleBackground*)
|
const nsStyleBackground* myColor = (const nsStyleBackground*)
|
||||||
mCheckButtonFaceStyle->GetStyleData(eStyleStruct_Background);
|
mCheckButtonFaceStyle->GetStyleData(eStyleStruct_Background);
|
||||||
|
|
||||||
|
@ -466,61 +266,43 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
nsGfxCheckboxControlFrame::CheckState
|
PRBool
|
||||||
nsGfxCheckboxControlFrame::GetCheckboxState ( )
|
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::SetCheckboxState (nsIPresContext* aPresContext,
|
||||||
nsGfxCheckboxControlFrame::CheckState aValue )
|
PRBool aValue )
|
||||||
{
|
{
|
||||||
mChecked = aValue;
|
nsCOMPtr<nsIDOMHTMLInputElement> elem(do_QueryInterface(mContent));
|
||||||
nsFormControlHelper::ForceDrawFrame(aPresContext, this);
|
elem->SetChecked(aValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
void nsGfxCheckboxControlFrame::GetCheckboxControlFrameState(nsAWritableString& aValue)
|
void
|
||||||
|
nsGfxCheckboxControlFrame::GetCheckboxControlFrameState (
|
||||||
|
nsAWritableString& aValue )
|
||||||
{
|
{
|
||||||
CheckStateToString(GetCheckboxState(), aValue);
|
CheckStateToString(GetCheckboxState(), aValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
void nsGfxCheckboxControlFrame::SetCheckboxControlFrameState(nsIPresContext* aPresContext,
|
void
|
||||||
const nsAReadableString& aValue)
|
nsGfxCheckboxControlFrame::SetCheckboxControlFrameState (
|
||||||
|
nsIPresContext* aPresContext,
|
||||||
|
const nsAReadableString& aValue )
|
||||||
{
|
{
|
||||||
CheckState state = StringToCheckState(aValue);
|
PRBool state = StringToCheckState(aValue);
|
||||||
SetCheckboxState(aPresContext, state);
|
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
|
// Converts from a CheckState to a string
|
||||||
//
|
//
|
||||||
void
|
void
|
||||||
nsGfxCheckboxControlFrame::CheckStateToString ( CheckState inState, nsAWritableString& outStateAsString )
|
nsGfxCheckboxControlFrame::CheckStateToString (
|
||||||
|
PRBool inState,
|
||||||
|
nsAWritableString& outStateAsString )
|
||||||
{
|
{
|
||||||
switch ( inState ) {
|
if (inState) {
|
||||||
case eOn:
|
outStateAsString.Assign(NS_STRING_TRUE);
|
||||||
outStateAsString.Assign(NS_STRING_TRUE);
|
} else {
|
||||||
break;
|
outStateAsString.Assign(NS_STRING_FALSE);
|
||||||
|
|
||||||
case eOff:
|
|
||||||
outStateAsString.Assign(NS_STRING_FALSE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case eMixed:
|
|
||||||
outStateAsString.Assign(NS_LITERAL_STRING("2"));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} // CheckStateToString
|
} // CheckStateToString
|
||||||
|
|
||||||
|
@ -553,55 +329,13 @@ nsGfxCheckboxControlFrame::CheckStateToString ( CheckState inState, nsAWritableS
|
||||||
//
|
//
|
||||||
// Converts from a string to a CheckState enum
|
// Converts from a string to a CheckState enum
|
||||||
//
|
//
|
||||||
nsGfxCheckboxControlFrame::CheckState
|
PRBool
|
||||||
nsGfxCheckboxControlFrame::StringToCheckState ( const nsAReadableString & aStateAsString )
|
nsGfxCheckboxControlFrame::StringToCheckState ( const nsAReadableString & aStateAsString )
|
||||||
{
|
{
|
||||||
if ( aStateAsString.Equals(NS_STRING_TRUE) )
|
return 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;
|
|
||||||
|
|
||||||
} // StringToCheckState
|
} // 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
|
// nsIStatefulFrame
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -615,15 +349,14 @@ NS_IMETHODIMP nsGfxCheckboxControlFrame::SaveState(nsIPresContext* aPresContext,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckState stateCheck = GetCheckboxState();
|
PRBool stateCheck = GetCheckboxState();
|
||||||
PRBool defaultStateBool = PR_FALSE;
|
PRBool defaultStateBool = PR_FALSE;
|
||||||
nsresult res = GetDefaultCheckState(&defaultStateBool);
|
nsresult res = GetDefaultCheckState(&defaultStateBool);
|
||||||
|
|
||||||
// Compare to default value, and only save if needed (Bug 62713)
|
// 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 &&
|
if (!(NS_CONTENT_ATTR_HAS_VALUE == res &&
|
||||||
((eOn == stateCheck && defaultStateBool) ||
|
((stateCheck && defaultStateBool) ||
|
||||||
(eOff == stateCheck && !defaultStateBool)))) {
|
(!stateCheck && !defaultStateBool)))) {
|
||||||
|
|
||||||
// Get the value string
|
// Get the value string
|
||||||
nsAutoString stateString;
|
nsAutoString stateString;
|
||||||
|
|
|
@ -66,21 +66,6 @@ public:
|
||||||
return MakeFrameName(NS_LITERAL_STRING("CheckboxControl"), aResult);
|
return MakeFrameName(NS_LITERAL_STRING("CheckboxControl"), aResult);
|
||||||
}
|
}
|
||||||
#endif
|
#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,
|
NS_IMETHOD Paint(nsIPresContext* aPresContext,
|
||||||
nsIRenderingContext& aRenderingContext,
|
nsIRenderingContext& aRenderingContext,
|
||||||
|
@ -93,10 +78,9 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//nsICheckboxControlFrame methods
|
//nsICheckboxControlFrame methods
|
||||||
NS_IMETHOD SetCheckboxFaceStyleContext(nsIStyleContext *aCheckboxFaceStyleContext);
|
NS_IMETHOD SetCheckboxFaceStyleContext(nsIStyleContext *aCheckboxFaceStyleContext);
|
||||||
|
NS_IMETHOD OnChecked(nsIPresContext* aPresContext, PRBool aChecked);
|
||||||
void InitializeControl(nsIPresContext* aPresContext);
|
|
||||||
|
|
||||||
NS_IMETHOD GetAdditionalStyleContext(PRInt32 aIndex,
|
NS_IMETHOD GetAdditionalStyleContext(PRInt32 aIndex,
|
||||||
nsIStyleContext** aStyleContext) const;
|
nsIStyleContext** aStyleContext) const;
|
||||||
|
@ -104,8 +88,6 @@ public:
|
||||||
nsIStyleContext* aStyleContext);
|
nsIStyleContext* aStyleContext);
|
||||||
|
|
||||||
// nsIFormControlFrame
|
// nsIFormControlFrame
|
||||||
NS_IMETHOD SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsAReadableString& aValue);
|
|
||||||
NS_IMETHOD GetProperty(nsIAtom* aName, nsAWritableString& aValue);
|
|
||||||
NS_IMETHOD OnContentReset();
|
NS_IMETHOD OnContentReset();
|
||||||
|
|
||||||
// nsIStatefulFrame
|
// nsIStatefulFrame
|
||||||
|
@ -121,14 +103,18 @@ public:
|
||||||
nsReflowStatus& aStatus);
|
nsReflowStatus& aStatus);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NS_IMETHOD GetChecked(PRBool* aIsChecked) { *aIsChecked = (GetCheckboxState() == eOn); return NS_OK; }
|
NS_IMETHOD GetChecked(PRBool* aIsChecked) {
|
||||||
NS_IMETHOD SetChecked(nsIPresContext* aPresContext, PRBool aIsChecked) { SetCheckboxState(aPresContext, aIsChecked ? eOn : eOff); return NS_OK; }
|
*aIsChecked = GetCheckboxState(); return NS_OK;
|
||||||
|
}
|
||||||
|
NS_IMETHOD SetChecked(nsIPresContext* aPresContext, PRBool aIsChecked) {
|
||||||
|
SetCheckboxState(aPresContext, aIsChecked); return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// native/gfx implementations need to implement needs.
|
// native/gfx implementations need to implement needs.
|
||||||
CheckState GetCheckboxState();
|
PRBool GetCheckboxState();
|
||||||
void SetCheckboxState(nsIPresContext* aPresContext, CheckState aValue);
|
void SetCheckboxState(nsIPresContext* aPresContext, PRBool aValue);
|
||||||
|
|
||||||
// Utility methods for implementing SetProperty/GetProperty
|
// Utility methods for implementing SetProperty/GetProperty
|
||||||
void SetCheckboxControlFrameState(nsIPresContext* aPresContext,
|
void SetCheckboxControlFrameState(nsIPresContext* aPresContext,
|
||||||
|
@ -136,22 +122,8 @@ protected:
|
||||||
void GetCheckboxControlFrameState(nsAWritableString& aValue);
|
void GetCheckboxControlFrameState(nsAWritableString& aValue);
|
||||||
|
|
||||||
// utility routine for converting from DOM values to internal enum
|
// utility routine for converting from DOM values to internal enum
|
||||||
void CheckStateToString ( CheckState inState, nsAWritableString& outStateAsString ) ;
|
void CheckStateToString(PRBool inState, nsAWritableString& outStateAsString) ;
|
||||||
CheckState StringToCheckState ( const nsAReadableString & aStateAsString ) ;
|
PRBool 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() ;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -159,12 +131,9 @@ protected:
|
||||||
nsIRenderingContext& aRenderingContext,
|
nsIRenderingContext& aRenderingContext,
|
||||||
const nsRect& aDirtyRect,
|
const nsRect& aDirtyRect,
|
||||||
nsFramePaintLayer aWhichLayer);
|
nsFramePaintLayer aWhichLayer);
|
||||||
virtual void PaintMixedMark(nsIRenderingContext& aRenderingContext,
|
|
||||||
float aPixelsToTwips, const nsRect& aRect) ;
|
|
||||||
|
|
||||||
//GFX-rendered state variables
|
//GFX-rendered state variables
|
||||||
PRBool mInClickEvent;
|
PRBool mInClickEvent;
|
||||||
CheckState mChecked;
|
|
||||||
nsIStyleContext* mCheckButtonFaceStyle;
|
nsIStyleContext* mCheckButtonFaceStyle;
|
||||||
|
|
||||||
private:
|
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>
|
|
Загрузка…
Ссылка в новой задаче