зеркало из https://github.com/mozilla/gecko-dev.git
Store instance node schema type as property instead of attribute. Bug 283004, r=smaug+aaronr, a=mkaply
This commit is contained in:
Родитель
31a4443835
Коммит
c0078f2887
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче