diff --git a/mozilla/extensions/xforms/nsXFormsModelElement.cpp b/mozilla/extensions/xforms/nsXFormsModelElement.cpp index 6643898471b..1f68f01f429 100644 --- a/mozilla/extensions/xforms/nsXFormsModelElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsModelElement.cpp @@ -1518,6 +1518,62 @@ nsXFormsModelElement::ValidateNode(nsIDOMNode *aInstanceNode, PRBool *aResult) return NS_OK; } +NS_IMETHODIMP +nsXFormsModelElement::ValidateDocument(nsIDOMDocument *aInstanceDocument, + PRBool *aResult) +{ + NS_ENSURE_ARG_POINTER(aResult); + NS_ENSURE_ARG(aInstanceDocument); + + /* + This will process the instance document and check for schema validity. It + will mark nodes in the document with their schema types using nsIProperty + until it hits a structural schema validation error. So if the instance + document's XML structure is invalid, don't expect type properties to be + set. + + Note that if the structure is fine but some simple types nodes (nodes + that contain text only) are invalid (say one has a empty nodeValue but + should be a date), the schema validator will continue processing and add + the type properties. Schema validation will return false at the end. + */ + + nsCOMPtr element; + nsresult rv = aInstanceDocument->GetDocumentElement(getter_AddRefs(element)); + NS_ENSURE_SUCCESS(rv, rv); + + PRBool isValid = PR_FALSE; + + // get namespace from node + nsAutoString nsuri; + element->GetNamespaceURI(nsuri); + + nsCOMPtr schemaColl = do_QueryInterface(mSchemas); + NS_ENSURE_STATE(schemaColl); + + nsCOMPtr schema; + schemaColl->GetSchema(nsuri, getter_AddRefs(schema)); + if (schema) { + nsXFormsSchemaValidator validator; + validator.LoadSchema(schema); + // Validate will validate the node and its subtree, as per the schema + // specification. + isValid = validator.Validate(element); + } else { + // no schema found for the instance document's namespace. + nsCOMPtr instanceElement; + nsXFormsUtils::GetInstanceNodeForData(element, + getter_AddRefs(instanceElement)); + const PRUnichar *strings[] = { nsuri.get() }; + nsXFormsUtils::ReportError(NS_LITERAL_STRING("noSchemaForInstance"), + strings, 1, instanceElement, nsnull); + rv = NS_ERROR_UNEXPECTED; + } + + *aResult = isValid; + return rv; +} + /* * SUBMIT_SERIALIZE_NODE - node is to be serialized * SUBMIT_SKIP_NODE - node is not to be serialized @@ -1588,6 +1644,21 @@ nsXFormsModelElement::GetTypeFromNode(nsIDOMNode *aInstanceData, // If there was no type information on the node itself, check for a type // bound to the node via \ if (!typeVal && !mNodeToType.Get(aInstanceData, &typeVal)) { + // check if schema validation left us a nsISchemaType* + nsCOMPtr content = do_QueryInterface(aInstanceData); + + if (content) { + nsISchemaType *type; + nsCOMPtr myAtom = do_GetAtom("xsdtype"); + + type = NS_STATIC_CAST(nsISchemaType *, content->GetProperty(myAtom)); + if (type) { + type->GetName(aType); + type->GetTargetNamespace(aNSUri); + return NS_OK; + } + } + // No type information found return NS_ERROR_NOT_AVAILABLE; } @@ -1932,6 +2003,37 @@ nsXFormsModelElement::MaybeNotifyCompletion() nsXFormsUtils::DispatchEvent(model->mElement, eEvent_ModelConstructDone); } + // validate the instance documents becauar we want schemaValidation to add + // schema type properties from the schema file unto our instance document + // elements. We don't care about the validation results. + if (mInstanceDocuments) { + PRUint32 instCount; + mInstanceDocuments->GetLength(&instCount); + if (instCount) { + nsCOMPtr document; + + for (PRUint32 i = 0; i < instCount; ++i) { + nsIInstanceElementPrivate* instEle = mInstanceDocuments->GetInstanceAt(i); + nsCOMPtr NSInstEle(instEle); + NSInstEle->GetInstanceDocument(getter_AddRefs(document)); + NS_ASSERTION(document, "nsIXFormsNSInstanceElement::GetInstanceDocument returned null?!"); + + if (document) { + PRBool isValid = PR_FALSE; + ValidateDocument(document, &isValid); + + if (!isValid) { + nsCOMPtr instanceElement; + instEle->GetElement(getter_AddRefs(instanceElement)); + + nsXFormsUtils::ReportError(NS_LITERAL_STRING("instDocumentInvalid"), + instanceElement); + } + } + } + } + } + nsXFormsModelElement::ProcessDeferredBinds(domDoc); nsCOMPtr doc = do_QueryInterface(domDoc); diff --git a/mozilla/extensions/xforms/nsXFormsModelElement.h b/mozilla/extensions/xforms/nsXFormsModelElement.h index 30e42719343..20d20847396 100644 --- a/mozilla/extensions/xforms/nsXFormsModelElement.h +++ b/mozilla/extensions/xforms/nsXFormsModelElement.h @@ -349,7 +349,10 @@ private: NS_HIDDEN_(nsresult) HandleUnload(nsIDOMEvent *aEvent); NS_HIDDEN_(nsresult) RefreshSubTree(nsXFormsControlListItem *aCurrent, - PRBool aForceRebind); + PRBool aForceRebind); + + NS_HIDDEN_(nsresult) ValidateDocument(nsIDOMDocument *aInstanceDocument, + PRBool *aResult); nsIDOMElement *mElement; nsCOMPtr mSchemas; diff --git a/mozilla/extensions/xforms/nsXFormsSchemaValidator.cpp b/mozilla/extensions/xforms/nsXFormsSchemaValidator.cpp index 5346272cdd9..144fff24fcf 100644 --- a/mozilla/extensions/xforms/nsXFormsSchemaValidator.cpp +++ b/mozilla/extensions/xforms/nsXFormsSchemaValidator.cpp @@ -83,28 +83,12 @@ nsXFormsSchemaValidator::ValidateString(const nsAString & aValue, } PRBool -nsXFormsSchemaValidator::ValidateNode(nsIDOMNode* aElement, - const nsAString & aType, - const nsAString & aNamespace) +nsXFormsSchemaValidator::Validate(nsIDOMNode* aElement) { PRBool isValid = PR_FALSE; NS_ENSURE_TRUE(mSchemaValidator, isValid); - if (aNamespace.EqualsLiteral(NS_NAMESPACE_XFORMS)) { - // XXX: currently, we will only support validating a lone node. When - // we get complex type support, we should load the schema for the xforms - // types and use ValidateAgainstType like below. - nsAutoString nodeValue; - nsCOMPtr domNode3 = do_QueryInterface(aElement); - domNode3->GetTextContent(nodeValue); - - isValid = ValidateString(nodeValue, aType, aNamespace); - } else { - nsCOMPtr type; - if (GetType(aType, aNamespace, getter_AddRefs(type))) { - mSchemaValidator->ValidateAgainstType(aElement, type, &isValid); - } - } + mSchemaValidator->Validate(aElement, &isValid); return isValid; } diff --git a/mozilla/extensions/xforms/nsXFormsSchemaValidator.h b/mozilla/extensions/xforms/nsXFormsSchemaValidator.h index b1ddf0ebfe3..aaebe121586 100644 --- a/mozilla/extensions/xforms/nsXFormsSchemaValidator.h +++ b/mozilla/extensions/xforms/nsXFormsSchemaValidator.h @@ -64,15 +64,12 @@ public: const nsAString & aNamespace); /** - * Validates a node against a namespace and schema type + * Validates a node and its subtree against the loaded schema(s) * * @param aElement Node to validate - * @param aType Type - * @param aNamespace Namespace * @return Whether the string is valid or not */ - PRBool ValidateNode(nsIDOMNode* aElement, const nsAString & aType, - const nsAString & aNamespace); + PRBool Validate(nsIDOMNode* aElement); /** * Returns a nsISchemaType given an type and namespace diff --git a/mozilla/extensions/xforms/resources/locale/en-US/xforms.properties b/mozilla/extensions/xforms/resources/locale/en-US/xforms.properties index a823f281a57..5cc55945e0c 100644 --- a/mozilla/extensions/xforms/resources/locale/en-US/xforms.properties +++ b/mozilla/extensions/xforms/resources/locale/en-US/xforms.properties @@ -71,10 +71,12 @@ externalLinkLoadOrigin = XForms Error (32): Security check failed! Trying to loa instanceNotFound = XForms Error (33): Could not find instance with id == '%S' defInstanceNotFound = XForms Error (34): Could not find default instance MDGLoopError = XForms Error (35): There are loops in the bindings of the model! +noSchemaForInstance = XForms Error (36): Could not find a schema for validating the instance document (namespace=%S) # Warning Messages: warnSOAP = XForms Warning (1): You are using the SOAP post feature, which is an experimental feature! Beware that the functionality might change, and forms may stop working at any time. warnMailtoBodyParam = XForms Warning (2): The submission action uri already contains a body parameter. +instDocumentInvalid = XForms Warning (3): Instance document did not validate. # XForms Permission Messages: xformsXDPermissionDialogTitle = Allowed Sites - XForms Cross Domain Access