[XForms] Fix namespace issues with submission. Bug 329479, r=doronr+me, patch by surkov@dc.baikal.ru

This commit is contained in:
allan%beaufour.dk 2006-03-23 09:07:21 +00:00
Родитель bd1aafafb3
Коммит 1a26d72755
1 изменённых файлов: 87 добавлений и 63 удалений

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

@ -639,7 +639,7 @@ nsXFormsSubmissionElement::Submit()
// serialization)
// This is handled by the SerializeData() method
// 4. serialize instance data
// Checking the format only before starting the submission.
mFormat = GetSubmissionFormat(mElement);
@ -845,48 +845,34 @@ nsXFormsSubmissionElement::SerializeDataXML(nsIDOMNode *data,
nsCOMPtr<nsIDOMSerializer> serializer =
do_GetService("@mozilla.org/xmlextras/xmlserializer;1");
NS_ENSURE_TRUE(serializer, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(serializer);
nsCOMPtr<nsIDOMDocument> doc, newDoc;
data->GetOwnerDocument(getter_AddRefs(doc));
nsCOMPtr<nsIDOMDocument> instDoc, submDoc;
data->GetOwnerDocument(getter_AddRefs(instDoc));
// XXX: We can't simply pass in data if !doc, since it crashes
if (!doc) {
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.
doc = do_QueryInterface(data);
NS_ENSURE_TRUE(doc, NS_ERROR_UNEXPECTED);
instDoc = do_QueryInterface(data);
NS_ENSURE_STATE(instDoc);
rv = CreateSubmissionDoc(doc, encoding, attachments,
getter_AddRefs(newDoc));
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(newDoc));
getter_AddRefs(submDoc));
}
// clone and possibly modify the document for submission
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(newDoc, NS_ERROR_UNEXPECTED);
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.
// first handle the main document
nsCOMPtr<nsIDOMDocument> mainDoc;
mElement->GetOwnerDocument(getter_AddRefs(mainDoc));
NS_ENSURE_TRUE(mainDoc, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsIDOMElement> docElm;
mainDoc->GetDocumentElement(getter_AddRefs(docElm));
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(docElm));
NS_ENSURE_TRUE(node, NS_ERROR_UNEXPECTED);
// get the document element of the document we are going to submit
nsCOMPtr<nsIDOMElement> newDocElm;
newDoc->GetDocumentElement(getter_AddRefs(newDocElm));
nsCOMPtr<nsIDOMNode> instanceNode;
rv = nsXFormsUtils::GetInstanceNodeForData(data, getter_AddRefs(instanceNode));
NS_ENSURE_SUCCESS(rv, rv);
@ -916,24 +902,54 @@ nsXFormsSubmissionElement::SerializeDataXML(nsIDOMNode *data,
NS_ENSURE_SUCCESS(rv, rv);
}
// handle namespace on main document
rv = AddNameSpaces(newDocElm, node, prefixHash);
// 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();
node = do_QueryInterface(model);
NS_ENSURE_STATE(node);
rv = AddNameSpaces(newDocElm, node, prefixHash);
nsCOMPtr<nsIDOMNode> modelNode(do_QueryInterface(model));
NS_ENSURE_STATE(modelNode);
rv = AddNameSpaces(submDocElm, modelNode, prefixHash);
NS_ENSURE_SUCCESS(rv, rv);
// handle namespaces on the xforms:instance
rv = AddNameSpaces(newDocElm, instanceNode, prefixHash);
NS_ENSURE_SUCCESS(rv, rv);
// handle namespace on main document
nsCOMPtr<nsIDOMDocument> mainDoc;
mElement->GetOwnerDocument(getter_AddRefs(mainDoc));
NS_ENSURE_STATE(mainDoc);
// handle namespaces on the root element of the instance document
doc->GetDocumentElement(getter_AddRefs(docElm));
rv = AddNameSpaces(newDocElm, docElm, prefixHash);
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)
@ -941,7 +957,7 @@ nsXFormsSubmissionElement::SerializeDataXML(nsIDOMNode *data,
}
// Serialize content
rv = serializer->SerializeToStream(newDoc, sink,
rv = serializer->SerializeToStream(submDoc, sink,
NS_LossyConvertUTF16toASCII(encoding));
NS_ENSURE_SUCCESS(rv, rv);
@ -1043,10 +1059,10 @@ nsXFormsSubmissionElement::AddNameSpaces(nsIDOMElement* aTarget,
{
nsCOMPtr<nsIDOMNamedNodeMap> attrMap;
nsCOMPtr<nsIDOMNode> attrNode;
nsAutoString nsURI, localName, value, attrName;
nsAutoString nsURI, localName, value;
aSource->GetAttributes(getter_AddRefs(attrMap));
NS_ENSURE_TRUE(attrMap, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(attrMap);
PRUint32 length;
attrMap->GetLength(&length);
@ -1059,18 +1075,26 @@ nsXFormsSubmissionElement::AddNameSpaces(nsIDOMElement* aTarget,
attrNode->GetLocalName(localName);
attrNode->GetNodeValue(value);
attrName.AssignLiteral("xmlns");
// xmlns:foo, not xmlns=
if (!localName.EqualsLiteral("xmlns")) {
// If "includenamespaceprefixes" attribute is present, don't add
// namespace unless it appears in hash
if (aPrefixHash && !aPrefixHash->Contains(localName))
continue;
attrName.AppendLiteral(":");
attrName.Append(localName);
}
if (!aPrefixHash || aPrefixHash->Contains(localName)) {
nsAutoString attrName(NS_LITERAL_STRING("xmlns:"));
attrName.Append(localName);
aTarget->SetAttributeNS(kXMLNSNameSpaceURI, attrName, value);
}
} else if (!value.IsEmpty()) {
PRBool hasDefaultNSAttr;
aTarget->HasAttributeNS(kXMLNSNameSpaceURI,
NS_LITERAL_STRING("xmlns"), &hasDefaultNSAttr);
aTarget->SetAttribute(attrName, value);
if (!hasDefaultNSAttr) {
aTarget->GetNamespaceURI(nsURI);
if (!nsURI.IsEmpty()) {
// if aTarget default namespace uri isn't empty and it hasn't
// default namespace attribute then we should add it.
aTarget->SetAttributeNS(kXMLNSNameSpaceURI, localName, value);
}
}
}
}
}
@ -1149,12 +1173,12 @@ nsXFormsSubmissionElement::CreateSubmissionDoc(nsIDOMNode *source,
source->GetOwnerDocument(getter_AddRefs(tmpDoc));
tmpDoc->GetImplementation(getter_AddRefs(impl));
}
NS_ENSURE_TRUE(impl, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(impl);
nsCOMPtr<nsIDOMDocument> doc;
impl->CreateDocument(EmptyString(), EmptyString(), nsnull,
getter_AddRefs(doc));
NS_ENSURE_TRUE(doc, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(doc);
if (!omit_xml_declaration)
{
@ -1208,14 +1232,14 @@ nsXFormsSubmissionElement::CopyChildren(nsIDOMNode *source, nsIDOMNode *dest,
// (remains to be determined) reference external entities.
destDoc->ImportNode(currentNode, PR_FALSE, getter_AddRefs(destChild));
NS_ENSURE_TRUE(destChild, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(destChild);
PRUint16 type;
destChild->GetNodeType(&type);
if (type == nsIDOMNode::PROCESSING_INSTRUCTION_NODE)
{
nsCOMPtr<nsIDOMProcessingInstruction> pi = do_QueryInterface(destChild);
NS_ENSURE_TRUE(pi, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(pi);
// ignore "<?xml ... ?>" since we would have already inserted this.
@ -1308,7 +1332,7 @@ nsXFormsSubmissionElement::CopyChildren(nsIDOMNode *source, nsIDOMNode *dest,
nsCOMPtr<nsIDOMText> text;
destDoc->CreateTextNode(cidURI, getter_AddRefs(text));
NS_ENSURE_TRUE(text, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(text);
destChild->AppendChild(text, getter_AddRefs(node));
dest->AppendChild(destChild, getter_AddRefs(node));
@ -1430,7 +1454,7 @@ nsXFormsSubmissionElement::SerializeDataURLEncoded(nsIDOMNode *data,
// make new stream
NS_NewCStringInputStream(stream, buf);
NS_ENSURE_TRUE(*stream, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(*stream);
contentType.AssignLiteral("application/x-www-form-urlencoded");
}
@ -1530,7 +1554,7 @@ nsXFormsSubmissionElement::SerializeDataMultipartRelated(nsIDOMNode *data,
nsCOMPtr<nsIMultiplexInputStream> multiStream =
do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
NS_ENSURE_TRUE(multiStream, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(multiStream);
nsCAutoString type, start;
@ -1635,7 +1659,7 @@ nsXFormsSubmissionElement::SerializeDataMultipartFormData(nsIDOMNode *data,
nsCOMPtr<nsIMultiplexInputStream> multiStream =
do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
NS_ENSURE_TRUE(multiStream, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(multiStream);
nsCString postDataChunk;
nsresult rv = AppendMultipartFormData(data, boundary, postDataChunk, multiStream);
@ -1805,7 +1829,7 @@ nsXFormsSubmissionElement::GetElementEncodingType(nsIDOMNode *node,
*encType = ELEMENT_ENCTYPE_STRING; // default
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(node);
NS_ENSURE_TRUE(element, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(element);
// check for 'xsd:base64Binary', 'xsd:hexBinary', or 'xsd:anyURI'
nsAutoString type, nsuri;
@ -1842,20 +1866,20 @@ nsXFormsSubmissionElement::CreateFileStream(const nsString &absURI,
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), absURI);
NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(uri);
// restrict to file:// -- XXX is this correct?
PRBool schemeIsFile = PR_FALSE;
uri->SchemeIs("file", &schemeIsFile);
NS_ENSURE_TRUE(schemeIsFile, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(schemeIsFile);
// NOTE: QI to nsIFileURL just means that the URL corresponds to a
// local file resource, which is not restricted to file://
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(uri);
NS_ENSURE_TRUE(fileURL, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(fileURL);
fileURL->GetFile(resultFile);
NS_ENSURE_TRUE(*resultFile, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(*resultFile);
return NS_NewLocalFileInputStream(resultStream, *resultFile);
}
@ -1989,7 +2013,7 @@ nsXFormsSubmissionElement::SendData(const nsCString &uriSpec,
if (stream)
{
NS_NewBufferedInputStream(getter_AddRefs(bufferedStream), stream, 4096);
NS_ENSURE_TRUE(bufferedStream, NS_ERROR_UNEXPECTED);
NS_ENSURE_STATE(bufferedStream);
}
nsCOMPtr<nsIChannel> channel;