From e9a49a3ae1d3a25e6e1741322a376d66e191a02d Mon Sep 17 00:00:00 2001 From: "doronr%us.ibm.com" Date: Tue, 22 Feb 2005 22:11:51 +0000 Subject: [PATCH] XForms bug 273428. Patch by aaronr, r=me,beaufour. --- .../public/nsISchemaValidator.idl | 1 + .../src/nsSchemaValidator.cpp | 6 +-- .../schema-validation/src/nsSchemaValidator.h | 4 -- extensions/xforms/nsXFormsInputElement.cpp | 23 ++++++++-- extensions/xforms/nsXFormsModelElement.cpp | 45 +++++++++++-------- extensions/xforms/nsXFormsSchemaValidator.cpp | 8 ++++ extensions/xforms/nsXFormsSchemaValidator.h | 3 ++ extensions/xforms/nsXFormsUtils.cpp | 28 ++++++++++++ extensions/xforms/nsXFormsUtils.h | 8 ++++ 9 files changed, 98 insertions(+), 28 deletions(-) diff --git a/extensions/schema-validation/public/nsISchemaValidator.idl b/extensions/schema-validation/public/nsISchemaValidator.idl index 5926555c4de..af2e1df5b10 100644 --- a/extensions/schema-validation/public/nsISchemaValidator.idl +++ b/extensions/schema-validation/public/nsISchemaValidator.idl @@ -7,4 +7,5 @@ interface nsISchemaValidator : nsISupports { void loadSchema(in nsISchema aSchema); boolean validate(in nsIDOMNode aElement); boolean validateString(in AString aValue, in AString aType, in AString aNamespace); + nsISchemaType getType(in AString aType, in AString aNamespace); }; diff --git a/extensions/schema-validation/src/nsSchemaValidator.cpp b/extensions/schema-validation/src/nsSchemaValidator.cpp index 470479016da..fd0c6956766 100644 --- a/extensions/schema-validation/src/nsSchemaValidator.cpp +++ b/extensions/schema-validation/src/nsSchemaValidator.cpp @@ -246,9 +246,9 @@ NS_IMETHODIMP nsSchemaValidator::Validate(nsIDOMNode* aElement, PRBool *aResult) /* Returns the nsISchemaType for a given value/type/namespace pair. */ -nsresult nsSchemaValidator::GetType(const nsAString & aType, - const nsAString & aNamespace, - nsISchemaType ** aSchemaType) +NS_IMETHODIMP nsSchemaValidator::GetType(const nsAString & aType, + const nsAString & aNamespace, + nsISchemaType ** aSchemaType) { nsresult rv; diff --git a/extensions/schema-validation/src/nsSchemaValidator.h b/extensions/schema-validation/src/nsSchemaValidator.h index d5188cb8751..bf344d25b4c 100644 --- a/extensions/schema-validation/src/nsSchemaValidator.h +++ b/extensions/schema-validation/src/nsSchemaValidator.h @@ -118,10 +118,6 @@ public: private: ~nsSchemaValidator(); - nsresult GetType(const nsAString & aType, - const nsAString & aNamespace, - nsISchemaType **aSchemaType); - // methods dealing with simpletypes nsresult ValidateSimpletype(const nsAString & aNodeValue, nsISchemaSimpleType *aSchemaSimpleType, PRBool *aResult); nsresult ValidateRestrictionSimpletype(const nsAString & aNodeValue, nsISchemaSimpleType *aSchemaSimpleType, PRBool *aResult); diff --git a/extensions/xforms/nsXFormsInputElement.cpp b/extensions/xforms/nsXFormsInputElement.cpp index d5cb9c9c738..b0c878b4b87 100644 --- a/extensions/xforms/nsXFormsInputElement.cpp +++ b/extensions/xforms/nsXFormsInputElement.cpp @@ -214,7 +214,7 @@ nsXFormsInputElement::OnDestroyed() NS_IMETHODIMP nsXFormsInputElement::AttributeSet(nsIAtom *aName, const nsAString &aValue) { - nsXFormsControlStub::WillSetAttribute(aName, aValue); + nsXFormsControlStub::AttributeSet(aName, aValue); if (aName == nsXFormsAtoms::incremental) mIncremental = aValue.EqualsLiteral("true"); @@ -235,7 +235,12 @@ nsXFormsInputElement::HandleDefault(nsIDOMEvent *aEvent, nsAutoString type; aEvent->GetType(type); - if (type.EqualsLiteral("keyup")) + + // Seems like too big of a hassle for too little gain to also check if we are + // a checkbox in addition to checking for the click. Plus, other input types + // like a date picker for input controls bound to a xsi:date type might + // need click updates, too. + if (type.EqualsLiteral("keyup") || type.EqualsLiteral("click")) UpdateInstanceData(); return NS_OK; @@ -282,7 +287,15 @@ nsXFormsInputElement::UpdateInstanceData() if (mType == eType_Input && type.EqualsLiteral("checkbox")) { PRBool checked; input->GetChecked(&checked); - value.AssignASCII(checked ? "1" : "0", 1); + // XXX we've got a problem here. Since UpdateInstanceData can be called + // due to a blur event, as it stands now we could be changing the instance + // data values even if the user didn't click on the checkbox, but instead + // was just tabbing through the form. + if(checked) { + value.Append(NS_LITERAL_STRING("true")); + } else { + value.Append(NS_LITERAL_STRING("false")); + } } else { input->GetValue(value); } @@ -345,6 +358,10 @@ nsXFormsInputElement::Refresh() input->SetChecked(text.EqualsLiteral("true") || text.EqualsLiteral("1")); + + // other xforms processors default to incremental update in this case, + // so we should, too. + mIncremental = PR_TRUE; } else { input->RemoveAttribute(NS_LITERAL_STRING("type")); input->SetValue(text); diff --git a/extensions/xforms/nsXFormsModelElement.cpp b/extensions/xforms/nsXFormsModelElement.cpp index 8ec60390791..74fb6abb083 100644 --- a/extensions/xforms/nsXFormsModelElement.cpp +++ b/extensions/xforms/nsXFormsModelElement.cpp @@ -768,8 +768,31 @@ NS_IMETHODIMP nsXFormsModelElement::GetTypeForControl(nsIXFormsControl *aControl, nsISchemaType **aType) { + NS_ENSURE_ARG_POINTER(aType); *aType = nsnull; - return NS_OK; + + nsAutoString schemaTypeName; + nsAutoString schemaTypePrefix; + nsCOMPtr boundNode; + + aControl->GetBoundNode(getter_AddRefs(boundNode)); + NS_ENSURE_TRUE(boundNode, NS_ERROR_FAILURE); + nsresult rv = nsXFormsUtils::ParseTypeFromNode(boundNode, schemaTypeName, + schemaTypePrefix); + NS_ENSURE_SUCCESS(rv, rv); + + // get the namespace url from the prefix + nsCOMPtr domNode3 = do_QueryInterface(mElement, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsAutoString schemaTypeNamespace; + rv = domNode3->LookupNamespaceURI(schemaTypePrefix, schemaTypeNamespace); + NS_ENSURE_SUCCESS(rv, rv); + + nsXFormsSchemaValidator validator; + nsCOMPtr schema = do_QueryInterface(mSchemas); + validator.LoadSchema(schema); + return validator.GetType(schemaTypeName, schemaTypeNamespace, aType); } NS_IMETHODIMP @@ -856,32 +879,18 @@ NS_IMETHODIMP nsXFormsModelElement::ValidateNode(nsIDOMNode *aInstanceNode, PRBool *aResult) { NS_ENSURE_ARG_POINTER(aResult); - nsresult rv; - - nsAutoString typeAttribute; - nsCOMPtr nodeElem = do_QueryInterface(aInstanceNode, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - nodeElem->GetAttributeNS(NS_LITERAL_STRING(NS_NAMESPACE_XML_SCHEMA_INSTANCE), - NS_LITERAL_STRING("type"), typeAttribute); - - // split type (ns:type) into namespace and type. - PRInt32 separator = typeAttribute.FindChar(':'); - if ((separator == kNotFound) || ((PRUint32) separator == typeAttribute.Length())) - return NS_ERROR_UNEXPECTED; - // xxx send error to console nsAutoString schemaTypeName; nsAutoString schemaTypePrefix; - nsAutoString schemaTypeNamespace; + nsresult rv = nsXFormsUtils::ParseTypeFromNode(aInstanceNode, schemaTypeName, + schemaTypePrefix); - schemaTypePrefix.Assign(Substring(typeAttribute, 0, separator)); - schemaTypeName.Assign(Substring(typeAttribute, ++separator, typeAttribute.Length())); // get the namespace url from the prefix nsCOMPtr domNode3 = do_QueryInterface(mElement, &rv); NS_ENSURE_SUCCESS(rv, rv); + nsAutoString schemaTypeNamespace; rv = domNode3->LookupNamespaceURI(schemaTypePrefix, schemaTypeNamespace); NS_ENSURE_SUCCESS(rv, rv); diff --git a/extensions/xforms/nsXFormsSchemaValidator.cpp b/extensions/xforms/nsXFormsSchemaValidator.cpp index 77edb01d0bc..00f1fd9a65f 100644 --- a/extensions/xforms/nsXFormsSchemaValidator.cpp +++ b/extensions/xforms/nsXFormsSchemaValidator.cpp @@ -77,3 +77,11 @@ PRBool nsXFormsSchemaValidator::Validate(nsIDOMNode* aElement) return isValid; } +PRBool nsXFormsSchemaValidator::GetType(const nsAString & aType, + const nsAString & aNamespace, nsISchemaType **aSchemaType) +{ + NS_ENSURE_TRUE(mSchemaValidator, PR_FALSE); + nsresult rv = mSchemaValidator->GetType(aType, aNamespace, aSchemaType); + + return( NS_SUCCEEDED(rv) ); +} diff --git a/extensions/xforms/nsXFormsSchemaValidator.h b/extensions/xforms/nsXFormsSchemaValidator.h index 1bcfebb02cd..e8260492542 100644 --- a/extensions/xforms/nsXFormsSchemaValidator.h +++ b/extensions/xforms/nsXFormsSchemaValidator.h @@ -49,6 +49,9 @@ public: PRBool ValidateString(const nsAString & aValue, const nsAString & aType, const nsAString & aNamespace); PRBool Validate(nsIDOMNode* aElement); + PRBool GetType(const nsAString & aType, const nsAString & aNamespace, + nsISchemaType **aSchemaType); + protected: nsCOMPtr mSchemaValidator; diff --git a/extensions/xforms/nsXFormsUtils.cpp b/extensions/xforms/nsXFormsUtils.cpp index 723ee743e4e..84805c8debe 100644 --- a/extensions/xforms/nsXFormsUtils.cpp +++ b/extensions/xforms/nsXFormsUtils.cpp @@ -1014,3 +1014,31 @@ nsXFormsUtils::GetInstanceNodeForData(nsIDOMNode *aInstanceDataNode, return NS_OK; } + +/* static */ nsresult +nsXFormsUtils::ParseTypeFromNode(nsIDOMNode *aInstanceData, + nsAString &aType, nsAString &aNSPrefix) +{ + nsresult rv; + nsCOMPtr nodeElem = do_QueryInterface(aInstanceData, &rv); + NS_ENSURE_TRUE(nodeElem, NS_ERROR_FAILURE); + + // right now type is stored as an attribute on the instance node. In the + // future it will be a property. + nsAutoString typeAttribute; + nodeElem->GetAttributeNS(NS_LITERAL_STRING(NS_NAMESPACE_XML_SCHEMA_INSTANCE), + NS_LITERAL_STRING("type"), typeAttribute); + + // split type (ns:type) into namespace and type. + PRInt32 separator = typeAttribute.FindChar(':'); + if ((separator == kNotFound) || + ((PRUint32) separator == typeAttribute.Length())) { + return NS_ERROR_UNEXPECTED; + // xxx send error to console + } + + aNSPrefix.Assign(Substring(typeAttribute, 0, separator)); + aType.Assign(Substring(typeAttribute, ++separator, typeAttribute.Length())); + + return NS_OK; +} diff --git a/extensions/xforms/nsXFormsUtils.h b/extensions/xforms/nsXFormsUtils.h index f1a844dfe5f..b8865089405 100644 --- a/extensions/xforms/nsXFormsUtils.h +++ b/extensions/xforms/nsXFormsUtils.h @@ -337,6 +337,14 @@ public: nsIModelElementPrivate *aModel, nsIDOMNode **aInstanceNode); + /** + * This function takes an instance data node, finds the type bound to it, and + * returns the seperated out type (integer) and namespace prefix (xsd). + */ + static NS_HIDDEN_(nsresult) ParseTypeFromNode(nsIDOMNode *aInstanceData, + nsAString &aType, + nsAString &aNSPrefix); + }; #endif