Logo Search packages:      
Sourcecode: xulrunner-1.9 version File versions

nsresult nsGenericElement::BindToTree ( nsIDocument *  aDocument,
nsIContent aParent,
nsIContent aBindingParent,
PRBool  aCompileEventHandlers 
) [virtual]

Bind this content node to a tree. If this method throws, the caller must call UnbindFromTree() on the node. In the typical case of a node being appended to a parent, this will be called after the node has been added to the parent's child list and before nsIDocumentObserver notifications for the addition are dispatched.

aDocument The new document for the content node. Must match the current document of aParent, if aParent is not null. May not be null if aParent is null.
aParent The new parent for the content node. May be null if the node is being bound as a direct child of the document.
aBindingParent The new binding parent for the content node. This is allowed to be null. In that case, the binding parent of aParent, if any, will be used.
aCompileEventHandlers whether to initialize the event handlers in the document (used by nsXULElement)
either aDocument or aParent must be non-null. If both are null, this method _will_ crash.

This method must not be called by consumers of nsIContent on a node that is already bound to a tree. Call UnbindFromTree first.

This method will handle rebinding descendants appropriately (eg changing their binding parent as needed).

This method does not add the content node to aParent's child list

NS_ERROR_OUT_OF_MEMORY if that happens

Implements nsIContent.

Reimplemented in nsGenericHTMLElement, nsGenericHTMLFormElement, and nsGenericHTMLFrameElement.

Definition at line 2007 of file nsGenericElement.cpp.

