diff --git a/extensions/xforms/nsXFormsMDGEngine.cpp b/extensions/xforms/nsXFormsMDGEngine.cpp index 12f0831843db..0191377e3d78 100644 --- a/extensions/xforms/nsXFormsMDGEngine.cpp +++ b/extensions/xforms/nsXFormsMDGEngine.cpp @@ -367,7 +367,10 @@ nsXFormsMDGEngine::Recalculate(nsXFormsMDGSet* aChangedNodes) rv = xpath_res->GetStringValue(nodeval); NS_ENSURE_SUCCESS(rv, rv); - rv = SetNodeValue(g->mContextNode, nodeval, PR_FALSE, nsnull); + rv = SetNodeValueInternal(g->mContextNode, + nodeval, + PR_FALSE, + PR_TRUE); if (NS_SUCCEEDED(rv)) { NS_ENSURE_TRUE(aChangedNodes->AddNode(g->mContextNode), NS_ERROR_FAILURE); @@ -609,8 +612,21 @@ nsXFormsMDGEngine::GetNodeValue(nsIDOMNode *aContextNode, nsresult nsXFormsMDGEngine::SetNodeValue(nsIDOMNode *aContextNode, const nsAString &aNodeValue, - PRBool aMarkNode, PRBool *aNodeChanged) +{ + return SetNodeValueInternal(aContextNode, + aNodeValue, + PR_TRUE, + PR_FALSE, + aNodeChanged); +} + +nsresult +nsXFormsMDGEngine::SetNodeValueInternal(nsIDOMNode *aContextNode, + const nsAString &aNodeValue, + PRBool aMarkNode, + PRBool aIsCalculate, + PRBool *aNodeChanged) { if (aNodeChanged) { *aNodeChanged = PR_FALSE; @@ -619,7 +635,9 @@ nsXFormsMDGEngine::SetNodeValue(nsIDOMNode *aContextNode, const nsXFormsNodeState* ns = GetNodeState(aContextNode); NS_ENSURE_TRUE(ns, NS_ERROR_FAILURE); - if (ns->IsReadonly()) { + // If the node is read-only and not set by a @calculate MIP, + // ignore the call + if (ns->IsReadonly() && !aIsCalculate) { /// /// @todo Better feedback for readonly nodes? (XXX) return NS_OK; diff --git a/extensions/xforms/nsXFormsMDGEngine.h b/extensions/xforms/nsXFormsMDGEngine.h index 8591447dbf29..045a4a32fcee 100644 --- a/extensions/xforms/nsXFormsMDGEngine.h +++ b/extensions/xforms/nsXFormsMDGEngine.h @@ -313,6 +313,20 @@ protected: */ nsresult Invalidate(); + /** + * Set the value of a node. + + * @param aContextNode The node to set the value for + * @param aNodeValue The value + * @param aMarkNode Whether to mark node as changed + * @param aNodeChanged Was node changed? + * @param aIsCalculate Is it a @calculate setting the value? + */ + nsresult SetNodeValueInternal(nsIDOMNode *aContextNode, + const nsAString &aNodeValue, + PRBool aMarkNode = PR_TRUE, + PRBool aIsCalculate = PR_FALSE, + PRBool *aNodeChanged = nsnull); public: /** * Constructor @@ -382,16 +396,14 @@ public: nsresult MarkNodeAsChanged(nsIDOMNode *aContextNode); /** - * Set the value of a node. (used by nsXFormsMDG) - + * Set the value of a node -- the public version of SetNodeValueInternal(). + * * @param aContextNode The node to set the value for * @param aNodeValue The value - * @param aMarkNode Whether to mark node as changed * @param aNodeChanged Was node changed? */ nsresult SetNodeValue(nsIDOMNode *aContextNode, const nsAString &aNodeValue, - PRBool aMarkNode = PR_TRUE, PRBool *aNodeChanged = nsnull); /** diff --git a/extensions/xforms/nsXFormsModelElement.cpp b/extensions/xforms/nsXFormsModelElement.cpp index 33d62f63bdfd..e85a9c5e8a79 100644 --- a/extensions/xforms/nsXFormsModelElement.cpp +++ b/extensions/xforms/nsXFormsModelElement.cpp @@ -841,7 +841,6 @@ nsXFormsModelElement::SetNodeValue(nsIDOMNode *aContextNode, { return mMDG.SetNodeValue(aContextNode, aNodeValue, - PR_TRUE, aNodeChanged); }