Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes
nsXFormsMDGEngine Class Reference

The Multi Dependency Graph (MDG) Engine. More...

#include <nsXFormsMDGEngine.h>

Collaboration diagram for nsXFormsMDGEngine:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsXFormsMDGEngine ()
 Constructor.
 ~nsXFormsMDGEngine ()
nsresult Init (nsXFormsModelElement *aModel)
 Initializes the internal structures.
nsresult AddMIP (ModelItemPropName aType, nsIDOMNSXPathExpression *aExpression, nsCOMArray< nsIDOMNode > *aDependencies, PRBool aDynFunc, nsIDOMNode *aContextNode, PRInt32 aContextPos, PRInt32 aContextSize)
 Insert new MIP (Model Item Property) into graph.
nsresult Recalculate (nsCOMArray< nsIDOMNode > *aChangedNodes)
 Recalculate the MDG.
nsresult Revalidate (nsCOMArray< nsIDOMNode > *aNodes)
 Revalidate nodes.
nsresult Rebuild ()
 Rebuilds the MDG.
nsresult Clear ()
 Clears all information in the MDG.
nsresult ClearDispatchFlags ()
 Clears all Dispatch flags.
nsresult MarkNodeAsChanged (nsIDOMNode *aContextNode)
 Mark a node as changed.
nsresult SetNodeValue (nsIDOMNode *aContextNode, const nsAString &aNodeValue, PRBool *aNodeChanged=nsnull)
 Set the value of a node -- the public version of SetNodeValueInternal().
nsresult SetNodeContent (nsIDOMNode *aContextNode, nsIDOMNode *aContentEnvelope)
 Set the contents of a node.
const nsXFormsNodeStateGetNodeState (nsIDOMNode *aContextNode)
 External interface of GetNCNodeState(), returns const pointer to the node state.

Protected Member Functions

 nsXFormsMDGEngine (nsXFormsMDGEngine &)
 Hidden copy constructor.
nsXFormsNodeStateGetNCNodeState (nsIDOMNode *aContextNode)
 Get non-const (NC) node state for a node, create a new node state if necessary.
nsresult CreateNewChild (nsIDOMNode *aContextNode, const nsAString &aNodeValue, nsIDOMNode *aBeforeNode=nsnull)
 Inserts a new text child for aContextNode.
nsXFormsMDGNodeGetNode (nsIDOMNode *aDomNode, ModelItemPropName aType, PRBool aCreate=PR_TRUE)
 Retrieve a node from the graph.
PRBool AndFlags (PRUint16 aAndMask)
 Boolean AND all flags with a mask.
nsresult BooleanExpression (nsXFormsMDGNode *aNode, PRBool &aRes)
 Evaluates the expression for the given node and returns the boolean result.
nsresult ComputeMIP (eFlag_t aStateFlag, eFlag_t aDispatchFlag, nsXFormsMDGNode *aNode, PRBool &aDidChange)
 Compute MIP value for node types with boolean result (all except calculate)
nsresult ComputeMIPWithInheritance (eFlag_t aStateFlag, eFlag_t aDispatchFlag, eFlag_t aInheritanceFlag, nsXFormsMDGNode *aNode, nsCOMArray< nsIDOMNode > *aSet)
 Same as ComputeMIP(), but also handles any inheritance of attributes.
nsresult AttachInheritance (nsCOMArray< nsIDOMNode > *aSet, nsIDOMNode *aSrc, PRBool aState, eFlag_t aStateFlag)
 Attaches inheritance to all children of a given node.
nsresult Invalidate ()
 Invalidate the information, ie.
nsresult SetNodeValueInternal (nsIDOMNode *aContextNode, const nsAString &aNodeValue, PRBool aMarkNode=PR_TRUE, PRBool aIsCalculate=PR_FALSE, PRBool *aNodeChanged=nsnull)
 Set the value of a node.
nsresult HandleMarkedNodes (nsCOMArray< nsIDOMNode > *aArray)
 Handle nodes nodes marked as dirty, and insert into "changed nodes array".

Static Protected Member Functions

static PLDHashOperator PR_CALLBACK DeleteLinkedNodes (nsISupports *aKey, nsAutoPtr< nsXFormsMDGNode > &aNode, void *aArg)
 Used by Clear() and ~ to delete the linked nodes in mNodeToMDG, the hash table itself handles the main nodes.
static PLDHashOperator PR_CALLBACK AddStartNodes (nsISupports *aKey, nsXFormsMDGNode *aNode, void *aDeque)
 Used by Rebuild() to find the start nodes for mGraph, that is nodes where mCount == 0.
static PLDHashOperator PR_CALLBACK AndFlag (nsISupports *aKey, nsAutoPtr< nsXFormsNodeState > &aState, void *aMask)
 Used by AndFlags() to boolean AND all flags with aMask.

Protected Attributes

nsClassHashtable
< nsISupportsHashKey,
nsXFormsMDGNode
mNodeToMDG
 Maps from nsIDOMNode to nsXFormsMDGNode.
nsClassHashtable
< nsISupportsHashKey,
nsXFormsNodeState
mNodeStates
 Maps from nsIDOMNode to nsXFormsNodeState.
nsXFormsNodeState mDefaultState
 Default node state.
PRBool mJustRebuilt
 True when Rebuild() has been run, but not ClearDispatchFlags()
PRBool mFirstCalculate
 True when last Calculate() was run when mJustRebuilt was true.
nsVoidArray mGraph
 The actual MDG.
nsXFormsModelElementmModel
 The model that created the MDG.
nsCOMArray< nsIDOMNodemMarkedNodes
 Nodes that are marked as changed, and should be included in recalculation.
PRInt32 mNodesInGraph
 Number of nodes in the graph.

Detailed Description

The Multi Dependency Graph (MDG) Engine.

This class handles all the necessary logic to create and maintain the MDG, and update the instance data accordingly.

A bit about the graph: As specified in the spec., one node (nsXFormsMDGNode) is created in the graph for each of the attributes (readonly, calculate, etc.) for a nsIDOMNode. These graph nodes are owned by the mNodeToMDG hash table, which maps from a nsIDOMNode to the first node in a single-linked list (mNext) of nodes for the same nsIDOMNode.

Todo:
Merge SetNodeValue() with nsXFormsUtils::SetNodeValue() (XXX)