References nsIContent::BindToTree(), nsIContent::GetBindingParent(), GetBindingParent(), nsINode::GetChildAt(), nsINode::GetCurrentDoc(), nsINode::GetOwnerDoc(), nsINode::GetParent(), nsINode::HasFlag(), nsINode::HasSameOwnerDoc(), nsIContent::IsInNativeAnonymousSubtree(), nsIContent::IsNativeAnonymous(), mAttrsAndChildren, nsGenericElement::nsDOMSlots::mBindingParent, and nsIContent::UpdateEditableState().

  NS_PRECONDITION(aParent || aDocument, "Must have document if no parent!");
  NS_PRECONDITION(HasSameOwnerDoc(NODE_FROM(aParent, aDocument)),
                  "Must have the same owner document");
  NS_PRECONDITION(!aParent || aDocument == aParent->GetCurrentDoc(),
                  "aDocument must be current doc of aParent");
  NS_PRECONDITION(!GetCurrentDoc(), "Already have a document.  Unbind first!");
  // Note that as we recurse into the kids, they'll have a non-null parent.  So
  // only assert if our parent is _changing_ while we have a parent.
  NS_PRECONDITION(!GetParent() || aParent == GetParent(),
                  "Already have a parent.  Unbind first!");
  NS_PRECONDITION(!GetBindingParent() ||
                  aBindingParent == GetBindingParent() ||
                  (!aBindingParent && aParent &&
                   aParent->GetBindingParent() == GetBindingParent()),
                  "Already have a binding parent.  Unbind first!");
  NS_PRECONDITION(!aParent || !aDocument ||
                  "Parent in document but flagged as forcing XBL");
  NS_PRECONDITION(aBindingParent != this || IsNativeAnonymous(),
                  "Only native anonymous content should have itself as its "
                  "own binding parent");
  NS_PRECONDITION(!IsNativeAnonymous() || aBindingParent == this,
                  "Native anonymous content must have itself as its "
                  "own binding parent");

  if (!aBindingParent && aParent) {
    aBindingParent = aParent->GetBindingParent();

#ifdef MOZ_XUL
  // First set the binding parent
  nsXULElement* xulElem = nsXULElement::FromContent(this);
  if (xulElem) {
    if (aBindingParent) {
      nsDOMSlots *slots = GetDOMSlots();

      if (!slots) {
        return NS_ERROR_OUT_OF_MEMORY;

      slots->mBindingParent = aBindingParent; // Weak, so no addref happens.
  NS_ASSERTION(!aBindingParent || IsNativeAnonymous() ||
               !HasFlag(NODE_IS_IN_ANONYMOUS_SUBTREE) ||
               "Trying to re-bind content from native anonymous subtree to"
               "non-native anonymous parent!");
  if (IsNativeAnonymous() ||
      aBindingParent && aBindingParent->IsInNativeAnonymousSubtree()) {


  // Now set the parent and set the "Force attach xbl" flag if needed.
  if (aParent) {
    mParentPtrBits = reinterpret_cast<PtrBits>(aParent) | PARENT_BIT_PARENT_IS_CONTENT;

    if (aParent->HasFlag(NODE_FORCE_XBL_BINDINGS)) {
  else {
    mParentPtrBits = reinterpret_cast<PtrBits>(aDocument);

  // XXXbz sXBL/XBL2 issue!

  // Finally, set the document
  if (aDocument) {
    // Notify XBL- & nsIAnonymousContentCreator-generated
    // anonymous content that the document is changing.
    // XXXbz ordering issues here?  Probably not, since ChangeDocumentFor is
    // just pretty broken anyway....  Need to get it working.
    // XXXbz XBL doesn't handle this (asserts), and we don't really want
    // to be doing this during parsing anyway... sort this out.    
    //    aDocument->BindingManager()->ChangeDocumentFor(this, nsnull,
    //                                                   aDocument);

    // Being added to a document.
    mParentPtrBits |= PARENT_BIT_INDOCUMENT;

    // Unset this flag since we now really are in a document.

  // If NODE_FORCE_XBL_BINDINGS was set we might have anonymous children
  // that also need to be told that they are moving.
  nsresult rv;
  if (hadForceXBL) {
    nsIDocument* ownerDoc = GetOwnerDoc();
    if (ownerDoc) {
      nsBindingManager* bmgr = ownerDoc->BindingManager();

      // First check if we have a binding...
      nsXBLBinding* contBinding =
        GetFirstBindingWithContent(bmgr, this);
      if (contBinding) {
        nsCOMPtr<nsIContent> anonRoot = contBinding->GetAnonymousContent();
        PRBool allowScripts = contBinding->AllowScripts();
        PRUint32 i;
        for (i = 0; i < anonRoot->GetChildCount(); ++i) {
          nsCOMPtr<nsIContent> child = anonRoot->GetChildAt(i);
          rv = child->BindToTree(aDocument, this, this, allowScripts);
          NS_ENSURE_SUCCESS(rv, rv);

        // ...then check if we have content in insertion points that are
        // direct children of the <content>
        rv = BindNodesInInsertPoints(contBinding, this, aDocument);
        NS_ENSURE_SUCCESS(rv, rv);

      // ...and finally check if we're in a binding where we have content in
      // insertion points.
      if (aBindingParent) {
        nsXBLBinding* binding = bmgr->GetBinding(aBindingParent);
        if (binding) {
          rv = BindNodesInInsertPoints(binding, this, aDocument);
          NS_ENSURE_SUCCESS(rv, rv);


  // Now recurse into our kids
  PRUint32 i;
  // Don't call GetChildCount() here since that'll make XUL generate
  // template children, which we're not in a consistent enough state for.
  // Additionally, there's not really a need to generate the children here.
  for (i = 0; i < mAttrsAndChildren.ChildCount(); ++i) {
    // The child can remove itself from the parent in BindToTree.
    nsCOMPtr<nsIContent> child = mAttrsAndChildren.ChildAt(i);
    rv = child->BindToTree(aDocument, this, aBindingParent,
    NS_ENSURE_SUCCESS(rv, rv);


  // XXXbz script execution during binding can trigger some of these
  // postcondition asserts....  But we do want that, since things will
  // generally be quite broken when that happens.
  NS_POSTCONDITION(aDocument == GetCurrentDoc(), "Bound to wrong document");
  NS_POSTCONDITION(aParent == GetParent(), "Bound to wrong parent");
  NS_POSTCONDITION(aBindingParent == GetBindingParent(),
                   "Bound to wrong binding parent");

  return NS_OK;

Generated by  Doxygen 1.6.0   Back to index