[XForms] non-relevant nodes not removed for some types of submission. Bug 338314, r=doronr+aaronr

This commit is contained in:
allan%beaufour.dk 2006-05-22 08:41:06 +00:00
Родитель 842eeaeb44
Коммит c9fd254723
5 изменённых файлов: 376 добавлений и 387 удалений

Просмотреть файл

@ -37,10 +37,6 @@
* ***** END LICENSE BLOCK ***** */
#include "nsXFormsElementFactory.h"
#include "nsXFormsModelElement.h"
#include "nsXFormsInstanceElement.h"
#include "nsXFormsSubmissionElement.h"
#include "nsXFormsStubElement.h"
#include "nsIDOMDocument.h"
#include "nsXFormsAtoms.h"
#include "nsIDocument.h"
@ -97,6 +93,11 @@ NS_HIDDEN_(nsresult) NS_NewXFormsToggleElement(nsIXTFElement **aResult);
NS_HIDDEN_(nsresult) NS_NewXFormsCaseElement(nsIXTFElement **aResult);
NS_HIDDEN_(nsresult) NS_NewXFormsSwitchElement(nsIXTFElement **aResult);
NS_HIDDEN_(nsresult) NS_NewXFormsModelElement(nsIXTFElement **aElement);
NS_HIDDEN_(nsresult) NS_NewXFormsSubmissionElement(nsIXTFElement **aElement);
NS_HIDDEN_(nsresult) NS_NewXFormsInstanceElement(nsIXTFElement **aElement);
NS_HIDDEN_(nsresult) NS_NewXFormsStubElement(nsIXTFElement **aElement);
NS_IMPL_ISUPPORTS2(nsXFormsElementFactory,
nsIXTFElementFactory,
nsIDOMNSFeatureFactory)

Просмотреть файл