Definition at line 155 of file nsXFormsMDGEngine.h.


Constructor & Destructor Documentation

Hidden copy constructor.

Definition at line 188 of file nsXFormsMDGEngine.h.

{}

Constructor.

Definition at line 126 of file nsXFormsMDGEngine.cpp.

Definition at line 132 of file nsXFormsMDGEngine.cpp.

Here is the call graph for this function:


Member Function Documentation

nsresult nsXFormsMDGEngine::AddMIP ( ModelItemPropName  aType,
nsIDOMNSXPathExpression aExpression,
nsCOMArray< nsIDOMNode > *  aDependencies,
PRBool  aDynFunc,
nsIDOMNode aContextNode,
PRInt32  aContextPos,
PRInt32  aContextSize 
)

Insert new MIP (Model Item Property) into graph.

Parameters:
aTypeThe type of MIP
aExpressionThe XPath expression
aDependenciesSet of nodes expression depends on
aDynFuncTrue if expression uses dynamic functions
aContextNodeThe context node for aExpression
aContextPosThe context positions of aExpression
aContextSizeThe context size for aExpression

Definition at line 153 of file nsXFormsMDGEngine.cpp.

{
  NS_ENSURE_ARG(aContextNode);
  
#ifdef DEBUG_XF_MDG
  nsAutoString nodename;
  aContextNode->GetNodeName(nodename);
  printf("nsXFormsMDGEngine::AddMIP(aContextNode=%s, aExpression=%p, aDependencies=|%d|,\n",
         NS_ConvertUTF16toUTF8(nodename).get(),
         (void*) aExpression,
         aDependencies ? aDependencies->Count() : 0);
  printf("                          aContextPos=%d, aContextSize=%d, aType=%s, aDynFunc=%d)\n",
         aContextPos, aContextSize, gMIPNames[aType], aDynFunc);
#endif
  nsXFormsMDGNode* newnode = GetNode(aContextNode,
                                     aType,
                                     PR_TRUE);
  
  if (!newnode) {
    return NS_ERROR_OUT_OF_MEMORY;
  }
  
  if (newnode->HasExpr()) {
    // MIP already in the graph. That is, there is already a MIP of the same
    // type for this node, which is illegal.
    // Example: <bind nodeset="x" required="true()" required="false()"/>
    return NS_ERROR_ABORT;
  }

  if (aExpression) {
    newnode->SetExpression(aExpression, aDynFunc, aContextPos, aContextSize);
  }
  
  // Add dependencies
  if (aDependencies) {
    nsCOMPtr<nsIDOMNode> dep_domnode;
    nsXFormsMDGNode* dep_gnode;
    for (PRInt32 i = 0; i < aDependencies->Count(); ++i) {
      dep_domnode = aDependencies->ObjectAt(i);
      if (!dep_domnode) {
        return NS_ERROR_NULL_POINTER;
      }

#ifdef DEBUG_XF_MDG
      printf("\tDependency #%2d: %p\n", i, (void*) dep_domnode);
#endif
      
      // Get calculate graph node for the dependency (only a calculate
      // property can influence another MIP).
      dep_gnode = GetNode(dep_domnode, eModel_calculate);
      if (!dep_gnode) {
        return NS_ERROR_OUT_OF_MEMORY;
      }
  
      if (dep_gnode->mType == aType && dep_gnode->mContextNode == aContextNode) {
        // Reference to itself, ignore
        continue;
      }
  
      // Add this node as a successor to the dependency (ie. the dependency
      // should be (re-)calculated before this node)
      dep_gnode->mSuc.AppendElement(newnode);
      newnode->mCount++;
    }
  }

  return NS_OK;
}

Here is the call graph for this function:

PLDHashOperator nsXFormsMDGEngine::AddStartNodes ( nsISupports *  aKey,
nsXFormsMDGNode aNode,
void aDeque 
) [static, protected]

Used by Rebuild() to find the start nodes for mGraph, that is nodes where mCount == 0.

Todo:
Is it not possible to check error condition? (XXX)

Definition at line 1015 of file nsXFormsMDGEngine.cpp.

{
#ifdef DEBUG_XF_MDG
  printf("nsXFormsMDGEngine::AddStartNodes(aKey=n/a, aNode=%p, aDeque=%p)\n",
         (void*) aNode,
         aDeque);
#endif

  nsDeque* deque = NS_STATIC_CAST(nsDeque*, aDeque);
  if (!deque) {
    NS_ERROR("nsXFormsMDGEngine::AddStartNodes called with NULL aDeque");
    return PL_DHASH_STOP;
  }
  
  while (aNode) {
    if (aNode->mCount == 0) {
      deque->Push(aNode);
    }
    aNode = aNode->mNext;
  }
    
  return PL_DHASH_NEXT;
}

Here is the caller graph for this function:

PLDHashOperator nsXFormsMDGEngine::AndFlag ( nsISupports *  aKey,
nsAutoPtr< nsXFormsNodeState > &  aState,
void aMask 
) [static, protected]

Used by AndFlags() to boolean AND all flags with aMask.

Definition at line 1044 of file nsXFormsMDGEngine.cpp.

{
  PRUint16* andMask = NS_STATIC_CAST(PRUint16*, aMask);
  if (!andMask) {
    return PL_DHASH_STOP;
  }
  *aState &= *andMask;
  return PL_DHASH_NEXT;
}

Here is the caller graph for this function:

PRBool nsXFormsMDGEngine::AndFlags ( PRUint16  aAndMask) [protected]

Boolean AND all flags with a mask.

Parameters:
aAndMaskThe mask
Returns:
Did operation succeed?

Definition at line 1057 of file nsXFormsMDGEngine.cpp.

