diff --git a/extensions/xforms/nsXFormsSubmissionElement.cpp b/extensions/xforms/nsXFormsSubmissionElement.cpp index 614fb4429c3b..3bf21486f264 100644 --- a/extensions/xforms/nsXFormsSubmissionElement.cpp +++ b/extensions/xforms/nsXFormsSubmissionElement.cpp @@ -509,33 +509,61 @@ nsXFormsSubmissionElement::LoadReplaceInstance(nsIChannel *channel) } } - // get the nodeset that we are currently bound to - nsCOMPtr data; + // Get the appropriate instance node. If the "instance" attribute is set, + // then get that instance node. Otherwise, get the one we are bound to. + nsresult rv; nsCOMPtr model = GetModel(); NS_ENSURE_STATE(model); - nsresult rv = GetSelectedInstanceData(getter_AddRefs(data)); - if (NS_SUCCEEDED(rv)) { - nsCOMPtr instanceNode; - rv = nsXFormsUtils::GetInstanceNodeForData(data, model, - getter_AddRefs(instanceNode)); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr instanceElement; + nsAutoString value; + mElement->GetAttribute(NS_LITERAL_STRING("instance"), value); + if (!value.IsEmpty()) { + rv = GetSelectedInstanceElement(value, model, + getter_AddRefs(instanceElement)); + } else { + nsCOMPtr data; + rv = GetBoundInstanceData(getter_AddRefs(data)); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr instanceNode; + rv = nsXFormsUtils::GetInstanceNodeForData(data, model, + getter_AddRefs(instanceNode)); + NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr instanceElement = - do_QueryInterface(instanceNode); - - // replace the document referenced by this instance element with the info - // returned back from the submission - if (instanceElement) { - instanceElement->SetDocument(newDoc); - - // refresh everything - model->Rebuild(); - model->Recalculate(); - model->Revalidate(); - model->Refresh(); + instanceElement = do_QueryInterface(instanceNode); } } + // replace the document referenced by this instance element with the info + // returned back from the submission + if (NS_SUCCEEDED(rv) && instanceElement) { + instanceElement->SetDocument(newDoc); + + // refresh everything + model->Rebuild(); + model->Recalculate(); + model->Revalidate(); + model->Refresh(); + } + + + return NS_OK; +} + +nsresult +nsXFormsSubmissionElement::GetSelectedInstanceElement( + const nsAString &aInstanceID, + nsIModelElementPrivate *aModel, + nsIInstanceElementPrivate **aResult) +{ + aModel->FindInstanceElement(aInstanceID, aResult); + if (*aResult == nsnull) { + // if failed to get desired instance, dispatch binding exception + const PRUnichar *strings[] = { PromiseFlatString(aInstanceID).get() }; + nsXFormsUtils::ReportError(NS_LITERAL_STRING("instanceBindError"), + strings, 1, mElement, mElement); + nsXFormsUtils::DispatchEvent(mElement, eEvent_BindingException); + return NS_ERROR_FAILURE; + } return NS_OK; } @@ -598,7 +626,7 @@ nsXFormsSubmissionElement::Submit() // 2. get selected node from the instance data (use xpath, gives us node // iterator) nsCOMPtr data; - rv = GetSelectedInstanceData(getter_AddRefs(data)); + rv = GetBoundInstanceData(getter_AddRefs(data)); NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && data, rv); @@ -628,7 +656,7 @@ nsXFormsSubmissionElement::Submit() } nsresult -nsXFormsSubmissionElement::GetSelectedInstanceData(nsIDOMNode **result) +nsXFormsSubmissionElement::GetBoundInstanceData(nsIDOMNode **result) { nsCOMPtr model; nsCOMPtr xpRes; diff --git a/extensions/xforms/nsXFormsSubmissionElement.h b/extensions/xforms/nsXFormsSubmissionElement.h index 36ed451e1f02..de8b51b09a19 100644 --- a/extensions/xforms/nsXFormsSubmissionElement.h +++ b/extensions/xforms/nsXFormsSubmissionElement.h @@ -98,7 +98,8 @@ public: NS_HIDDEN_(nsresult) Submit(); NS_HIDDEN_(PRBool) GetBooleanAttr(const nsAString &attrName, PRBool defaultVal = PR_FALSE); NS_HIDDEN_(void) GetDefaultInstanceData(nsIDOMNode **result); - NS_HIDDEN_(nsresult) GetSelectedInstanceData(nsIDOMNode **result); + NS_HIDDEN_(nsresult) GetBoundInstanceData(nsIDOMNode **result); + NS_HIDDEN_(nsresult) GetSelectedInstanceElement(const nsAString &aInstance, nsIModelElementPrivate *aModel, nsIInstanceElementPrivate **result); NS_HIDDEN_(nsresult) SerializeData(nsIDOMNode *data, nsCString &uri, nsIInputStream **, nsCString &contentType); NS_HIDDEN_(nsresult) SerializeDataXML(nsIDOMNode *data, nsIInputStream **, nsCString &contentType, SubmissionAttachmentArray *); NS_HIDDEN_(nsresult) CreateSubmissionDoc(nsIDOMNode *source, const nsString &encoding, SubmissionAttachmentArray *, nsIDOMDocument **result); diff --git a/extensions/xforms/resources/locale/en-US/xforms.properties b/extensions/xforms/resources/locale/en-US/xforms.properties index 3ba6e0605227..42e8333acb4e 100644 --- a/extensions/xforms/resources/locale/en-US/xforms.properties +++ b/extensions/xforms/resources/locale/en-US/xforms.properties @@ -56,6 +56,7 @@ labelLinkLoadOrigin = XForms Error (17): Security check failed! Trying to load labelLink1Error = XForms Error (18): External file (%S) for Label element not found labelLink2Error = XForms Error (19): Failed to load Label element from external file: %S invalidSeparator = XForms Error (20): Submission separator may only be either "&" or ";", but found "%S". +instanceBindError = XForms Error (21): Submission failed trying to replace instance document '%S'. Instance document doesn't exist in same model as submission element. # XForms Permission Messages: xformsXDPermissionDialogTitle = Allowed Sites - XForms Cross Domain Access