@ -1644,7 +1644,8 @@ nsXFormsModelElement::ValidateDocument(nsIDOMDocument *aInstanceDocument,
* SUBMIT_ABORT_SUBMISSION - abort submission (invalid node or empty required node)
*/
NS_IMETHODIMP
nsXFormsModelElement::HandleInstanceDataNode(nsIDOMNode *aInstanceDataNode, unsigned short *aResult)
nsXFormsModelElement::HandleInstanceDataNode(nsIDOMNode *aInstanceDataNode,
unsigned short *aResult)
{
// abort by default
*aResult = SUBMIT_ABORT_SUBMISSION;

Просмотреть файл

@ -95,6 +95,7 @@
#include "nsIMIMEHeaderParam.h"
#include "nsIExternalProtocolService.h"
#include "nsEscape.h"
#include "nsAutoPtr.h"
// namespace literals
#define kXMLNSNameSpaceURI \
@ -600,11 +601,18 @@ nsXFormsSubmissionElement::Submit()
{
LOG(("+++ nsXFormsSubmissionElement::Submit\n"));
NS_ENSURE_STATE(mElement);
nsresult rv;
mIsSOAPRequest = PR_FALSE;
//
// 1. ensure that we are not currently processing a xforms-submit (see E37)
NS_ENSURE_STATE(!mSubmissionActive);
if (mSubmissionActive) {
nsXFormsUtils::ReportError(NS_LITERAL_STRING("warnSubmitAlreadyRunning"),
mElement, nsIScriptError::warningFlag);
return NS_ERROR_FAILURE;
}
mSubmissionActive = PR_TRUE;
if (mActivator)
@ -615,17 +623,9 @@ nsXFormsSubmissionElement::Submit()
nsAutoString replace;
mElement->GetAttribute(NS_LITERAL_STRING("replace"), replace);
mIsReplaceInstance = replace.EqualsLiteral("instance");
// XXX seems to be required by
// http://www.w3.org/TR/2003/REC-xforms-20031014/slice4.html#evt-revalidate
// but is it really needed for us?
nsCOMPtr<nsIModelElementPrivate> model = GetModel();
NS_ENSURE_STATE(model);
model->Recalculate();
model->Revalidate();
// 2. get selected node from the instance data (use xpath, gives us node
// iterator)
//
// 2. get selected node from the instance data
nsCOMPtr<nsIDOMNode> data;
rv = GetBoundInstanceData(getter_AddRefs(data));
NS_ENSURE_SUCCESS(rv, rv);
@ -636,26 +636,44 @@ nsXFormsSubmissionElement::Submit()
return NS_OK;
}
// 3. revalidate selected instance data (only for namespaces considered for
// serialization)
//
// 3. Create submission document (include namespaces, purge non-relevant
// nodes, check simple type validity)
nsCOMPtr<nsIDOMDocument> submissionDoc;
rv = CreateSubmissionDoc(data, getter_AddRefs(submissionDoc));
NS_ENSURE_SUCCESS(rv, rv);
// This is handled by the SerializeData() method
//
// 4. Validate document
// XXX: model->ValidateDocument(submissionDoc, &res);
// 4. serialize instance data
//
// 5. Convert submission document into the requested format
// Checking the format only before starting the submission.
mFormat = GetSubmissionFormat(mElement);
NS_ENSURE_STATE(mFormat != 0);
nsCOMPtr<nsIInputStream> stream;
nsCAutoString uri, contentType;
rv = SerializeData(data, uri, getter_AddRefs(stream), contentType);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString action;
mElement->GetAttribute(NS_LITERAL_STRING("action"), action);
CopyUTF16toUTF8(action, uri);
rv = SerializeData(submissionDoc, uri, getter_AddRefs(stream), contentType);
if (NS_FAILED(rv)) {
nsXFormsUtils::ReportError(NS_LITERAL_STRING("warnSubmitSerializeFailed"),
mElement, nsIScriptError::warningFlag);
return rv;
}
// 5. dispatch network request
//
// 6. dispatch network request
rv = SendData(uri, stream, contentType);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
nsXFormsUtils::ReportError(NS_LITERAL_STRING("warnSubmitNetworkFailure"),
mElement, nsIScriptError::warningFlag);
return rv;
}
return rv;
}
@ -735,52 +753,31 @@ nsXFormsSubmissionElement::GetDefaultInstanceData(nsIDOMNode **result)
}
nsresult
nsXFormsSubmissionElement::SerializeData(nsIDOMNode *data,
nsCString &uri,
nsIInputStream **stream,
nsCString &contentType)
nsXFormsSubmissionElement::SerializeData(nsIDOMDocument *aData,
nsCString &aUri,
nsIInputStream **aStream,
nsCString &aContentType)
{
// initialize uri to the given action
nsAutoString action;
mElement->GetAttribute(NS_LITERAL_STRING("action"), action);
CopyUTF16toUTF8(action, uri);
// 'get' method:
// The URI is constructed as follows:
// o The submit URI from the action attribute is examined. If it does not
// already contain a ? (question mark) character, one is appended. If it
// does already contain a question mark character, then a separator
// character from the attribute separator is appended.
// o The serialized form data is appended to the URI.
if (mFormat & ENCODING_XML)
return SerializeDataXML(data, stream, contentType, nsnull);
// Ensure the data is valid and required nodes are non-empty
// This is handled directly within SerializeDataXML()
nsCOMPtr<nsIModelElementPrivate> model = GetModel();
NS_ENSURE_STATE(model);
nsresult rv = CanSubmit(data, model, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
return SerializeDataXML(aData, aStream, aContentType);
if (mFormat & ENCODING_URL)
return SerializeDataURLEncoded(data, uri, stream, contentType);
return SerializeDataURLEncoded(aData, aUri, aStream, aContentType);
if (mFormat & ENCODING_MULTIPART_RELATED)
return SerializeDataMultipartRelated(data, stream, contentType);
return SerializeDataMultipartRelated(aData, aStream, aContentType);
if (mFormat & ENCODING_MULTIPART_FORM_DATA)
return SerializeDataMultipartFormData(data, stream, contentType);
return SerializeDataMultipartFormData(aData, aStream, aContentType);
NS_WARNING("unsupported submission encoding");
return NS_ERROR_UNEXPECTED;
}
nsresult
nsXFormsSubmissionElement::SerializeDataXML(nsIDOMNode *data,
nsXFormsSubmissionElement::SerializeDataXML(nsIDOMDocument *data,
nsIInputStream **stream,
nsCString &contentType,
SubmissionAttachmentArray *attachments)
nsCString &contentType)
{
nsresult rv;
nsAutoString mediaType;
@ -833,11 +830,6 @@ nsXFormsSubmissionElement::SerializeDataXML(nsIDOMNode *data,
CopyUTF16toUTF8(mediaType, contentType);
}
nsAutoString encoding;
mElement->GetAttribute(NS_LITERAL_STRING("encoding"), encoding);
if (encoding.IsEmpty())
encoding.AssignLiteral("UTF-8");
nsCOMPtr<nsIStorageStream> storage;
NS_NewStorageStream(4096, PR_UINT32_MAX, getter_AddRefs(storage));
NS_ENSURE_TRUE(storage, NS_ERROR_OUT_OF_MEMORY);
@ -850,117 +842,14 @@ nsXFormsSubmissionElement::SerializeDataXML(nsIDOMNode *data,
do_GetService("@mozilla.org/xmlextras/xmlserializer;1");
NS_ENSURE_STATE(serializer);
nsCOMPtr<nsIDOMDocument> instDoc, submDoc;
data->GetOwnerDocument(getter_AddRefs(instDoc));
// XXX: We can't simply pass in data if !doc, since it crashes
if (!instDoc) {
// owner doc is null when the data node is the document (e.g., ref="/")
// so we can just get the document via QI.
instDoc = do_QueryInterface(data);
NS_ENSURE_STATE(instDoc);
rv = CreateSubmissionDoc(instDoc, encoding, attachments,
getter_AddRefs(submDoc));
} else {
// if we got a document, we need to create a new
rv = CreateSubmissionDoc(data, encoding, attachments,
getter_AddRefs(submDoc));
}
// clone and possibly modify the document for submission
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(submDoc);
// We now need to add namespaces to the submission document. We get them
// from 3 sources - the main document's documentElement, the model and the
// xforms:instance that contains the submitted instance data node.
nsCOMPtr<nsIDOMNode> instanceNode;
rv = nsXFormsUtils::GetInstanceNodeForData(data, getter_AddRefs(instanceNode));
NS_ENSURE_SUCCESS(rv, rv);
// add namespaces from the main document to the submission document, but only
// if the instance data is local, not remote.
PRBool serialize = PR_FALSE;
nsCOMPtr<nsIDOMElement> instanceElement(do_QueryInterface(instanceNode));
// make sure that this is a DOMElement. It won't be if it was lazy
// authored. Lazy authored instance documents don't inherit namespaces
// from parent nodes or the original document (in formsPlayer and Novell,
// at least).
if (instanceElement) {
PRBool hasSrc = PR_FALSE;
instanceElement->HasAttribute(NS_LITERAL_STRING("src"), &hasSrc);
serialize = !hasSrc;
}
if (serialize) {
// Handle "includenamespaceprefixes" attribute, if present
nsStringHashSet* prefixHash = nsnull;
PRBool hasPrefixAttr = PR_FALSE;
mElement->HasAttribute(kIncludeNamespacePrefixes, &hasPrefixAttr);
if (hasPrefixAttr) {
rv = GetIncludeNSPrefixesAttr(&prefixHash);
NS_ENSURE_SUCCESS(rv, rv);
}
// get the document element of the document we are going to submit
nsCOMPtr<nsIDOMElement> submDocElm;
submDoc->GetDocumentElement(getter_AddRefs(submDocElm));
NS_ENSURE_STATE(submDocElm);
// if submission document has empty default namespace attribute and if
// @includenamespaceprefixes attribute doesn't contain "#default" value then
// we should remove default namespace attribute (see the specs 11.3).
nsAutoString XMLNSAttrValue;
submDocElm->GetAttributeNS(kXMLNSNameSpaceURI, NS_LITERAL_STRING("xmlns"),
XMLNSAttrValue);
if (XMLNSAttrValue.IsEmpty() && (!prefixHash ||
!prefixHash->Contains(NS_LITERAL_STRING("#default")))) {
submDocElm->RemoveAttributeNS(kXMLNSNameSpaceURI,
NS_LITERAL_STRING("xmlns"));
}
// handle namespaces on the root element of the instance document
nsCOMPtr<nsIDOMElement> instDocElm;
instDoc->GetDocumentElement(getter_AddRefs(instDocElm));
nsCOMPtr<nsIDOMNode> instDocNode(do_QueryInterface(instDocElm));
NS_ENSURE_STATE(instDocNode);
rv = AddNameSpaces(submDocElm, instDocNode, prefixHash);
NS_ENSURE_SUCCESS(rv, rv);
// handle namespaces on the xforms:instance
rv = AddNameSpaces(submDocElm, instanceNode, prefixHash);
NS_ENSURE_SUCCESS(rv, rv);
// handle namespaces on the model
nsCOMPtr<nsIModelElementPrivate> model = GetModel();
nsCOMPtr<nsIDOMNode> modelNode(do_QueryInterface(model));
NS_ENSURE_STATE(modelNode);
rv = AddNameSpaces(submDocElm, modelNode, prefixHash);
NS_ENSURE_SUCCESS(rv, rv);
// handle namespace on main document
nsCOMPtr<nsIDOMDocument> mainDoc;
mElement->GetOwnerDocument(getter_AddRefs(mainDoc));
NS_ENSURE_STATE(mainDoc);
nsCOMPtr<nsIDOMElement> mainDocElm;
mainDoc->GetDocumentElement(getter_AddRefs(mainDocElm));
nsCOMPtr<nsIDOMNode> mainDocNode(do_QueryInterface(mainDocElm));
NS_ENSURE_STATE(mainDocNode);
rv = AddNameSpaces(submDocElm, mainDocNode, prefixHash);
NS_ENSURE_SUCCESS(rv, rv);
if (prefixHash)
delete prefixHash;
}
// Serialize content
rv = serializer->SerializeToStream(submDoc, sink,
nsAutoString encoding;
mElement->GetAttribute(NS_LITERAL_STRING("encoding"), encoding);
if (encoding.IsEmpty())
encoding.AssignLiteral("UTF-8");
// XXX: should check @indent and possibly indent content. Bug 278761
rv = serializer->SerializeToStream(data, sink,
NS_LossyConvertUTF16toASCII(encoding));
NS_ENSURE_SUCCESS(rv, rv);
@ -972,7 +861,8 @@ nsXFormsSubmissionElement::SerializeDataXML(nsIDOMNode *data,
}
PRBool
nsXFormsSubmissionElement::CheckSameOrigin(nsIDocument *aBaseDocument, nsIURI *aTestURI)
nsXFormsSubmissionElement::CheckSameOrigin(nsIDocument *aBaseDocument,
nsIURI *aTestURI)
{
// we default to true to allow regular posts to work like html forms.
PRBool allowSubmission = PR_TRUE;
@ -1056,9 +946,9 @@ nsXFormsSubmissionElement::CheckPermissionManager(nsIURI *aBaseURI)
}
nsresult
nsXFormsSubmissionElement::AddNameSpaces(nsIDOMElement* aTarget,
nsIDOMNode* aSource,
nsStringHashSet* aPrefixHash)
nsXFormsSubmissionElement::AddNameSpaces(nsIDOMElement *aTarget,
nsIDOMNode *aSource,
nsStringHashSet *aPrefixHash)
{
nsCOMPtr<nsIDOMNamedNodeMap> attrMap;
nsCOMPtr<nsIDOMNode> attrNode;
@ -1145,12 +1035,124 @@ nsXFormsSubmissionElement::GetIncludeNSPrefixesAttr(nsStringHashSet** aHash)
}
nsresult
nsXFormsSubmissionElement::CreateSubmissionDoc(nsIDOMNode *source,
const nsString &encoding,
SubmissionAttachmentArray *attachments,
nsIDOMDocument **result)
nsXFormsSubmissionElement::CreateSubmissionDoc(nsIDOMNode *aRoot,
nsIDOMDocument **aReturnDoc)
{
NS_ENSURE_ARG_POINTER(aRoot);
NS_ENSURE_ARG_POINTER(aReturnDoc);
nsCOMPtr<nsIDOMDocument> instDoc, submDoc;
aRoot->GetOwnerDocument(getter_AddRefs(instDoc));
nsresult rv;
if (!instDoc) {
// owner doc is null when the aRoot node is the document (e.g., ref="/")
// so we can just get the document via QI.
instDoc = do_QueryInterface(aRoot);
NS_ENSURE_STATE(instDoc);
rv = CreatePurgedDoc(instDoc, getter_AddRefs(submDoc));
} else {
rv = CreatePurgedDoc(aRoot, getter_AddRefs(submDoc));
}
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(submDoc);
// We now need to add namespaces to the submission document. We get them
// from 3 sources - the main document's documentElement, the model and the
// xforms:instance that contains the submitted instance data node.
nsCOMPtr<nsIDOMNode> instanceNode;
rv = nsXFormsUtils::GetInstanceNodeForData(aRoot,
getter_AddRefs(instanceNode));
NS_ENSURE_SUCCESS(rv, rv);
// add namespaces from the main document to the submission document, but only
// if the instance data is local, not remote.
PRBool serialize = PR_FALSE;
nsCOMPtr<nsIDOMElement> instanceElement(do_QueryInterface(instanceNode));
// make sure that this is a DOMElement. It won't be if it was lazy
// authored. Lazy authored instance documents don't inherit namespaces
// from parent nodes or the original document (in formsPlayer and Novell,
// at least).
if (instanceElement) {
PRBool hasSrc = PR_FALSE;
instanceElement->HasAttribute(NS_LITERAL_STRING("src"), &hasSrc);
serialize = !hasSrc;
}
if (serialize) {
// Handle "includenamespaceprefixes" attribute, if present
nsAutoPtr<nsStringHashSet> prefixHash;
PRBool hasPrefixAttr = PR_FALSE;
mElement->HasAttribute(kIncludeNamespacePrefixes, &hasPrefixAttr);
if (hasPrefixAttr) {
rv = GetIncludeNSPrefixesAttr(getter_Transfers(prefixHash));
NS_ENSURE_SUCCESS(rv, rv);
}
// get the document element of the document we are going to submit
nsCOMPtr<nsIDOMElement> submDocElm;
submDoc->GetDocumentElement(getter_AddRefs(submDocElm));
NS_ENSURE_STATE(submDocElm);
// if submission document has empty default namespace attribute and if
// @includenamespaceprefixes attribute doesn't contain "#default" value then
// we should remove default namespace attribute (see the specs 11.3).
nsAutoString XMLNSAttrValue;
submDocElm->GetAttributeNS(kXMLNSNameSpaceURI, NS_LITERAL_STRING("xmlns"),
XMLNSAttrValue);
if (XMLNSAttrValue.IsEmpty() && (!prefixHash ||
!prefixHash->Contains(NS_LITERAL_STRING("#default")))) {
submDocElm->RemoveAttributeNS(kXMLNSNameSpaceURI,
NS_LITERAL_STRING("xmlns"));
}
// handle namespaces on the root element of the instance document
nsCOMPtr<nsIDOMElement> instDocElm;
instDoc->GetDocumentElement(getter_AddRefs(instDocElm));
nsCOMPtr<nsIDOMNode> instDocNode(do_QueryInterface(instDocElm));
NS_ENSURE_STATE(instDocNode);
rv = AddNameSpaces(submDocElm, instDocNode, prefixHash);
NS_ENSURE_SUCCESS(rv, rv);
// handle namespaces on the xforms:instance
rv = AddNameSpaces(submDocElm, instanceNode, prefixHash);
NS_ENSURE_SUCCESS(rv, rv);
// handle namespaces on the model
nsCOMPtr<nsIModelElementPrivate> model = GetModel();
nsCOMPtr<nsIDOMNode> modelNode(do_QueryInterface(model));
NS_ENSURE_STATE(modelNode);
rv = AddNameSpaces(submDocElm, modelNode, prefixHash);
NS_ENSURE_SUCCESS(rv, rv);
// handle namespace on main document
nsCOMPtr<nsIDOMDocument> mainDoc;
mElement->GetOwnerDocument(getter_AddRefs(mainDoc));
NS_ENSURE_STATE(mainDoc);
nsCOMPtr<nsIDOMElement> mainDocElm;
mainDoc->GetDocumentElement(getter_AddRefs(mainDocElm));
nsCOMPtr<nsIDOMNode> mainDocNode(do_QueryInterface(mainDocElm));
NS_ENSURE_STATE(mainDocNode);
rv = AddNameSpaces(submDocElm, mainDocNode, prefixHash);
NS_ENSURE_SUCCESS(rv, rv);
}
NS_ADDREF(*aReturnDoc = submDoc);
return NS_OK;
}
nsresult
nsXFormsSubmissionElement::CreatePurgedDoc(nsIDOMNode *source,
nsIDOMDocument **result)
{
PRBool indent = GetBooleanAttr(NS_LITERAL_STRING("indent"), PR_FALSE);
PRBool omit_xml_declaration
= GetBooleanAttr(NS_LITERAL_STRING("omit-xml-declaration"), PR_FALSE);
@ -1183,11 +1185,16 @@ nsXFormsSubmissionElement::CreateSubmissionDoc(nsIDOMNode *source,
getter_AddRefs(doc));
NS_ENSURE_STATE(doc);
if (!omit_xml_declaration)
{
nsAutoString buf
= NS_LITERAL_STRING("version=\"1.0\" encoding=\"") + encoding
+ NS_LITERAL_STRING("\"");
if (!omit_xml_declaration) {
nsAutoString encoding;
mElement->GetAttribute(NS_LITERAL_STRING("encoding"), encoding);
if (encoding.IsEmpty())
encoding.AssignLiteral("UTF-8");
nsAutoString buf =
NS_LITERAL_STRING("version=\"1.0\" encoding=\"") +
encoding +
NS_LITERAL_STRING("\"");
nsCOMPtr<nsIDOMProcessingInstruction> pi;
doc->CreateProcessingInstruction(NS_LITERAL_STRING("xml"), buf,
@ -1210,8 +1217,7 @@ nsXFormsSubmissionElement::CreateSubmissionDoc(nsIDOMNode *source,
nsCOMPtr<nsIModelElementPrivate> model = GetModel();
NS_ENSURE_STATE(model);
nsresult rv = CopyChildren(model, startNode, doc, doc, attachments,
cdataElements, indent, 0);
nsresult rv = CopyChildren(model, startNode, doc, doc, cdataElements, 0);
NS_ENSURE_SUCCESS(rv, rv);
NS_ADDREF(*result = doc);
@ -1219,196 +1225,158 @@ nsXFormsSubmissionElement::CreateSubmissionDoc(nsIDOMNode *source,
}
nsresult
nsXFormsSubmissionElement::CopyChildren(nsIModelElementPrivate* model,
nsIDOMNode *source, nsIDOMNode *dest,
nsIDOMDocument *destDoc,
SubmissionAttachmentArray *attachments,
const nsString &cdataElements,
PRBool indent, PRUint32 depth)
nsXFormsSubmissionElement::CreateAttachments(nsIModelElementPrivate *aModel,
nsIDOMNode *aNode,
SubmissionAttachmentArray *aAttachments)
{
nsCOMPtr<nsIDOMNode> currentNode(source), node, destChild;
nsCOMPtr<nsIDOMNode> currentNode(aNode);
while (currentNode)
{
// if not indenting, then strip all unnecessary whitespace
while (currentNode) {
// If |currentNode| is an element node of type 'xsd:anyURI', we need to
// generate a ContentID for the child of this element, and append a new
// attachment to the attachments array.
PRUint32 encType;
nsresult rv;
if (NS_SUCCEEDED(GetElementEncodingType(currentNode, &encType, aModel)) &&
encType == ELEMENT_ENCTYPE_URI) {
// ok, looks like we have a local file to upload
nsCOMPtr<nsIContent> content = do_QueryInterface(currentNode);
NS_ENSURE_STATE(content);
nsIFile *file =
NS_STATIC_CAST(nsIFile *,
content->GetProperty(nsXFormsAtoms::uploadFileProperty));
// NOTE: this value may be null if a file hasn't been selected.
nsCString cid;
MakeMultipartContentID(cid);
nsAutoString cidURI;
cidURI.AssignLiteral("cid:");
AppendASCIItoUTF16(cid, cidURI);
aAttachments->Append(file, cid);
rv = currentNode->SetNodeValue(cidURI);
NS_ENSURE_SUCCESS(rv, rv);
}
nsCOMPtr<nsIDOMNode> child;
currentNode->GetFirstChild(getter_AddRefs(child));
if (child) {
rv = CreateAttachments(aModel, child, aAttachments);
NS_ENSURE_SUCCESS(rv, rv);
}
nsCOMPtr<nsIDOMNode> node;
currentNode->GetNextSibling(getter_AddRefs(node));
currentNode.swap(node);
}
return NS_OK;
}
nsresult
nsXFormsSubmissionElement::CopyChildren(nsIModelElementPrivate *aModel,
nsIDOMNode *aSource,
nsIDOMNode *aDest,
nsIDOMDocument *aDestDoc,
const nsString &aCDATAElements,
PRUint32 aDepth)
{
nsCOMPtr<nsIDOMNode> currentNode(aSource), node, destChild;
while (currentNode) {
// XXX importing the entire node is not quite right here... we also have
// to iterate over the attributes since the attributes could somehow
// (remains to be determined) reference external entities.
destDoc->ImportNode(currentNode, PR_FALSE, getter_AddRefs(destChild));
aDestDoc->ImportNode(currentNode, PR_FALSE, getter_AddRefs(destChild));
NS_ENSURE_STATE(destChild);
PRUint16 type;
destChild->GetNodeType(&type);
if (type == nsIDOMNode::PROCESSING_INSTRUCTION_NODE)
{
nsCOMPtr<nsIDOMProcessingInstruction> pi = do_QueryInterface(destChild);
NS_ENSURE_STATE(pi);
switch (type) {
case nsIDOMNode::PROCESSING_INSTRUCTION_NODE: {
nsCOMPtr<nsIDOMProcessingInstruction> pi = do_QueryInterface(destChild);
NS_ENSURE_STATE(pi);
// ignore "<?xml ... ?>" since we would have already inserted this.
// ignore "<?xml ... ?>" since we would have already inserted this.
// XXXbeaufour: depends on omit-xml-decl, does it not?
nsAutoString target;
pi->GetTarget(target);
if (!target.EqualsLiteral("xml"))
dest->AppendChild(destChild, getter_AddRefs(node));
}
else if (type == nsIDOMNode::TEXT_NODE)
{
// honor cdata-section-elements (see xslt spec section 16.1)
if (cdataElements.IsEmpty())
{
dest->AppendChild(destChild, getter_AddRefs(node));
nsAutoString target;
pi->GetTarget(target);
if (!target.EqualsLiteral("xml"))
aDest->AppendChild(destChild, getter_AddRefs(node));
break;
}
else
{
currentNode->GetParentNode(getter_AddRefs(node));
NS_ENSURE_STATE(node);
nsAutoString name;
node->GetNodeName(name);
// check to see if name is mentioned on cdataElements
if (HasToken(cdataElements, name))
{
nsCOMPtr<nsIDOMText> textNode = do_QueryInterface(destChild);
NS_ENSURE_STATE(textNode);
case nsIDOMNode::TEXT_NODE: {
// honor cdata-section-elements (see xslt spec section 16.1)
if (aCDATAElements.IsEmpty()) {
aDest->AppendChild(destChild, getter_AddRefs(node));
} else {
currentNode->GetParentNode(getter_AddRefs(node));
NS_ENSURE_STATE(node);
nsAutoString textData;
textNode->GetData(textData);
nsAutoString name;
node->GetNodeName(name);
// check to see if name is mentioned on cdataElements
if (HasToken(aCDATAElements, name)) {
nsCOMPtr<nsIDOMText> textNode = do_QueryInterface(destChild);
NS_ENSURE_STATE(textNode);
nsCOMPtr<nsIDOMCDATASection> cdataNode;
destDoc->CreateCDATASection(textData, getter_AddRefs(cdataNode));
nsAutoString textData;
textNode->GetData(textData);
dest->AppendChild(cdataNode, getter_AddRefs(node));
}
else
{
dest->AppendChild(destChild, getter_AddRefs(node));
nsCOMPtr<nsIDOMCDATASection> cdataNode;
aDestDoc->CreateCDATASection(textData, getter_AddRefs(cdataNode));
aDest->AppendChild(cdataNode, getter_AddRefs(node));
} else {
aDest->AppendChild(destChild, getter_AddRefs(node));
}
}
}
}
else
{
PRUint16 handleNodeResult;
model->HandleInstanceDataNode(currentNode, &handleNodeResult);
default: {
PRUint16 handleNodeResult;
aModel->HandleInstanceDataNode(currentNode, &handleNodeResult);
/*
* SUBMIT_SERIALIZE_NODE - node is to be serialized
* SUBMIT_SKIP_NODE - node is not to be serialized
* SUBMIT_ABORT_SUBMISSION - abort submission (invalid node or empty required node)
*/
if (handleNodeResult == nsIModelElementPrivate::SUBMIT_SKIP_NODE) {
// skip node and subtree
currentNode->GetNextSibling(getter_AddRefs(node));
currentNode.swap(node);
continue;
} else if (handleNodeResult == nsIModelElementPrivate::SUBMIT_ABORT_SUBMISSION) {
// abort
return NS_ERROR_ILLEGAL_VALUE;
}
/*
* SUBMIT_SERIALIZE_NODE - node is to be serialized
* SUBMIT_SKIP_NODE - node is not to be serialized
* SUBMIT_ABORT_SUBMISSION - abort submission (invalid node or empty required node)
*/
if (handleNodeResult == nsIModelElementPrivate::SUBMIT_SKIP_NODE) {
// skip node and subtree
currentNode->GetNextSibling(getter_AddRefs(node));
currentNode.swap(node);
continue;
} else if (handleNodeResult == nsIModelElementPrivate::SUBMIT_ABORT_SUBMISSION) {
// abort
nsXFormsUtils::ReportError(NS_LITERAL_STRING("warnSubmitInvalidNode"),
currentNode, nsIScriptError::warningFlag);
return NS_ERROR_ILLEGAL_VALUE;
}
// If |currentNode| is an element node of type 'xsd:anyURI', and if we
// have an attachments array, then we need to perform multipart/related
// processing (i.e., generate a ContentID for the child of this element,
// and append a new attachment to the attachments array).
PRUint32 encType;
if (attachments &&
NS_SUCCEEDED(GetElementEncodingType(currentNode, &encType, model)) &&
encType == ELEMENT_ENCTYPE_URI)
{
// ok, looks like we have a local file to upload
nsCOMPtr<nsIContent> content = do_QueryInterface(currentNode);
NS_ENSURE_STATE(content);
nsIFile *file =
NS_STATIC_CAST(nsIFile *,
content->GetProperty(nsXFormsAtoms::uploadFileProperty));
// NOTE: this value may be null if a file hasn't been selected.
nsCString cid;
MakeMultipartContentID(cid);
nsAutoString cidURI;
cidURI.AssignLiteral("cid:");
AppendASCIItoUTF16(cid, cidURI);
nsCOMPtr<nsIDOMText> text;
destDoc->CreateTextNode(cidURI, getter_AddRefs(text));
NS_ENSURE_STATE(text);
destChild->AppendChild(text, getter_AddRefs(node));
dest->AppendChild(destChild, getter_AddRefs(node));
attachments->Append(file, cid);
}
else
{
dest->AppendChild(destChild, getter_AddRefs(node));
aDest->AppendChild(destChild, getter_AddRefs(node));
// recurse
nsCOMPtr<nsIDOMNode> startNode;
currentNode->GetFirstChild(getter_AddRefs(startNode));
nsresult rv = CopyChildren(model, startNode, destChild, destDoc,
attachments, cdataElements, indent,
depth + 1);
nsresult rv = CopyChildren(aModel, startNode, destChild, aDestDoc,
aCDATAElements, aDepth + 1);
NS_ENSURE_SUCCESS(rv, rv);
}
}
if (!depth) {
break;
}
currentNode->GetNextSibling(getter_AddRefs(node));
currentNode.swap(node);
}
return NS_OK;
}
nsresult
nsXFormsSubmissionElement::CanSubmit(nsIDOMNode *aTopNode,
nsIModelElementPrivate *aModel,
PRBool aCheckSiblings)
{
nsCOMPtr<nsIDOMNode> currentNode(aTopNode), node;
while (currentNode) {
PRUint16 handleNodeResult;
aModel->HandleInstanceDataNode(currentNode, &handleNodeResult);
/*
* SUBMIT_SERIALIZE_NODE - node is to be serialized
* SUBMIT_SKIP_NODE - node is not to be serialized
* SUBMIT_ABORT_SUBMISSION - abort submission
* (invalid node or empty required node)
*/
if (handleNodeResult == nsIModelElementPrivate::SUBMIT_SKIP_NODE) {
// skip node and subtree
currentNode->GetNextSibling(getter_AddRefs(node));
currentNode.swap(node);
continue;
} else if (handleNodeResult ==
nsIModelElementPrivate::SUBMIT_ABORT_SUBMISSION) {
// abort
return NS_ERROR_ABORT;
}
NS_ASSERTION(
handleNodeResult == nsIModelElementPrivate::SUBMIT_SERIALIZE_NODE,
"unexpected node type");
// recurse
nsCOMPtr<nsIDOMNode> firstChild;
currentNode->GetFirstChild(getter_AddRefs(firstChild));
nsresult rv = CanSubmit(firstChild, aModel);
NS_ENSURE_SUCCESS(rv, rv);
if (!aCheckSiblings) {
if (!aDepth) {
break;
}
@ -1420,11 +1388,19 @@ nsXFormsSubmissionElement::CanSubmit(nsIDOMNode *aTopNode,
}
nsresult
nsXFormsSubmissionElement::SerializeDataURLEncoded(nsIDOMNode *data,
nsXFormsSubmissionElement::SerializeDataURLEncoded(nsIDOMDocument *data,
nsCString &uri,
nsIInputStream **stream,
nsCString &contentType)
{
// 'get' method:
// The URI is constructed as follows:
// o The submit URI from the action attribute is examined. If it does not
// already contain a ? (question mark) character, one is appended. If it
// does already contain a question mark character, then a separator
// character from the attribute separator is appended.
// o The serialized form data is appended to the URI.
nsCAutoString separator;
{
nsAutoString temp;
@ -1556,7 +1532,7 @@ nsXFormsSubmissionElement::AppendURLEncodedData(nsIDOMNode *data,
}
nsresult
nsXFormsSubmissionElement::SerializeDataMultipartRelated(nsIDOMNode *data,
nsXFormsSubmissionElement::SerializeDataMultipartRelated(nsIDOMDocument *data,
nsIInputStream **stream,
nsCString &contentType)
{
@ -1573,13 +1549,15 @@ nsXFormsSubmissionElement::SerializeDataMultipartRelated(nsIDOMNode *data,
MakeMultipartContentID(start);
// XXX we need to extend SerializeDataXML so that it has a mode in which it
// generates ContentIDs for elements of type xsd:anyURI, and returns a
// list of ContentID <-> URI mappings.
nsresult rv;
nsCOMPtr<nsIModelElementPrivate> model(GetModel());
NS_ENSURE_STATE(model);
SubmissionAttachmentArray attachments;
rv = CreateAttachments(model, data, &attachments);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIInputStream> xml;
SubmissionAttachmentArray attachments;
nsresult rv = SerializeDataXML(data, getter_AddRefs(xml), type, &attachments);
rv = SerializeDataXML(data, getter_AddRefs(xml), type);
NS_ENSURE_SUCCESS(rv, rv);
// XXX we should output a 'charset=' with the 'Content-Type' header
@ -1594,8 +1572,7 @@ nsXFormsSubmissionElement::SerializeDataMultipartRelated(nsIDOMNode *data,
multiStream->AppendStream(xml);
for (PRUint32 i=0; i<attachments.Count(); ++i)
{
for (PRUint32 i = 0; i < attachments.Count(); ++i) {
SubmissionAttachment *a = attachments.Item(i);
nsCOMPtr<nsIInputStream> fileStream;
@ -1644,7 +1621,7 @@ nsXFormsSubmissionElement::SerializeDataMultipartRelated(nsIDOMNode *data,
}
nsresult
nsXFormsSubmissionElement::SerializeDataMultipartFormData(nsIDOMNode *data,
nsXFormsSubmissionElement::SerializeDataMultipartFormData(nsIDOMDocument *data,
nsIInputStream **stream,
nsCString &contentType)
{

Просмотреть файл

@ -105,31 +105,28 @@ public:
NS_HIDDEN_(nsresult) GetSelectedInstanceElement(const nsAString &aInstance,
nsIModelElementPrivate *aModel,
nsIInstanceElementPrivate **result);
NS_HIDDEN_(nsresult) SerializeData(nsIDOMNode *data, nsCString &uri,
NS_HIDDEN_(nsresult) SerializeData(nsIDOMDocument *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);
NS_HIDDEN_(nsresult) SerializeDataXML(nsIDOMDocument *data, nsIInputStream **,
nsCString &contentType);
NS_HIDDEN_(nsresult) CreatePurgedDoc(nsIDOMNode *source,
nsIDOMDocument **result);
NS_HIDDEN_(nsresult) CopyChildren(nsIModelElementPrivate* model,
nsIDOMNode *source, nsIDOMNode *dest,
nsIDOMDocument *destDoc,
SubmissionAttachmentArray *,
const nsString &cdataElements,
PRBool indent, PRUint32 depth);
NS_HIDDEN_(nsresult) SerializeDataURLEncoded(nsIDOMNode *data, nsCString &uri,
PRUint32 depth);
NS_HIDDEN_(nsresult) SerializeDataURLEncoded(nsIDOMDocument *data,
nsCString &uri,
nsIInputStream **,
nsCString &contentType);
NS_HIDDEN_(void) AppendURLEncodedData(nsIDOMNode *data,
const nsCString &sep,
nsCString &buf);
NS_HIDDEN_(nsresult) SerializeDataMultipartRelated(nsIDOMNode *data,
NS_HIDDEN_(nsresult) SerializeDataMultipartRelated(nsIDOMDocument *data,
nsIInputStream **,
nsCString &contentType);
NS_HIDDEN_(nsresult) SerializeDataMultipartFormData(nsIDOMNode *data,
NS_HIDDEN_(nsresult) SerializeDataMultipartFormData(nsIDOMDocument *data,
nsIInputStream **,
nsCString &contentType);
NS_HIDDEN_(nsresult) AppendMultipartFormData(nsIDOMNode *data,
@ -169,21 +166,6 @@ private:
nsStringHashSet* aPrefixHash);
nsresult GetIncludeNSPrefixesAttr(nsStringHashSet** aHash);
/**
* This walks the DOM tree, starting at aTopNode and invokes
* model->HandleInstanceDataNode()that ensures that the instance is valid,
* required conditions met...if so, then can submit.
*
* @param aTopNode Root instance node of tree to be evaluated
* @param aModel The model for the submission
* @param aCheckSiblings Check siblings too?
* @return NS_ERROR_ABORT if instance is not valid and empty
* required nodes, otherwise return NS_OK.
*
*/
nsresult CanSubmit(nsIDOMNode *aTopNode, nsIModelElementPrivate *aModel,
PRBool aCheckSiblings = PR_TRUE);
/**
* Send xforms-submit-done/-error, depending on |aSucceeded|
*
@ -191,6 +173,30 @@ private:
*
*/
void EndSubmit(PRBool aSucceeded);
/**
* Create submission document.
*
* This creates a new document, include namespaces, purges non-relevant
* nodes, and checks simple type validity. If a check fails, no document
* will be returned.
*
* @param aRoot The source node
* @param aReturnDoc The resulting document
*/
nsresult CreateSubmissionDoc(nsIDOMNode *aRoot,
nsIDOMDocument** aReturnDoc);
/**
* Run through document and create attachment ids for xsd:anyURI nodes. This
* is used for "multipart/related".
*
* @param aModel The model to use
* @param aDoc The document to run through
* @param aAttachments Array of files and attachment ids
*/
nsresult CreateAttachments(nsIModelElementPrivate *aModel, nsIDOMNode *aDoc,
SubmissionAttachmentArray *aAttachments);
};
NS_HIDDEN_(nsresult)

Просмотреть файл

@ -76,9 +76,13 @@ inlineInstanceNoChildError = XForms Error (37): Inline instance has no child ele
inlineInstanceMultipleElementsError = XForms Error (38): Inline instance has multiple child elements. This is illegal.
# 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.
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.
warnSubmitAlreadyRunning = XForms Warning (4): Submission is already running.
warnSubmitInvalidNode = XForms Warning (5): Submission validation failed for node
warnSubmitSerializeFailed = XForms Warning (6): Submission failed to serialize data
warnSubmitNetworkFailure = XForms Warning (7): Submission could not send data to the network
# XForms Permission Messages:
xformsXDPermissionDialogTitle = Allowed Sites - XForms Cross Domain Access