{
  PRUint32 entries = mNodeStates.Enumerate(AndFlag, &aAndMask);
  return (entries == mNodeStates.Count()) ? PR_TRUE : PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXFormsMDGEngine::AttachInheritance ( nsCOMArray< nsIDOMNode > *  aSet,
nsIDOMNode aSrc,
PRBool  aState,
eFlag_t  aStateFlag 
) [protected]

Attaches inheritance to all children of a given node.

Parameters:
aSetSet of the nodes influenced by operation
aSrcThe node
aStateThe state of the flag
aStateFlagThe flag

Definition at line 1152 of file nsXFormsMDGEngine.cpp.

{
  NS_ENSURE_ARG(aSrc);
  
  nsCOMPtr<nsIDOMNode> node;
  nsresult rv;
  PRBool updateNode = PR_FALSE;

  nsCOMPtr<nsIDOMNodeList> childList;
  rv = aSrc->GetChildNodes(getter_AddRefs(childList));
  NS_ENSURE_SUCCESS(rv, rv);

  PRUint32 childCount;
  rv = childList->GetLength(&childCount);
  NS_ENSURE_SUCCESS(rv, rv);

  for (PRUint32 i = 0; i < childCount; i++) {
    rv = childList->Item(i, getter_AddRefs(node));
    NS_ENSURE_SUCCESS(rv, rv);
    NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);

    nsXFormsNodeState *ns = GetNCNodeState(node);
    NS_ENSURE_TRUE(ns, NS_ERROR_FAILURE);

    PRBool curState = ns->Test(aStateFlag);    

    if (aStateFlag == eFlag_RELEVANT) {
      if (!aState) { // The nodes are getting irrelevant
        if (ns->Test(eFlag_INHERITED_RELEVANT) && curState) {
          ns->Set(eFlag_INHERITED_RELEVANT, PR_FALSE);
          ns->Set(eFlag_DISPATCH_RELEVANT_CHANGED, PR_TRUE);
          updateNode = PR_TRUE;
        }
      } else { // The nodes are becoming relevant
        if (curState) {
          // Relevant has changed from inheritance
          ns->Set(eFlag_DISPATCH_RELEVANT_CHANGED, PR_TRUE);
          ns->Set(eFlag_INHERITED_RELEVANT, PR_TRUE);
          updateNode = PR_TRUE;
        }
      }
    } else if (aStateFlag == eFlag_READONLY) {
      if (aState) { // The nodes are getting readonly
        if (!ns->Test(eFlag_INHERITED_READONLY) && curState == PR_FALSE) {
          ns->Set(eFlag_INHERITED_READONLY | eFlag_DISPATCH_READONLY_CHANGED,
                  PR_TRUE);
          updateNode = PR_TRUE;
        }
      } else { // The nodes are getting readwrite
        if (curState) {
          ns->Set(eFlag_DISPATCH_READONLY_CHANGED, PR_TRUE);
          ns->Set(eFlag_INHERITED_READONLY, PR_FALSE);
          updateNode = PR_TRUE;
        }
      }
    }
    
    if (updateNode) {
      rv = AttachInheritance(aSet, node, aState, aStateFlag);
      NS_ENSURE_SUCCESS(rv, rv);
      NS_ENSURE_TRUE(aSet->AppendObject(node), NS_ERROR_FAILURE);
      updateNode = PR_FALSE;
    }
  }

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Evaluates the expression for the given node and returns the boolean result.

Parameters:
aNodeThe node to evaluate
aResThe result of the evaluation

Definition at line 1065 of file nsXFormsMDGEngine.cpp.

{
  NS_ENSURE_ARG_POINTER(aNode);
  NS_ENSURE_TRUE(aNode->mExpression, NS_ERROR_FAILURE);
  
  nsISupports* retval;
  nsresult rv;

  rv = aNode->mExpression->EvaluateWithContext(aNode->mContextNode,
                                               aNode->mContextPosition,
                                               aNode->mContextSize,
                                               nsIDOMXPathResult::BOOLEAN_TYPE,
                                               nsnull,
                                               &retval);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIDOMXPathResult> xpath_res = do_QueryInterface(retval);
  NS_ENSURE_TRUE(xpath_res, NS_ERROR_FAILURE);
  
  rv = xpath_res->GetBooleanValue(&state);
  
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Clears all information in the MDG.

Definition at line 600 of file nsXFormsMDGEngine.cpp.

                         {
#ifdef DEBUG_XF_MDG
  printf("nsXFormsMDGEngine::Clear()\n");
#endif

  nsresult rv = mNodeToMDG.Enumerate(DeleteLinkedNodes, nsnull);
  NS_ENSURE_SUCCESS(rv, rv);

  mNodeToMDG.Clear();

  mNodeStates.Clear();
  
  mGraph.Clear();
  
  mNodesInGraph = 0;

  return NS_OK;
}

Here is the call graph for this function:

Clears all Dispatch flags.

Definition at line 593 of file nsXFormsMDGEngine.cpp.

Here is the call graph for this function:

nsresult nsXFormsMDGEngine::ComputeMIP ( eFlag_t  aStateFlag,
eFlag_t  aDispatchFlag,
nsXFormsMDGNode aNode,
PRBool aDidChange 
) [protected]

Compute MIP value for node types with boolean result (all except calculate)

Parameters:
aStateFlagThe flag for the type of MIP
aDispatchFlagThe dispatch flag
aNodeThe context node
aDidChangeWas the node changed?

Definition at line 1090 of file nsXFormsMDGEngine.cpp.

{
  NS_ENSURE_ARG(aNode);

  aDidChange = PR_FALSE;

  if (!aNode->mExpression)
    return NS_OK;

  nsXFormsNodeState* ns = GetNCNodeState(aNode->mContextNode);
  NS_ENSURE_TRUE(ns, NS_ERROR_FAILURE);
  
  PRBool state;
  nsresult rv = BooleanExpression(aNode, state);
  NS_ENSURE_SUCCESS(rv, rv);
  
  PRBool cstate = ns->Test(aStateFlag);  
  
  ns->Set(aStateFlag, state);

  aDidChange = (state != cstate) ? PR_TRUE : PR_FALSE;
  if (aDidChange) {
    ns->Set(aDispatchFlag, PR_TRUE);
  }
  
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXFormsMDGEngine::ComputeMIPWithInheritance ( eFlag_t  aStateFlag,
eFlag_t  aDispatchFlag,
eFlag_t  aInheritanceFlag,
nsXFormsMDGNode aNode,
nsCOMArray< nsIDOMNode > *  aSet 
) [protected]

Same as ComputeMIP(), but also handles any inheritance of attributes.

Parameters:
aStateFlagThe flag for the type of MIP
aDispatchFlagThe dispatch flag
aInheritanceFlagThe inheritance flag for the type of MIP
aNodeThe context node
aSetSet of the nodes influenced by operation

Definition at line 1122 of file nsXFormsMDGEngine.cpp.

{
  nsresult rv;
  PRBool didChange;
  rv = ComputeMIP(aStateFlag, aDispatchFlag, aNode, didChange);
  NS_ENSURE_SUCCESS(rv, rv);
  
  if (didChange) {
    nsXFormsNodeState* ns = GetNCNodeState(aNode->mContextNode);
    NS_ENSURE_TRUE(ns, NS_ERROR_FAILURE);
    if (   !(aStateFlag == eFlag_READONLY && ns->Test(aInheritanceFlag))
        ||  (aStateFlag == eFlag_RELEVANT && ns->Test(aInheritanceFlag)) )
    {
      NS_ENSURE_TRUE(aSet->AppendObject(aNode->mContextNode),
                     NS_ERROR_FAILURE);
      rv = AttachInheritance(aSet,
                             aNode->mContextNode,
                             ns->Test(aStateFlag),
                             aStateFlag);
    }
  }

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXFormsMDGEngine::CreateNewChild ( nsIDOMNode aContextNode,
const nsAString &  aNodeValue,
nsIDOMNode aBeforeNode = nsnull 
) [protected]

Inserts a new text child for aContextNode.

Parameters:
aContextNodeThe node to create a child for
aNodeValueThe value of the new node
aBeforeNodeIf non-null, insert new node before this node

Definition at line 910 of file nsXFormsMDGEngine.cpp.

{
  nsresult rv;

  nsCOMPtr<nsIDOMDocument> document;
  rv = aContextNode->GetOwnerDocument(getter_AddRefs(document));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIDOMText> textNode;
  rv = document->CreateTextNode(aNodeValue, getter_AddRefs(textNode));
  NS_ENSURE_SUCCESS(rv, rv);
  
  nsCOMPtr<nsIDOMNode> newNode;
  if (aBeforeNode) {
    rv = aContextNode->InsertBefore(textNode,
                                    aBeforeNode,
                                    getter_AddRefs(newNode));
  } else {
    rv = aContextNode->AppendChild(textNode,
                                   getter_AddRefs(newNode));
  }

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PLDHashOperator nsXFormsMDGEngine::DeleteLinkedNodes ( nsISupports *  aKey,
nsAutoPtr< nsXFormsMDGNode > &  aNode,
void aArg 
) [static, protected]

Used by Clear() and ~ to delete the linked nodes in mNodeToMDG, the hash table itself handles the main nodes.

Definition at line 938 of file nsXFormsMDGEngine.cpp.

{
  if (!aNode) {
    NS_WARNING("nsXFormsMDGEngine::DeleteLinkedNodes() called with aNode == nsnull!");
    return PL_DHASH_STOP;
  }
  nsXFormsMDGNode* temp;
  nsXFormsMDGNode* next = aNode->mNext;
  
  while (next) {
    temp = next;  
    next = next->mNext;
    delete temp;
  }

  return PL_DHASH_NEXT;
}

Here is the caller graph for this function:

Get non-const (NC) node state for a node, create a new node state if necessary.

Parameters:
aContextNodeThe node to get the state for
Returns:
The state (owned by nsXFormsMDGEngine)

Definition at line 885 of file nsXFormsMDGEngine.cpp.

{
  nsXFormsNodeState* ns = nsnull;

  if (aContextNode && !mNodeStates.Get(aContextNode, &ns)) {
    ns = new nsXFormsNodeState(kFlags_DEFAULT |
                               ((mJustRebuilt && mFirstCalculate) ? kFlags_INITIAL_DISPATCH : 0));
    NS_ASSERTION(ns, "Could not create new nsXFormsNodeState");

    if (!mNodeStates.Put(aContextNode, ns)) {
      NS_ERROR("Could not insert new nsXFormsNodeState");
      delete ns;
      return nsnull;
    }    
    aContextNode->AddRef();

    // Do an initial type check, and set the validity state
    PRBool constraint;
    mModel->ValidateNode(aContextNode, &constraint);
    ns->Set(eFlag_CONSTRAINT_SCHEMA, constraint);
  }
  return ns;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsXFormsMDGNode * nsXFormsMDGEngine::GetNode ( nsIDOMNode aDomNode,
ModelItemPropName  aType,
PRBool  aCreate = PR_TRUE 
) [protected]

Retrieve a node from the graph.

Parameters:
aDomNodeThe DOM node to retrieve
aTypeThe type to retrieve (readonly, calculate, etc)
aCreateCreate the node and insert it into the graph if it does not exist?
Returns:
The node, nsnull if not found and aCreate != PR_TRUE
Note:
aType == eModel_type means "any type", as we do not store type information in the MDG.

Definition at line 959 of file nsXFormsMDGEngine.cpp.

{
  nsIDOMNode* nodeKey = aDomNode;
  nsXFormsMDGNode* nd = nsnull;

#ifdef DEBUG_XF_MDG
  printf("nsXFormsMDGEngine::GetNode(aDomNode=%p, aType=%s, aCreate=%d)\n",
         (void*) nodeKey, gMIPNames[aType], aCreate);
#endif
  

  // Find correct type
  if (mNodeToMDG.Get(nodeKey, &nd) && aType != eModel_type) {
    while (nd && aType != nd->mType) {
      nd = nd->mNext;
    }
  } 
  
  // Eventually create node
  if (!nd && aCreate){
    nd = new nsXFormsMDGNode(nodeKey, aType);
    if (!nd) {
      NS_ERROR("Could not allocate room for new nsXFormsMDGNode");
      return nsnull;
    }
    
#ifdef DEBUG_XF_MDG
    printf("\tNode not found, create new MDGNode '%p'\n", (void*) nd);
#endif
    // Link to existing node
    nsXFormsMDGNode* nd_exists;
    if (mNodeToMDG.Get(nodeKey, &nd_exists)) {
      while (nd_exists->mNext) {
        nd_exists = nd_exists->mNext;
      }
#ifdef DEBUG_XF_MDG
      printf("\tLinking to existing MDGNode '%p'\n", (void*) nd_exists);
#endif
      nd_exists->mNext = nd;
    } else {
      if (!mNodeToMDG.Put(nodeKey, nd)) {
        delete nd;
        NS_ERROR("Could not insert new node in HashTable!");
        return nsnull;
      }
      nodeKey->AddRef();
    }

    mNodesInGraph++;
  }
  return nd;
}

Here is the call graph for this function:

Here is the caller graph for this function:

External interface of GetNCNodeState(), returns const pointer to the node state.

Parameters:
aContextNodeThe node to get the state for
Returns:
The state (owned by nsXFormsMDGEngine)

Definition at line 876 of file nsXFormsMDGEngine.cpp.

{
  return GetNCNodeState(aContextNode);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Handle nodes nodes marked as dirty, and insert into "changed nodes array".

Parameters:
aArrayThe "changed nodes array" to insert into

Definition at line 235 of file nsXFormsMDGEngine.cpp.

{
  NS_ENSURE_ARG_POINTER(aArray);

  // Handle nodes marked as changed
  for (PRInt32 i = 0; i < mMarkedNodes.Count(); ++i) {
    nsCOMPtr<nsIDOMNode> node = mMarkedNodes.ObjectAt(i);
    nsXFormsNodeState* ns = GetNCNodeState(node);
    NS_ENSURE_TRUE(ns, NS_ERROR_FAILURE);

    ns->Set(kFlags_ALL_DISPATCH, PR_TRUE);

    // Get the node, eMode_type == get any type of node
    nsXFormsMDGNode* n = GetNode(node, eModel_type, PR_FALSE);
    if (n) {
      while (n) {
        n->MarkDirty();
        n = n->mNext;
      }
    } else {
      // Add constraint to trigger validation of node
      n = GetNode(node, eModel_constraint, PR_TRUE);
      if (!n) {
        return NS_ERROR_OUT_OF_MEMORY;
      }
      n->MarkDirty();
      NS_ENSURE_TRUE(mGraph.AppendElement(n), NS_ERROR_OUT_OF_MEMORY);
    }

    NS_ENSURE_TRUE(aArray->AppendObjects(mMarkedNodes),
                   NS_ERROR_OUT_OF_MEMORY);

  }

  mMarkedNodes.Clear();

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Initializes the internal structures.

Needs to be called before class is used!

Parameters:
aModelThe model that created this MDGEngine instance.

Definition at line 140 of file nsXFormsMDGEngine.cpp.

{
  nsresult rv = NS_ERROR_FAILURE;
  if (mNodeStates.Init() && mNodeToMDG.Init()) {
    rv = NS_OK;
  }

  mModel = aModel;

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Invalidate the information, ie.

mark all nodes as dirty.

Definition at line 1224 of file nsXFormsMDGEngine.cpp.

{
  nsXFormsMDGNode* g;
  for (PRInt32 i = 0; i < mGraph.Count(); ++i) {
    g = NS_STATIC_CAST(nsXFormsMDGNode*, mGraph[i]);
    NS_ENSURE_TRUE(g, NS_ERROR_FAILURE);
    g->MarkDirty();
  }
  return NS_OK;
}

Here is the call graph for this function:

Mark a node as changed.

Parameters:
aContextNodeThe node to be marked.

Definition at line 229 of file nsXFormsMDGEngine.cpp.

{
  return mMarkedNodes.AppendObject(aContextNode);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Rebuilds the MDG.

Definition at line 522 of file nsXFormsMDGEngine.cpp.

{
#ifdef DEBUG_XF_MDG
  printf("nsXFormsMDGEngine::Rebuild()\n");
#endif
  nsresult rv = NS_OK;
  mJustRebuilt = PR_TRUE;
  mFirstCalculate = PR_FALSE;

  mGraph.Clear();
  mNodeStates.Clear();

  nsDeque sortedNodes(nsnull);

#ifdef DEBUG_XF_MDG
  printf("\tmNodesInGraph: %d\n", mNodesInGraph);
  printf("\tmNodeToMDG:    %d\n", mNodeToMDG.Count());
  printf("\tmNodeStates:   %d\n", mNodeStates.Count());
#endif

  // Initial scan for nsXFormsMDGNodes with no dependencies (mCount == 0)
  PRUint32 entries = mNodeToMDG.EnumerateRead(AddStartNodes, &sortedNodes);
  if (entries != mNodeToMDG.Count()) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

#ifdef DEBUG_XF_MDG
  printf("\tStartNodes:    %d\n", sortedNodes.GetSize());
#endif
  
  
  nsXFormsMDGNode* node;
  while ((node = NS_STATIC_CAST(nsXFormsMDGNode*, sortedNodes.Pop()))) {
    for (PRInt32 i = 0; i < node->mSuc.Count(); ++i) {
      nsXFormsMDGNode* sucNode = NS_STATIC_CAST(nsXFormsMDGNode*,
                                                node->mSuc[i]);
      NS_ASSERTION(sucNode, "XForms: NULL successor node");

      sucNode->mCount--;
      if (sucNode->mCount == 0) {
        sortedNodes.Push(sucNode);
      }
    }

    node->MarkDirty();

    if (!mGraph.AppendElement(node)) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }

#ifdef DEBUG_XF_MDG
    printf("\tmGraph.Count() = %2d\n", mGraph.Count());
    printf("\tmNodesInGraph  = %2d\n", mNodesInGraph);
#endif

  if (mGraph.Count() != mNodesInGraph) {
    nsCOMPtr<nsIDOMElement> modelElement;
    if (mModel) {
      modelElement = mModel->GetDOMElement();
    }
    nsXFormsUtils::ReportError(NS_LITERAL_STRING("MDGLoopError"), modelElement);
    rv = NS_ERROR_ABORT;
  }

  mNodesInGraph = 0;

  return rv;
}

Here is the call graph for this function:

Recalculate the MDG.

Parameters:
aChangedNodesReturns the nodes that was changed during recalculation.

Definition at line 321 of file nsXFormsMDGEngine.cpp.

{
  NS_ENSURE_ARG(aChangedNodes);

#ifdef DEBUG_XF_MDG
  printf("nsXFormsMDGEngine::Recalculate(aChangedNodes=|%d|)\n",
         aChangedNodes->Count());
#endif

  // XXX: There's something wrong with the marking of nodes, as we assume that
  // recalculate will always be called first. bug 338146
  nsresult rv = HandleMarkedNodes(aChangedNodes);
  NS_ENSURE_SUCCESS(rv, rv);
  
  PRBool res = PR_TRUE;

  mFirstCalculate = mJustRebuilt;

#ifdef DEBUG_XF_MDG
  printf("\taChangedNodes: %d\n", aChangedNodes->Count());
  printf("\tmNodeToMDG:    %d\n", mNodeToMDG.Count());
  printf("\tmNodeStates:   %d\n", mNodeStates.Count());
  printf("\tGraph nodes:   %d\n", mGraph.Count());
#endif
  
  // Go through all dirty nodes in the graph
  nsXFormsMDGNode* g;
  for (PRInt32 i = 0; i < mGraph.Count(); ++i) {
    g = NS_STATIC_CAST(nsXFormsMDGNode*, mGraph[i]);

    if (!g) {
      NS_WARNING("nsXFormsMDGEngine::Calculate(): Empty node in graph!!!");
      continue;
    }

    NS_ASSERTION(g->mCount == 0,
                 "nsXFormsMDGEngine::Calculate(): Graph node with mCount != 0");

#ifdef DEBUG_XF_MDG
    nsAutoString domNodeName;
    g->mContextNode->GetNodeName(domNodeName);

    printf("\tNode #%d: This=%p, Dirty=%d, DynFunc=%d, Type=%d, Count=%d, Suc=%d, CSize=%d, CPos=%d, Next=%p, HasExpr=%d, domnode=%s\n",
           i, (void*) g, g->IsDirty(), g->mDynFunc, g->mType,
           g->mCount, g->mSuc.Count(), g->mContextSize, g->mContextPosition,
           (void*) g->mNext, g->HasExpr(), NS_ConvertUTF16toUTF8(domNodeName).get());
#endif

    // Ignore node if it is not dirty
    if (!g->IsDirty()) {
      continue;
    }

    nsXFormsNodeState* ns = GetNCNodeState(g->mContextNode);
    NS_ENSURE_TRUE(ns, NS_ERROR_FAILURE);
    
    PRBool constraint = PR_TRUE;
    PRBool conChanged;
    // Find MIP-type and handle it accordingly
    switch (g->mType) {
    case eModel_calculate:
      if (g->HasExpr()) {
        nsCOMPtr<nsIDOMXPathResult> xpath_res;
        rv = g->mExpression->EvaluateWithContext(g->mContextNode,
                                                 g->mContextPosition,
                                                 g->mContextSize,
                                                 nsIDOMXPathResult::STRING_TYPE,
                                                 nsnull,
                                                 getter_AddRefs(xpath_res));
        NS_ENSURE_SUCCESS(rv, rv);
        NS_ENSURE_STATE(xpath_res);
        
        nsAutoString nodeval;
        rv = xpath_res->GetStringValue(nodeval);
        NS_ENSURE_SUCCESS(rv, rv);

        rv = SetNodeValueInternal(g->mContextNode,
                                  nodeval,
                                  PR_FALSE,
                                  PR_TRUE);
        if (NS_SUCCEEDED(rv)) {
          NS_ENSURE_TRUE(aChangedNodes->AppendObject(g->mContextNode),
                         NS_ERROR_FAILURE);
        }

        ns->Set(eFlag_DISPATCH_VALUE_CHANGED, PR_TRUE);
      }

      break;
      
    case eModel_constraint:
      if (g->HasExpr()) {
        rv = BooleanExpression(g, constraint);
        NS_ENSURE_SUCCESS(rv, rv);
      }

      conChanged = ns->IsConstraint() != constraint;
        // On the first calculate after a rebuild (mFirstCalculate) we also
        // add constraints to the set of changed nodes to trigger validation
        // of type information if present.
      if (conChanged || mFirstCalculate) {
        if (conChanged) {
          ns->Set(eFlag_CONSTRAINT, constraint);
          ns->Set(eFlag_DISPATCH_VALID_CHANGED, PR_TRUE);
        }
        NS_ENSURE_TRUE(aChangedNodes->AppendObject(g->mContextNode),
                       NS_ERROR_FAILURE);
      }

      break;

    case eModel_readonly:
      if (g->HasExpr()) {
        rv = ComputeMIPWithInheritance(eFlag_READONLY,
                                       eFlag_DISPATCH_READONLY_CHANGED,
                                       eFlag_INHERITED_READONLY,
                                       g,
                                       aChangedNodes);
        NS_ENSURE_SUCCESS(rv, rv);
      }
      break;
      
    case eModel_relevant:
      if (g->HasExpr()) {
        rv = ComputeMIPWithInheritance(eFlag_RELEVANT,
                                       eFlag_DISPATCH_RELEVANT_CHANGED,
                                       eFlag_INHERITED_RELEVANT,
                                       g,
                                       aChangedNodes);
        NS_ENSURE_SUCCESS(rv, rv);
      }
      break;
      
    case eModel_required:
      if (g->HasExpr()) {
        PRBool didChange;
        rv = ComputeMIP(eFlag_REQUIRED,
                        eFlag_DISPATCH_REQUIRED_CHANGED,
                        g,
                        didChange);
        NS_ENSURE_SUCCESS(rv, rv);
      
        if (didChange) {
          NS_ENSURE_TRUE(aChangedNodes->AppendObject(g->mContextNode),
                         NS_ERROR_FAILURE);
        }
      }
      break;
      
    default:
      NS_ERROR("There was no expression which matched\n");
      res = PR_FALSE;
      break;
    }

    // Mark successors dirty
    nsXFormsMDGNode* sucnode;
    for (PRInt32 j = 0; j < g->mSuc.Count(); ++j) {
      sucnode = NS_STATIC_CAST(nsXFormsMDGNode*, g->mSuc[j]);
      if (!sucnode) {
        NS_ERROR("nsXFormsMDGEngine::Calculate(): Node has NULL successor!");
        return NS_ERROR_FAILURE;
      }
      sucnode->MarkDirty();
    }

    g->MarkClean();
  }
  nsXFormsUtils::MakeUniqueAndSort(aChangedNodes);
  
#ifdef DEBUG_XF_MDG
  printf("\taChangedNodes: %d\n", aChangedNodes->Count());
  printf("\tmNodeToMDG:    %d\n", mNodeToMDG.Count());
  printf("\tmNodeStates:   %d\n", mNodeStates.Count());
  printf("\tGraph nodes:   %d\n", mGraph.Count());
#endif

  return res;
}

Here is the call graph for this function:

Revalidate nodes.

Parameters:
aNodesThe nodes to revalidate

Definition at line 502 of file nsXFormsMDGEngine.cpp.

{
  NS_ENSURE_ARG(aNodes);
  NS_ENSURE_STATE(mModel);

  for (PRInt32 i = 0; i < aNodes->Count(); ++i) {
    nsCOMPtr<nsIDOMNode> node = aNodes->ObjectAt(i);
    nsXFormsNodeState* ns = GetNCNodeState(node);
    PRBool constraint;
    mModel->ValidateNode(node, &constraint);
    if (constraint != ns->IsConstraintSchema()) {
      ns->Set(eFlag_CONSTRAINT_SCHEMA, constraint);
      ns->Set(eFlag_DISPATCH_VALID_CHANGED, PR_TRUE);
    }
  }

  return NS_OK;
}

Here is the call graph for this function:

nsresult nsXFormsMDGEngine::SetNodeContent ( nsIDOMNode aContextNode,
nsIDOMNode aContentEnvelope 
)

Set the contents of a node.

Parameters:
aContextNodeThe node to set the contents of
aContentEnvelopeThe container of the contents that need to be moved under aContextNode
Todo:
Better feedback for readonly nodes? (XXX)

Definition at line 741 of file nsXFormsMDGEngine.cpp.

{
  NS_ENSURE_ARG(aContextNode);
  NS_ENSURE_ARG(aContentEnvelope);

  // ok, this is tricky.  This function will REPLACE the contents of
  // aContextNode with the a clone of the contents of aContentEnvelope.  If
  // aContentEnvelope has no contents, then any contents that aContextNode
  // has will still be removed.  

  const nsXFormsNodeState* ns = GetNodeState(aContextNode);
  NS_ENSURE_TRUE(ns, NS_ERROR_FAILURE);

  // If the node is read-only and not set by a @calculate MIP,
  // ignore the call
  if (ns->IsReadonly()) {
    return NS_OK;
  }

  PRUint16 nodeType;
  nsresult rv = aContextNode->GetNodeType(&nodeType);
  NS_ENSURE_SUCCESS(rv, rv);

  if (nodeType != nsIDOMNode::ELEMENT_NODE) {
    // got to return something pretty unique that we can check down the road in
    // order to dispatch any error events
    return NS_ERROR_DOM_WRONG_TYPE_ERR;
  }

  // Need to determine if the contents of the context node and content envelope
  // are already the same.  If so, we can avoid some unnecessary work.

  PRBool hasChildren1, hasChildren2, contentsEqual = PR_FALSE;
  nsresult rv1 = aContextNode->HasChildNodes(&hasChildren1);
  nsresult rv2 = aContentEnvelope->HasChildNodes(&hasChildren2);
  if (NS_SUCCEEDED(rv1) && NS_SUCCEEDED(rv2) && hasChildren1 == hasChildren2) {
    // First test passed.  Both have the same number of children nodes.
    if (hasChildren1) {
      nsCOMPtr<nsIDOMNodeList> children1, children2;
      PRUint32 childrenLength1, childrenLength2;
  
      rv1 = aContextNode->GetChildNodes(getter_AddRefs(children1));
      rv2 = aContentEnvelope->GetChildNodes(getter_AddRefs(children2));

      if (NS_SUCCEEDED(rv1) && NS_SUCCEEDED(rv2) && children1 && children2) {

        // Both have child nodes.
        rv1 = children1->GetLength(&childrenLength1);
        rv2 = children2->GetLength(&childrenLength2);
        if (NS_SUCCEEDED(rv1) && NS_SUCCEEDED(rv2) && 
            (childrenLength1 == childrenLength2)) {

          // both have the same number of child nodes.  Now checking to see if
          // each of the children are equal.
          for (PRUint32 i = 0; i < childrenLength1; ++i) {
            nsCOMPtr<nsIDOMNode> child1, child2;
      
            rv1 = children1->Item(i, getter_AddRefs(child1));
            rv2 = children2->Item(i, getter_AddRefs(child2));
            if (NS_FAILED(rv1) || NS_FAILED(rv2)) {
              // Unexpected error.  Not as many children in the list as we
              // were told.
              return NS_ERROR_UNEXPECTED;
            }
      
            contentsEqual = nsXFormsUtils::AreNodesEqual(child1, child2, PR_TRUE);
            if (!contentsEqual) {
              break;
            }
          }
        }
      }
    } else {
      // neither have children
      contentsEqual = PR_TRUE;
    }
  }

  if (contentsEqual) {
    return NS_OK;
  }

  // remove any child nodes that aContextNode already contains
  nsCOMPtr<nsIDOMNode> resultNode;
  nsCOMPtr<nsIDOMNodeList> childList;
  rv = aContextNode->GetChildNodes(getter_AddRefs(childList));
  NS_ENSURE_SUCCESS(rv, rv);
  if (childList) {
    PRUint32 length;
    rv = childList->GetLength(&length);
    NS_ENSURE_SUCCESS(rv, rv);

    for (PRInt32 i = length-1; i >= 0; i--) {
      nsCOMPtr<nsIDOMNode> childNode;
      rv = childList->Item(i, getter_AddRefs(childNode));
      NS_ENSURE_SUCCESS(rv, rv);

      rv = aContextNode->RemoveChild(childNode, getter_AddRefs(resultNode));
      NS_ENSURE_SUCCESS(rv, rv);
    }
  }

  // add contents of the envelope under aContextNode
  nsCOMPtr<nsIDOMNode> childNode;
  rv = aContentEnvelope->GetFirstChild(getter_AddRefs(childNode));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIDOMDocument> document;
  rv = aContextNode->GetOwnerDocument(getter_AddRefs(document));
  NS_ENSURE_STATE(document);

  while (childNode) {
    nsCOMPtr<nsIDOMNode> importedNode;
    rv = document->ImportNode(childNode, PR_TRUE, getter_AddRefs(importedNode));
    NS_ENSURE_STATE(importedNode);
    rv = aContextNode->AppendChild(importedNode, getter_AddRefs(resultNode));
    NS_ENSURE_SUCCESS(rv, rv);

    rv = childNode->GetNextSibling(getter_AddRefs(resultNode));
    NS_ENSURE_SUCCESS(rv, rv);

    resultNode.swap(childNode);
  }

  // We already know that the contents have changed.  Mark the node so that
  // a xforms-value-changed can be dispatched.
  MarkNodeAsChanged(aContextNode);

  return NS_OK;
}

Here is the call graph for this function:

nsresult nsXFormsMDGEngine::SetNodeValue ( nsIDOMNode aContextNode,
const nsAString &  aNodeValue,
PRBool aNodeChanged = nsnull 
)

Set the value of a node -- the public version of SetNodeValueInternal().

Parameters:
aContextNodeThe node to set the value for
aNodeValueThe value
aNodeChangedWas node changed?

Definition at line 620 of file nsXFormsMDGEngine.cpp.

{
  return SetNodeValueInternal(aContextNode,
                              aNodeValue,
                              PR_TRUE,
                              PR_FALSE,
                              aNodeChanged);
}

Here is the call graph for this function:

nsresult nsXFormsMDGEngine::SetNodeValueInternal ( nsIDOMNode aContextNode,
const nsAString &  aNodeValue,
PRBool  aMarkNode = PR_TRUE,
PRBool  aIsCalculate = PR_FALSE,
PRBool aNodeChanged = nsnull 
) [protected]

Set the value of a node.

Parameters:
aContextNodeThe node to set the value for
aNodeValueThe value
aMarkNodeWhether to mark node as changed
aNodeChangedWas node changed?
aIsCalculateIs it a setting the value?
Todo:
Better feedback for readonly nodes? (XXX)

Unsupported nodeType

Todo:
Should return more specific error? (XXX)

Definition at line 632 of file nsXFormsMDGEngine.cpp.

{
  if (aNodeChanged) {
    *aNodeChanged = PR_FALSE;
  }

  const nsXFormsNodeState* ns = GetNodeState(aContextNode);
  NS_ENSURE_TRUE(ns, NS_ERROR_FAILURE);

  // If the node is read-only and not set by a @calculate MIP,
  // ignore the call
  if (ns->IsReadonly() && !aIsCalculate) {
    return NS_OK;
  }

  nsCOMPtr<nsIDOMNode> childNode;
  PRUint16 nodeType;
  nsresult rv = aContextNode->GetNodeType(&nodeType);
  NS_ENSURE_SUCCESS(rv, rv);

  nsAutoString oldValue;
  nsXFormsUtils::GetNodeValue(aContextNode, oldValue);
  if (oldValue.Equals(aNodeValue)) {
    return NS_OK;
  }

  switch(nodeType) {
  case nsIDOMNode::ATTRIBUTE_NODE:
  case nsIDOMNode::TEXT_NODE:
  case nsIDOMNode::CDATA_SECTION_NODE:
  case nsIDOMNode::PROCESSING_INSTRUCTION_NODE:
  case nsIDOMNode::COMMENT_NODE:
    rv = aContextNode->SetNodeValue(aNodeValue);
    NS_ENSURE_SUCCESS(rv, rv);

    break;

  case nsIDOMNode::ELEMENT_NODE:

    rv = aContextNode->GetFirstChild(getter_AddRefs(childNode));
    NS_ENSURE_SUCCESS(rv, rv);

    if (!childNode) {
      rv = CreateNewChild(aContextNode, aNodeValue);
      NS_ENSURE_SUCCESS(rv, rv);
    } else {
      PRUint16 childType;
      rv = childNode->GetNodeType(&childType);
      NS_ENSURE_SUCCESS(rv, rv);

      if (childType == nsIDOMNode::TEXT_NODE ||
          childType == nsIDOMNode::CDATA_SECTION_NODE) {
        rv = childNode->SetNodeValue(aNodeValue);
        NS_ENSURE_SUCCESS(rv, rv);

        // Remove all leading text child nodes except first one (see
        // nsXFormsUtils::GetNodeValue method for motivation).
        nsCOMPtr<nsIDOMNode> siblingNode;
        while (true) {
          rv = childNode->GetNextSibling(getter_AddRefs(siblingNode));
          NS_ENSURE_SUCCESS(rv, rv);
          if (!siblingNode)
            break;

          rv = siblingNode->GetNodeType(&childType);
          NS_ENSURE_SUCCESS(rv, rv);
          if (childType != nsIDOMNode::TEXT_NODE &&
              childType != nsIDOMNode::CDATA_SECTION_NODE) {
            break;
          }
          nsCOMPtr<nsIDOMNode> stubNode;
          rv = aContextNode->RemoveChild(siblingNode,
                                         getter_AddRefs(stubNode));
          NS_ENSURE_SUCCESS(rv, rv);
        }
      } else {
        // Not a text child, create a new one
        rv = CreateNewChild(aContextNode, aNodeValue, childNode);
        NS_ENSURE_SUCCESS(rv, rv);
      }
    }

    break;

  default:
    return NS_ERROR_ILLEGAL_VALUE;
    break;
  }
  
  // NB: Never reached for Readonly nodes.  
  if (aNodeChanged) {
    *aNodeChanged = PR_TRUE;
  }
  if (aMarkNode) {
      MarkNodeAsChanged(aContextNode);
  }
  
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Default node state.

Definition at line 165 of file nsXFormsMDGEngine.h.

True when last Calculate() was run when mJustRebuilt was true.

Definition at line 171 of file nsXFormsMDGEngine.h.

The actual MDG.

Definition at line 174 of file nsXFormsMDGEngine.h.

True when Rebuild() has been run, but not ClearDispatchFlags()

Definition at line 168 of file nsXFormsMDGEngine.h.

Nodes that are marked as changed, and should be included in recalculation.

Definition at line 182 of file nsXFormsMDGEngine.h.

The model that created the MDG.

Definition at line 177 of file nsXFormsMDGEngine.h.

Number of nodes in the graph.

Definition at line 185 of file nsXFormsMDGEngine.h.

Maps from nsIDOMNode to nsXFormsNodeState.

Definition at line 162 of file nsXFormsMDGEngine.h.

Maps from nsIDOMNode to nsXFormsMDGNode.

Definition at line 159 of file nsXFormsMDGEngine.h.


The documentation for this class was generated from the following files: