mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 20:05:49 +00:00
[XForms] Make binds static. Bug 307421, r=aaronr+smaug
This commit is contained in:
parent
426f83aecc
commit
32a42eb82c
@ -49,7 +49,7 @@ interface nsIDOMElement;
|
||||
/**
|
||||
* Interface implemented by all XForms form control classes.
|
||||
*/
|
||||
[uuid(8377c845-5d55-4eee-9a76-0f86751dcbc8)]
|
||||
[uuid(1bea8750-2133-4a00-986a-04e5cbd129b2)]
|
||||
interface nsIXFormsControl : nsIXFormsContextControl
|
||||
{
|
||||
/**
|
||||
@ -86,4 +86,10 @@ interface nsIXFormsControl : nsIXFormsContextControl
|
||||
* need to override IsEventTarget() and return PR_FALSE
|
||||
*/
|
||||
boolean isEventTarget();
|
||||
|
||||
/**
|
||||
* Is true when the control is getting its instance data node binding from a
|
||||
* model bind element, ie. it has a |bind| attribute.
|
||||
*/
|
||||
readonly attribute boolean usesModelBinding;
|
||||
};
|
||||
|
@ -146,6 +146,7 @@ nsXFormsControlStubBase::ResetBoundNode(const nsString &aBindAttribute,
|
||||
{
|
||||
// Clear existing bound node, etc.
|
||||
mBoundNode = nsnull;
|
||||
mUsesModelBinding = PR_FALSE;
|
||||
mDependencies.Clear();
|
||||
RemoveIndexListeners();
|
||||
|
||||
@ -166,8 +167,13 @@ nsXFormsControlStubBase::ResetBoundNode(const nsString &aBindAttribute,
|
||||
if (!result)
|
||||
return NS_OK;
|
||||
|
||||
// Get context node, if any
|
||||
result->GetSingleNodeValue(getter_AddRefs(mBoundNode));
|
||||
// Get context node, if any
|
||||
if (mUsesModelBinding) {
|
||||
// When bound via @bind, we'll get a snapshot back
|
||||
result->SnapshotItem(0, getter_AddRefs(mBoundNode));
|
||||
} else {
|
||||
result->GetSingleNodeValue(getter_AddRefs(mBoundNode));
|
||||
}
|
||||
|
||||
if (mBoundNode && mModel) {
|
||||
mModel->SetStates(this, mBoundNode);
|
||||
@ -212,7 +218,13 @@ nsXFormsControlStubBase::IsEventTarget(PRBool *aOK)
|
||||
*aOK = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsControlStubBase::GetUsesModelBinding(PRBool *aRes)
|
||||
{
|
||||
*aRes = mUsesModelBinding;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXFormsControlStubBase::ProcessNodeBinding(const nsString &aBindingAttr,
|
||||
@ -237,6 +249,7 @@ nsXFormsControlStubBase::ProcessNodeBinding(const nsString &aBindingAtt
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
PRBool usesModelBinding;
|
||||
rv = nsXFormsUtils::EvaluateNodeBinding(mElement,
|
||||
kElementFlags,
|
||||
aBindingAttr,
|
||||
@ -244,6 +257,7 @@ nsXFormsControlStubBase::ProcessNodeBinding(const nsString &aBindingAtt
|
||||
aResultType,
|
||||
getter_AddRefs(mModel),
|
||||
aResult,
|
||||
&usesModelBinding,
|
||||
&mDependencies,
|
||||
&indexesUsed);
|
||||
NS_ENSURE_STATE(mModel);
|
||||
@ -251,10 +265,11 @@ nsXFormsControlStubBase::ProcessNodeBinding(const nsString &aBindingAtt
|
||||
mModel->AddFormControl(this);
|
||||
if (aModel)
|
||||
NS_ADDREF(*aModel = mModel);
|
||||
mUsesModelBinding = usesModelBinding;
|
||||
|
||||
if (NS_SUCCEEDED(rv) && indexesUsed.Count()) {
|
||||
// add index listeners on repeat elements
|
||||
|
||||
|
||||
for (PRInt32 i = 0; i < indexesUsed.Count(); ++i) {
|
||||
// Find the repeat element and add |this| as a listener
|
||||
nsCOMPtr<nsIDOMElement> repElem;
|
||||
@ -471,6 +486,7 @@ nsXFormsControlStubBase::OnDestroyed()
|
||||
{
|
||||
ResetHelpAndHint(PR_FALSE);
|
||||
RemoveIndexListeners();
|
||||
mDependencies.Clear();
|
||||
|
||||
if (mModel) {
|
||||
mModel->RemoveFormControl(this);
|
||||
|
@ -89,6 +89,7 @@ public:
|
||||
NS_IMETHOD Bind();
|
||||
NS_IMETHOD TryFocus(PRBool* aOK);
|
||||
NS_IMETHOD IsEventTarget(PRBool *aOK);
|
||||
NS_IMETHOD GetUsesModelBinding(PRBool *aRes);
|
||||
|
||||
nsresult Create(nsIXTFElementWrapper *aWrapper);
|
||||
// for nsIXTFElement
|
||||
@ -140,6 +141,7 @@ public:
|
||||
kElementFlags(nsXFormsUtils::ELEMENT_WITH_MODEL_ATTR),
|
||||
mHasParent(PR_FALSE),
|
||||
mPreventLoop(PR_FALSE),
|
||||
mUsesModelBinding(PR_FALSE),
|
||||
mBindAttrsCount(0)
|
||||
{};
|
||||
|
||||
@ -160,12 +162,17 @@ protected:
|
||||
nsCOMPtr<nsIDOMEventListener> mEventListener;
|
||||
|
||||
/** State that tells whether control has a parent or not */
|
||||
PRBool mHasParent;
|
||||
PRPackedBool mHasParent;
|
||||
|
||||
/** State to prevent infinite loop when generating and handling xforms-next
|
||||
* and xforms-previous events
|
||||
*/
|
||||
PRBool mPreventLoop;
|
||||
PRPackedBool mPreventLoop;
|
||||
|
||||
/**
|
||||
* Does the control use a model bind? That is, does it have a @bind.
|
||||
*/
|
||||
PRPackedBool mUsesModelBinding;
|
||||
|
||||
/**
|
||||
* Array of repeat-elements of which the control uses repeat-index.
|
||||
|
@ -157,24 +157,15 @@ nsXFormsCopyElement::GetCopyNode(nsIDOMNode **aNode)
|
||||
NS_ENSURE_ARG_POINTER(aNode);
|
||||
*aNode = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> singleNode;
|
||||
nsCOMPtr<nsIModelElementPrivate> model;
|
||||
nsCOMPtr<nsIDOMXPathResult> result;
|
||||
nsresult rv =
|
||||
nsXFormsUtils::EvaluateNodeBinding(mElement,
|
||||
nsXFormsUtils::ELEMENT_WITH_MODEL_ATTR,
|
||||
NS_LITERAL_STRING("ref"), EmptyString(),
|
||||
nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE,
|
||||
getter_AddRefs(model),
|
||||
getter_AddRefs(result));
|
||||
PRBool succeeded =
|
||||
nsXFormsUtils::GetSingleNodeBinding(mElement,
|
||||
getter_AddRefs(singleNode),
|
||||
getter_AddRefs(model));
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (result) {
|
||||
nsCOMPtr<nsIDOMNode> singleNode;
|
||||
result->GetSingleNodeValue(getter_AddRefs(singleNode));
|
||||
|
||||
NS_IF_ADDREF(*aNode = singleNode);
|
||||
}
|
||||
if (succeeded && singleNode)
|
||||
NS_ADDREF(*aNode = singleNode);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -97,13 +97,15 @@ nsXFormsInsertDeleteElement::HandleAction(nsIDOMEvent *aEvent,
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIModelElementPrivate> model;
|
||||
nsCOMPtr<nsIDOMXPathResult> nodeset;
|
||||
PRBool usesModelBinding;
|
||||
rv = nsXFormsUtils::EvaluateNodeBinding(mElement,
|
||||
nsXFormsUtils::ELEMENT_WITH_MODEL_ATTR,
|
||||
NS_LITERAL_STRING("nodeset"),
|
||||
EmptyString(),
|
||||
nsIDOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE,
|
||||
getter_AddRefs(model),
|
||||
getter_AddRefs(nodeset));
|
||||
getter_AddRefs(nodeset),
|
||||
&usesModelBinding);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!model || !nodeset)
|
||||
|
@ -169,6 +169,14 @@ GetModelList(nsIDOMDocument *domDoc)
|
||||
doc->GetProperty(nsXFormsAtoms::modelListProperty));
|
||||
}
|
||||
|
||||
static void
|
||||
SupportsDtorFunc(void *aObject, nsIAtom *aPropertyName,
|
||||
void *aPropertyValue, void *aData)
|
||||
{
|
||||
nsISupports *propertyValue = NS_STATIC_CAST(nsISupports*, aPropertyValue);
|
||||
NS_IF_RELEASE(propertyValue);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static const nsIID sScriptingIIDs[] = {
|
||||
@ -650,7 +658,11 @@ nsXFormsModelElement::Rebuild()
|
||||
mNodeToType.Clear();
|
||||
mNodeToP3PType.Clear();
|
||||
|
||||
// 2. Re-attach all elements
|
||||
// 2. Process bind elements
|
||||
rv = ProcessBindElements();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// 3. Re-attach all elements
|
||||
if (mDocumentLoaded) { // if it's not during initializing phase
|
||||
// Copy the form control list as it stands right now.
|
||||
nsVoidArray *oldFormList = new nsVoidArray();
|
||||
@ -685,10 +697,7 @@ nsXFormsModelElement::Rebuild()
|
||||
mNeedsRefresh = PR_TRUE;
|
||||
}
|
||||
|
||||
// 3. Rebuild graph
|
||||
rv = ProcessBindElements();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// 4. Rebuild graph
|
||||
return mMDG.Rebuild();
|
||||
}
|
||||
|
||||
@ -823,12 +832,22 @@ nsXFormsModelElement::Refresh()
|
||||
if (mNeedsRefresh) {
|
||||
refresh = PR_TRUE;
|
||||
} else {
|
||||
// Get dependencies
|
||||
nsCOMArray<nsIDOMNode> *deps = nsnull;
|
||||
control->GetDependencies(&deps);
|
||||
PRBool usesModelBinding = PR_FALSE;
|
||||
control->GetUsesModelBinding(&usesModelBinding);
|
||||
|
||||
#ifdef DEBUG_MODEL
|
||||
nsCOMArray<nsIDOMNode> *deps = nsnull;
|
||||
if (usesModelBinding) {
|
||||
if (!boundNode)
|
||||
// If a control uses a model binding, but has no bound node a
|
||||
// rebuild is the only thing that'll (eventually) change it
|
||||
continue;
|
||||
} else {
|
||||
// Get dependencies
|
||||
control->GetDependencies(&deps);
|
||||
}
|
||||
PRUint32 depCount = deps ? deps->Count() : 0;
|
||||
|
||||
#ifdef DEBUG_MODEL
|
||||
nsCOMPtr<nsIDOMElement> controlElement;
|
||||
control->GetElement(getter_AddRefs(controlElement));
|
||||
if (controlElement) {
|
||||
@ -864,16 +883,25 @@ nsXFormsModelElement::Refresh()
|
||||
// control (get updated node value from the bound node)
|
||||
if (!refresh && boundNode) {
|
||||
curChanged->IsSameNode(boundNode, &refresh);
|
||||
|
||||
if (refresh)
|
||||
// We need to refresh the control. We cannot break out of the loop
|
||||
// as we need to check dependencies
|
||||
|
||||
// Two ways to go here. Keep in mind that controls using model
|
||||
// binding expressions never needs to have dependencies checked as
|
||||
// they only rebind on xforms-rebuild
|
||||
if (refresh && usesModelBinding) {
|
||||
// 1) If the control needs a refresh, and uses model bindings,
|
||||
// we can stop checking here
|
||||
break;
|
||||
}
|
||||
if (refresh || usesModelBinding) {
|
||||
// 2) If either the control needs a refresh or it uses a model
|
||||
// binding we can continue to next changed node
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether any dependencies are dirty. If so, we need to rebind
|
||||
// the control (re-evaluate it's binding expression)
|
||||
for (PRInt32 k = 0; k < deps->Count(); ++k) {
|
||||
for (PRUint32 k = 0; k < depCount; ++k) {
|
||||
/// @note beaufour: I'm not to happy about this ...
|
||||
/// O(mChangedNodes.Count() * deps->Count()), but using the pointers
|
||||
/// for sorting and comparing does not work...
|
||||
@ -1378,7 +1406,8 @@ nsXFormsModelElement::ProcessBindElements()
|
||||
child->GetNamespaceURI(namespaceURI);
|
||||
if (namespaceURI.EqualsLiteral(NS_NAMESPACE_XFORMS)) {
|
||||
rv = ProcessBind(xpath, firstInstanceRoot, 1, 1,
|
||||
nsCOMPtr<nsIDOMElement>(do_QueryInterface(child)));
|
||||
nsCOMPtr<nsIDOMElement>(do_QueryInterface(child)),
|
||||
PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1575,7 +1604,8 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
||||
nsIDOMNode *aContextNode,
|
||||
PRInt32 aContextPosition,
|
||||
PRInt32 aContextSize,
|
||||
nsIDOMElement *aBindElement)
|
||||
nsIDOMElement *aBindElement,
|
||||
PRBool aIsOuter)
|
||||
{
|
||||
// Get the model item properties specified by this \<bind\>.
|
||||
nsCOMPtr<nsIDOMNSXPathExpression> props[eModel__count];
|
||||
@ -1626,6 +1656,19 @@ nsXFormsModelElement::ProcessBind(nsIXFormsXPathEvaluator *aEvaluator,
|
||||
}
|
||||
|
||||
NS_ENSURE_STATE(result);
|
||||
|
||||
// If this is an outer bind, store the nodeset, as controls binding to this
|
||||
// bind will need this.
|
||||
if (aIsOuter) {
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aBindElement));
|
||||
NS_ASSERTION(content, "nsIDOMElement not implementing nsIContent?!");
|
||||
rv = content->SetProperty(nsXFormsAtoms::bind, result,
|
||||
SupportsDtorFunc);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// addref, circumventing nsDerivedSave
|
||||
NS_ADDREF(NS_STATIC_CAST(nsIDOMXPathResult*, result));
|
||||
}
|
||||
|
||||
PRUint32 snapLen;
|
||||
rv = result->GetSnapshotLength(&snapLen);
|
||||
|
@ -196,7 +196,8 @@ private:
|
||||
nsIDOMNode *aContextNode,
|
||||
PRInt32 aContextPosition,
|
||||
PRInt32 aContextSize,
|
||||
nsIDOMElement *aBindElement);
|
||||
nsIDOMElement *aBindElement,
|
||||
PRBool aIsOuter = PR_FALSE);
|
||||
|
||||
NS_HIDDEN_(void) RemoveModelFromDocument();
|
||||
|
||||
|
@ -124,7 +124,12 @@ nsXFormsOutputElement::Bind()
|
||||
}
|
||||
|
||||
if (result) {
|
||||
result->GetSingleNodeValue(getter_AddRefs(mBoundNode));
|
||||
if (mUsesModelBinding) {
|
||||
// When bound via @bind, we'll get a snapshot back
|
||||
result->SnapshotItem(0, getter_AddRefs(mBoundNode));
|
||||
} else {
|
||||
result->GetSingleNodeValue(getter_AddRefs(mBoundNode));
|
||||
}
|
||||
}
|
||||
|
||||
if (mBoundNode && mModel) {
|
||||
|
@ -91,13 +91,15 @@ nsXFormsSetIndexElement::HandleAction(nsIDOMEvent *aEvent,
|
||||
nsCOMPtr<nsIDOMXPathResult> result;
|
||||
// EvaluateNodeBinding uses @bind if @index is not present, but we have
|
||||
// checked that @index is present above
|
||||
PRBool usesModelBinding;
|
||||
rv = nsXFormsUtils::EvaluateNodeBinding(mElement,
|
||||
0,
|
||||
indexStr,
|
||||
EmptyString(),
|
||||
nsIDOMXPathResult::NUMBER_TYPE,
|
||||
getter_AddRefs(model),
|
||||
getter_AddRefs(result));
|
||||
getter_AddRefs(result),
|
||||
&usesModelBinding);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!result) {
|
||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("indexEvalError"),
|
||||
|
@ -66,23 +66,13 @@ nsXFormsSetValueElement::HandleAction(nsIDOMEvent* aEvent,
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIModelElementPrivate> modelPriv;
|
||||
nsCOMPtr<nsIDOMXPathResult> result;
|
||||
nsresult rv =
|
||||
nsXFormsUtils:: EvaluateNodeBinding(mElement,
|
||||
nsXFormsUtils::ELEMENT_WITH_MODEL_ATTR,
|
||||
NS_LITERAL_STRING("ref"),
|
||||
EmptyString(),
|
||||
nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE,
|
||||
getter_AddRefs(modelPriv),
|
||||
getter_AddRefs(result));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!result | !modelPriv)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> singleNode;
|
||||
result->GetSingleNodeValue(getter_AddRefs(singleNode));
|
||||
if (!singleNode)
|
||||
PRBool succeeded =
|
||||
nsXFormsUtils::GetSingleNodeBinding(mElement,
|
||||
getter_AddRefs(singleNode),
|
||||
getter_AddRefs(modelPriv));
|
||||
|
||||
if (!succeeded | !modelPriv | !singleNode)
|
||||
return NS_OK;
|
||||
|
||||
nsAutoString value;
|
||||
@ -105,7 +95,8 @@ nsXFormsSetValueElement::HandleAction(nsIDOMEvent* aEvent,
|
||||
}
|
||||
|
||||
PRBool changed;
|
||||
rv = modelPriv->SetNodeValue(singleNode, value, &changed);
|
||||
nsresult rv =
|
||||
modelPriv->SetNodeValue(singleNode, value, &changed);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (changed) {
|
||||
|
@ -665,18 +665,21 @@ nsXFormsSubmissionElement::GetBoundInstanceData(nsIDOMNode **result)
|
||||
{
|
||||
nsCOMPtr<nsIModelElementPrivate> model;
|
||||
nsCOMPtr<nsIDOMXPathResult> xpRes;
|
||||
PRBool usesModelBind;
|
||||
nsresult rv =
|
||||
nsXFormsUtils::EvaluateNodeBinding(mElement, 0,
|
||||
NS_LITERAL_STRING("ref"),
|
||||
NS_LITERAL_STRING("/"),
|
||||
nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE,
|
||||
getter_AddRefs(model),
|
||||
getter_AddRefs(xpRes));
|
||||
getter_AddRefs(xpRes),
|
||||
&usesModelBind);
|
||||
|
||||
if (NS_FAILED(rv) || !xpRes)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
return xpRes->GetSingleNodeValue(result);
|
||||
return usesModelBind ? xpRes->SnapshotItem(0, result)
|
||||
: xpRes->GetSingleNodeValue(result);
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -470,15 +470,17 @@ nsXFormsUtils::EvaluateNodeBinding(nsIDOMElement *aElement,
|
||||
PRUint16 aResultType,
|
||||
nsIModelElementPrivate **aModel,
|
||||
nsIDOMXPathResult **aResult,
|
||||
PRBool *aUsesModelBind,
|
||||
nsCOMArray<nsIDOMNode> *aDeps,
|
||||
nsStringArray *aIndexesUsed)
|
||||
{
|
||||
if (!aElement || !aModel || !aResult) {
|
||||
return NS_OK;
|
||||
if (!aElement || !aModel || !aResult || !aUsesModelBind) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aModel = nsnull;
|
||||
*aResult = nsnull;
|
||||
*aUsesModelBind = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> contextNode;
|
||||
nsCOMPtr<nsIDOMElement> bindElement;
|
||||
@ -500,30 +502,44 @@ nsXFormsUtils::EvaluateNodeBinding(nsIDOMElement *aElement,
|
||||
return NS_OK; // this will happen if the doc is still loading
|
||||
}
|
||||
|
||||
nsAutoString expr;
|
||||
////////////////////
|
||||
// STEP 1: Handle @bind'ings
|
||||
if (bindElement) {
|
||||
if (!outerBind) {
|
||||
if (outerBind) {
|
||||
// If there is an outer bind element, we retrieve its nodeset.
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(bindElement));
|
||||
NS_ASSERTION(content, "nsIDOMElement not implementing nsIContent?!");
|
||||
|
||||
NS_IF_ADDREF(*aResult =
|
||||
NS_STATIC_CAST(nsIDOMXPathResult*,
|
||||
content->GetProperty(nsXFormsAtoms::bind)));
|
||||
*aUsesModelBind = PR_TRUE;
|
||||
} else {
|
||||
// References to inner binds are not defined.
|
||||
// "When you refer to @id on a nested bind it returns an emtpy nodeset
|
||||
// because it has no meaning. The XForms WG will assign meaning in the
|
||||
// future."
|
||||
// @see http://www.w3.org/MarkUp/Group/2004/11/f2f/2004Nov11#resolution6
|
||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("innerBindRefError"),
|
||||
aElement);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////
|
||||
// STEP 2: No bind attribute
|
||||
// If there's no bind attribute, we expect there to be a |aBindingAttr|
|
||||
// attribute.
|
||||
nsAutoString expr;
|
||||
aElement->GetAttribute(aBindingAttr, expr);
|
||||
if (expr.IsEmpty()) {
|
||||
// if there's no default binding, bail out
|
||||
if (aDefaultRef.IsEmpty())
|
||||
return NS_OK;
|
||||
} else {
|
||||
// If there is a (outer) bind element, we retrieve its nodeset.
|
||||
bindElement->GetAttribute(NS_LITERAL_STRING("nodeset"), expr);
|
||||
}
|
||||
} else {
|
||||
// If there's no bind element, we expect there to be a |aBindingAttr| attribute.
|
||||
aElement->GetAttribute(aBindingAttr, expr);
|
||||
|
||||
if (expr.IsEmpty())
|
||||
{
|
||||
if (aDefaultRef.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
expr.Assign(aDefaultRef);
|
||||
}
|
||||
expr.Assign(aDefaultRef);
|
||||
}
|
||||
|
||||
// Evaluate |expr|
|
||||
@ -536,6 +552,9 @@ nsXFormsUtils::EvaluateNodeBinding(nsIDOMElement *aElement,
|
||||
aDeps,
|
||||
aIndexesUsed);
|
||||
|
||||
////////////////////
|
||||
// STEP 3: Check for lazy binding
|
||||
|
||||
// If the evaluation failed because the node wasn't there and we should be
|
||||
// lazy authoring, then create it (if the situation qualifies, of course).
|
||||
// Novell only allows lazy authoring of single bound nodes.
|
||||
@ -769,6 +788,7 @@ nsXFormsUtils::GetSingleNodeBinding(nsIDOMElement* aElement,
|
||||
return PR_FALSE;
|
||||
nsCOMPtr<nsIModelElementPrivate> model;
|
||||
nsCOMPtr<nsIDOMXPathResult> result;
|
||||
PRBool usesModelBind;
|
||||
|
||||
nsresult rv = EvaluateNodeBinding(aElement,
|
||||
nsXFormsUtils::ELEMENT_WITH_MODEL_ATTR,
|
||||
@ -776,13 +796,18 @@ nsXFormsUtils::GetSingleNodeBinding(nsIDOMElement* aElement,
|
||||
EmptyString(),
|
||||
nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE,
|
||||
getter_AddRefs(model),
|
||||
getter_AddRefs(result));
|
||||
getter_AddRefs(result),
|
||||
&usesModelBind);
|
||||
|
||||
if (NS_FAILED(rv) || !result)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> singleNode;
|
||||
result->GetSingleNodeValue(getter_AddRefs(singleNode));
|
||||
if (usesModelBind) {
|
||||
result->SnapshotItem(0, getter_AddRefs(singleNode));
|
||||
} else {
|
||||
result->GetSingleNodeValue(getter_AddRefs(singleNode));
|
||||
}
|
||||
if (!singleNode)
|
||||
return PR_FALSE;
|
||||
|
||||
|
@ -221,6 +221,7 @@ public:
|
||||
PRUint16 aResultType,
|
||||
nsIModelElementPrivate **aModel,
|
||||
nsIDOMXPathResult **aResult,
|
||||
PRBool *aUsesModelBind,
|
||||
nsCOMArray<nsIDOMNode> *aDeps = nsnull,
|
||||
nsStringArray *aIndexesUsed = nsnull);
|
||||
|
||||
|
@ -94,26 +94,12 @@ nsXFormsValueElement::OnCreated(nsIXTFGenericElementWrapper *aWrapper)
|
||||
NS_IMETHODIMP
|
||||
nsXFormsValueElement::GetValue(nsAString &aValue)
|
||||
{
|
||||
nsCOMPtr<nsIModelElementPrivate> model;
|
||||
nsCOMPtr<nsIDOMXPathResult> result;
|
||||
nsXFormsUtils::EvaluateNodeBinding(mElement,
|
||||
nsXFormsUtils::ELEMENT_WITH_MODEL_ATTR,
|
||||
NS_LITERAL_STRING("ref"),
|
||||
EmptyString(),
|
||||
nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE,
|
||||
getter_AddRefs(model),
|
||||
getter_AddRefs(result));
|
||||
|
||||
if (result) {
|
||||
nsCOMPtr<nsIDOMNode> singleNode;
|
||||
result->GetSingleNodeValue(getter_AddRefs(singleNode));
|
||||
|
||||
if (singleNode) {
|
||||
nsString value;
|
||||
nsXFormsUtils::GetNodeValue(singleNode, value);
|
||||
aValue.Assign(value);
|
||||
return NS_OK;
|
||||
}
|
||||
nsString value;
|
||||
PRBool singleNodeVal =
|
||||
nsXFormsUtils::GetSingleNodeBindingValue(mElement, value);
|
||||
if (singleNodeVal) {
|
||||
aValue.Assign(value);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOM3Node> node3 = do_QueryInterface(mElement);
|
||||
|
@ -67,6 +67,7 @@ uploadBoundTypeError = XForms Error (28): Upload element not bound to valid data
|
||||
copyError = XForms Error (29): A copy element was found whose parent is not an itemset element
|
||||
submitMailtoInit = XForms Error (30): No mailto: handler found
|
||||
submitMailtoFailed = XForms Error (31): Failed to load a mail client for a mailto: submission
|
||||
innerBindRefError = XForms Error (32): You are refering to an inner bind, which is undefined in XForms 1.0
|
||||
|
||||
# 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.
|
||||
|
Loading…
Reference in New Issue
Block a user