[XForms] Fix context setting for output with value attribute. Bug 305196, r=smaug+aaronr

This commit is contained in:
allan%beaufour.dk 2006-04-06 08:08:55 +00:00
Родитель be0a441b6e
Коммит 442017d857
5 изменённых файлов: 68 добавлений и 28 удалений

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

@ -320,12 +320,18 @@ nsXFormsControlStubBase::ProcessNodeBinding(const nsString &aBindingAtt
}
nsresult
nsXFormsControlStubBase::BindToModel()
nsXFormsControlStubBase::BindToModel(PRBool aSetBoundNode)
{
nsCOMPtr<nsIModelElementPrivate> oldModel(mModel);
nsCOMPtr<nsIXFormsControl> parentControl;
mModel = nsXFormsUtils::GetModel(mElement, getter_AddRefs(parentControl));
nsCOMPtr<nsIDOMNode> boundNode;
mModel = nsXFormsUtils::GetModel(mElement, getter_AddRefs(parentControl),
kElementFlags,
getter_AddRefs(boundNode));
if (aSetBoundNode) {
mBoundNode.swap(boundNode);
}
return MaybeAddToModel(oldModel, parentControl);
}
@ -632,8 +638,7 @@ nsXFormsControlStubBase::GetContext(nsAString &aModelID,
if (aContextNode) {
if (mBoundNode) {
// We are bound to a node: This is the context node
CallQueryInterface(mBoundNode, aContextNode); // addrefs
NS_ASSERTION(*aContextNode, "could not QI context node from bound node?");
NS_ADDREF(*aContextNode = mBoundNode);
} else if (mModel) {
// We are bound to a model: The document element of its default instance
// document is the context node

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

@ -240,11 +240,15 @@ protected:
void RemoveIndexListeners();
/**
* Binds the control to the model. Does _not_ set mBoundNode, etc. Just sets
* mModel, and handle attaching to the model (including reattaching from any
* old model).
* Binds the control to the model. Just sets mModel, and handle attaching to
* the model (including reattaching from any old model).
*
* @note It can also set the mBoundNode, but does not do a proper node
* binding, as in setting up dependencies, attaching index() listeners, etc.
*
* @param aSetBoundNode Set mBoundNode too?
*/
nsresult BindToModel();
nsresult BindToModel(PRBool aSetBoundNode = PR_FALSE);
/**
* Forces a rebinding to the model.

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

@ -75,20 +75,26 @@ public:
// nsIXFormsControl
NS_IMETHOD Bind();
NS_IMETHOD Refresh();
NS_IMETHOD GetBoundNode(nsIDOMNode **aBoundNode);
// nsIXFormsDelegate
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD GetHasBoundNode(PRBool *aHasBoundNode);
nsXFormsOutputElement() :
nsXFormsDelegateStub(NS_LITERAL_STRING("output")) {}
nsXFormsOutputElement();
private:
PRBool mHasBinding;
nsString mValue;
PRBool mValueIsDirty;
PRPackedBool mHasBinding;
PRPackedBool mValueIsDirty;
nsString mValue;
};
nsXFormsOutputElement::nsXFormsOutputElement()
: nsXFormsDelegateStub(NS_LITERAL_STRING("output")),
mHasBinding(PR_FALSE), mValueIsDirty(PR_TRUE)
{
}
// nsIXFormsControl
nsresult
@ -101,21 +107,24 @@ nsXFormsOutputElement::Bind()
if (!mHasParent)
return NS_OK;
nsresult rv = mElement->HasAttribute(NS_LITERAL_STRING("ref"), &mHasBinding);
PRBool tmp;
nsresult rv = mElement->HasAttribute(NS_LITERAL_STRING("ref"), &tmp);
NS_ENSURE_SUCCESS(rv, rv);
mHasBinding = tmp;
if (!mHasBinding) {
rv = mElement->HasAttribute(NS_LITERAL_STRING("bind"), &mHasBinding);
rv = mElement->HasAttribute(NS_LITERAL_STRING("bind"), &tmp);
NS_ENSURE_SUCCESS(rv, rv);
mHasBinding = tmp;
if (!mHasBinding) {
// If output only has a value attribute, it can't have a bound node.
// In an effort to streamline this a bit, we'll just get mModel here and
// add output to the deferred bind list if necessary. This should be all
// that we need from the services that ProcessNodeBinding provides.
// ProcessNodeBinding is called during ::Refresh (via GetValue) so we just
// need a few things set up before ::Refresh gets called (usually right
// after ::Bind)
// If output only has a value attribute, it can't have a proper single
// node binding. In an effort to streamline this a bit, we'll just bind
// to the model here and add output to the deferred bind list if
// necessary. This should be all that we need from the services that
// ProcessNodeBinding provides. ProcessNodeBinding is called during
// ::Refresh (via GetValue) so we just need a few things set up before
// ::Refresh gets called (usually right after ::Bind)
nsCOMPtr<nsIDOMDocument> domDoc;
mElement->GetOwnerDocument(getter_AddRefs(domDoc));
@ -123,7 +132,7 @@ nsXFormsOutputElement::Bind()
nsXFormsModelElement::DeferElementBind(domDoc, this);
}
return BindToModel();
return BindToModel(PR_TRUE);
}
}
@ -160,6 +169,20 @@ nsXFormsOutputElement::Refresh()
return nsXFormsDelegateStub::Refresh();
}
NS_IMETHODIMP
nsXFormsOutputElement::GetBoundNode(nsIDOMNode **aBoundNode)
{
return mHasBinding ? nsXFormsDelegateStub::GetBoundNode(aBoundNode) : NS_OK;
}
NS_IMETHODIMP
nsXFormsOutputElement::GetHasBoundNode(PRBool *aHasBoundNode)
{
NS_ENSURE_ARG_POINTER(aHasBoundNode);
*aHasBoundNode = (mBoundNode && mHasBinding) ? PR_TRUE : PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsXFormsOutputElement::GetValue(nsAString& aValue)
{

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

@ -367,7 +367,8 @@ nsXFormsUtils::GetNodeContext(nsIDOMElement *aElement,
/* static */ already_AddRefed<nsIModelElementPrivate>
nsXFormsUtils::GetModel(nsIDOMElement *aElement,
nsIXFormsControl **aParentControl,
PRUint32 aElementFlags)
PRUint32 aElementFlags,
nsIDOMNode **aContextNode)
{
nsCOMPtr<nsIModelElementPrivate> model;
@ -385,9 +386,13 @@ nsXFormsUtils::GetModel(nsIDOMElement *aElement,
NS_ENSURE_TRUE(model, nsnull);
if (aContextNode) {
NS_IF_ADDREF(*aContextNode = contextNode);
}
nsIModelElementPrivate *result = nsnull;
if (model)
CallQueryInterface(model, &result); // addrefs
NS_ADDREF(result = model);
return result;
}

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

@ -207,12 +207,15 @@ public:
* @param aElement The element
* @param aParentControl The parent control setting the context
* @param aElementFlags Flags describing characteristics of aElement
* @param aContextNode The context node
* @return The model
*/
static NS_HIDDEN_(already_AddRefed<nsIModelElementPrivate>)
GetModel(nsIDOMElement *aElement,
nsIXFormsControl **aParentControl = nsnull,
PRUint32 aElementFlags = ELEMENT_WITH_MODEL_ATTR);
PRUint32 aElementFlags = ELEMENT_WITH_MODEL_ATTR,
nsIDOMNode **aContextNode = nsnull);
/**
* Evaluate a 'bind' or |aBindingAttr| attribute on |aElement|.