Store instance node schema type as property instead of attribute. Bug 283004, r=smaug+aaronr, a=mkaply

This commit is contained in:
allan%beaufour.dk 2005-06-07 07:03:09 +00:00
Родитель 33e3547c8a
Коммит efb7e287b9
2 изменённых файлов: 61 добавлений и 75 удалений

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

@ -69,6 +69,7 @@
#include "nsIInstanceElementPrivate.h"
#include "nsXFormsUtils.h"
#include "nsXFormsSchemaValidator.h"
#include "nsIAttribute.h"
#include "nsISchemaLoader.h"
#include "nsISchema.h"
@ -1277,6 +1278,15 @@ nsXFormsModelElement::MaybeNotifyCompletion()
nsXFormsModelElement::ProcessDeferredBinds(domDoc);
}
static void
DeleteAutoString(void *aObject,
nsIAtom *aPropertyName,
void *aPropertyValue,
void *aData)
{
delete NS_STATIC_CAST(nsAutoString*, aPropertyValue);
}
nsresult
nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
nsIDOMNode *aContextNode,
@ -1361,48 +1371,34 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
if (propStrings[j].IsEmpty())
continue;
// type and p3ptype are applied as attributes on the instance node
// type and p3ptype are stored as properties on the instance node
if (j == eModel_type || j == eModel_p3ptype) {
nsCOMPtr<nsIDOMElement> nodeElem = do_QueryInterface(node, &rv);
if (NS_FAILED(rv)) {
NS_WARNING("nsXFormsModelElement::ProcessBind(): Node is not nsIDOMElement!\n");
continue;
}
// Check whether attribute already exists
if (j == eModel_type) {
rv = nodeElem->HasAttributeNS(NS_LITERAL_STRING(NS_NAMESPACE_XML_SCHEMA_INSTANCE),
NS_LITERAL_STRING("type"),
&multiMIP);
nsAutoPtr<nsAutoString> prop (new nsAutoString(propStrings[j]));
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
if (content) {
rv = content->SetProperty(sModelPropsList[j],
prop,
DeleteAutoString);
} else {
rv = nodeElem->HasAttributeNS(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS),
NS_LITERAL_STRING("p3ptype"),
&multiMIP);
nsCOMPtr<nsIAttribute> attribute = do_QueryInterface(node);
if (attribute) {
rv = attribute->SetProperty(sModelPropsList[j],
prop,
DeleteAutoString);
} else {
NS_WARNING("node is neither nsIContent or nsIAttribute");
continue;
}
}
NS_ENSURE_SUCCESS(rv, rv);
// It is an error to set a MIP twice, so break and emit an exception.
if (multiMIP) {
if (NS_SUCCEEDED(rv)) {
prop.forget();
} else {
return rv;
}
if (rv == NS_PROPTABLE_PROP_OVERWRITTEN) {
multiMIP = PR_TRUE;
break;
}
// Set attribute
if (j == eModel_type) {
rv = nodeElem->SetAttributeNS(NS_LITERAL_STRING(NS_NAMESPACE_XML_SCHEMA_INSTANCE),
NS_LITERAL_STRING("type"),
propStrings[j]);
NS_ENSURE_SUCCESS(rv, rv);
// Inform MDG that it needs to check type. The only arguments
// actually used are |eModel_constraint| and |node|.
rv = mMDG.AddMIP(eModel_constraint, nsnull, nsnull, PR_FALSE, node, 1, 1);
} else {
rv = nodeElem->SetAttributeNS(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS),
NS_LITERAL_STRING("p3ptype"),
propStrings[j]);
}
NS_ENSURE_SUCCESS(rv, rv);
} else {
// the rest of the MIPs are given to the MDG
nsCOMPtr<nsIDOMNSXPathExpression> expr = props[j];

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

@ -58,6 +58,8 @@
#include "nsIDOMNSDocument.h"
#include "nsIDOMLocation.h"
#include "nsIDOMSerializer.h"
#include "nsIContent.h"
#include "nsIAttribute.h"
#include "nsIXFormsContextControl.h"
#include "nsIDOMDocumentEvent.h"
@ -1147,63 +1149,51 @@ nsXFormsUtils::GetInstanceNodeForData(nsIDOMNode *aInstanceDataNode,
nsXFormsUtils::ParseTypeFromNode(nsIDOMNode *aInstanceData,
nsAString &aType, nsAString &aNSPrefix)
{
nsresult rv;
nsresult rv = NS_OK;
// aInstanceData could be an instance data node or it could be an attribute
// on an instance data node (basically the node that a control is bound to).
// So first checking to see if it is a proper element node. If it isn't,
// making sure that it is at least an attribute.
//
// XXX - Once node type is set as a property on the element or attribute node,
// then we can treat elements and attributes the same. For now we are using
// an attribute on the instance data node to store the type. If we bind
// to an attribute on the instance data node there is nothing we can do but
// hope that it doesn't have a bound type until we get properties on
// attributes working. (bug 283004)
nsCOMPtr<nsIDOMElement> nodeElem = do_QueryInterface(aInstanceData, &rv);
if (NS_FAILED(rv)) {
nsCOMPtr<nsIDOMAttr> attrNode = do_QueryInterface(aInstanceData, &rv);
if(NS_SUCCEEDED(rv)){
// right now we can't handle having a 'type' property on attribute nodes.
// For now we'll treat this condition as not having a 'type' property
// on the given node at all. This will allow a lot of testcases to still
// work ok as the caller will usually assign a default type of
// 'xsd:string' when we return NS_ERROR_NOT_AVAILABLE here.
return NS_ERROR_NOT_AVAILABLE;
} else {
// can't have a 'type' property on anything other than an element or an
// attribute. Return failure
/// @bug We need to check for any type attributes set directly on the node
/// too (XXX)
nsAutoString *typeVal = nsnull;
nsCOMPtr<nsIContent> nodeContent(do_QueryInterface(aInstanceData));
if (nodeContent) {
typeVal =
NS_STATIC_CAST(nsAutoString*,
nodeContent->GetProperty(nsXFormsAtoms::type, &rv));
} else {
nsCOMPtr<nsIAttribute> nodeAttribute(do_QueryInterface(aInstanceData));
if (!nodeAttribute)
// node is neither content or attribute!
return NS_ERROR_FAILURE;
}
typeVal =
NS_STATIC_CAST(nsAutoString*,
nodeAttribute->GetProperty(nsXFormsAtoms::type, &rv));
}
// right now type is stored as an attribute on the instance node. In the
// future it will be a property.
PRBool typeExists = PR_FALSE;
NS_NAMED_LITERAL_STRING(schemaInstanceURI, NS_NAMESPACE_XML_SCHEMA_INSTANCE);
NS_NAMED_LITERAL_STRING(type, "type");
nodeElem->HasAttributeNS(schemaInstanceURI, type, &typeExists);
if (!typeExists) {
if (NS_FAILED(rv) || !typeVal) {
return NS_ERROR_NOT_AVAILABLE;
}
nsAutoString typeAttribute;
nodeElem->GetAttributeNS(schemaInstanceURI, type, typeAttribute);
// split type (ns:type) into namespace and type.
PRInt32 separator = typeAttribute.FindChar(':');
if ((PRUint32) separator == (typeAttribute.Length() - 1)) {
const PRUnichar *strings[] = { typeAttribute.get() };
PRInt32 separator = typeVal->FindChar(':');
if ((PRUint32) separator == (typeVal->Length() - 1)) {
const PRUnichar *strings[] = { typeVal->get() };
// XXX: get an element from the document this came from
ReportError(NS_LITERAL_STRING("missingTypeName"), strings, 1, nsnull, nsnull);
return NS_ERROR_UNEXPECTED;
} else if (separator == kNotFound) {
// no namespace prefix, which is valid;
aNSPrefix.AssignLiteral("");
aType.Assign(typeAttribute);
aType.Assign(*typeVal);
} else {
aNSPrefix.Assign(Substring(typeAttribute, 0, separator));
aType.Assign(Substring(typeAttribute, ++separator, typeAttribute.Length()));
aNSPrefix.Assign(Substring(*typeVal, 0, separator));
aType.Assign(Substring(*typeVal, ++separator, typeVal->Length()));
}
return NS_OK;