if (! parent) { NS_ERROR("parent doesn't support nsIContent"); return NS_ERROR_UNEXPECTED; }
NS_ASSERTION(parent != nsnull, "parent doesn't support nsIContent"); if (! parent) return NS_ERROR_UNEXPECTED;
RDFTreeBuilderImpl::OnRemoveChild(nsIDOMNode* aParent, nsIDOMNode* aOldChild){    NS_PRECONDITION(aParent != nsnull, "null ptr");    if (!aParent)        return NS_ERROR_NULL_POINTER;    NS_PRECONDITION(aOldChild != nsnull, "null ptr");    if (!aOldChild)        return NS_ERROR_NULL_POINTER;    nsresult rv;    nsCOMPtr<nsIRDFResource> resource;    if (NS_FAILED(rv = GetDOMNodeResource(aParent, getter_AddRefs(resource)))) {        // XXX it's not a resource element, so there's no assertions        // we need to make on the back-end. Should we just do the        // update?        return NS_OK;    }    // Get the nsIContent interface, it's a bit more utilitarian    nsCOMPtr<nsIContent> parent( do_QueryInterface(aParent) );    if (! parent) {        NS_ERROR("parent doesn't support nsIContent");        return NS_ERROR_UNEXPECTED;    }    // Make sure that the element is in the widget. XXX Even this may be    // a bit too promiscuous: an element may also be a XUL element...    if (!IsElementInWidget(parent))        return NS_OK;    // Split the parent into its namespace and tag components    PRInt32 parentNameSpaceID;    if (NS_FAILED(rv = parent->GetNameSpaceID(parentNameSpaceID))) {        NS_ERROR("unable to get parent namespace ID");        return rv;    }    nsCOMPtr<nsIAtom> parentNameAtom;    if (NS_FAILED(rv = parent->GetTag( *getter_AddRefs(parentNameAtom) ))) {        NS_ERROR("unable to get parent tag");        return rv;    }    // Now do the same for the child    nsCOMPtr<nsIContent> child( do_QueryInterface(aOldChild) );    if (! child) {        NS_ERROR("child doesn't support nsIContent");        return NS_ERROR_UNEXPECTED;    }    PRInt32 childNameSpaceID;    if (NS_FAILED(rv = child->GetNameSpaceID(childNameSpaceID))) {        NS_ERROR("unable to get child's namespace ID");        return rv;    }    nsCOMPtr<nsIAtom> childNameAtom;    if (NS_FAILED(rv = child->GetTag( *getter_AddRefs(childNameAtom) ))) {        NS_ERROR("unable to get child's tag");        return rv;    }    // Now see if there's anything we can do about it.    if ((parentNameSpaceID == kNameSpaceID_XUL) &&        ((parentNameAtom.get() == kTreeChildrenAtom) ||         (parentNameAtom.get() == kTreeBodyAtom))) {        // The parent is a xul:treechildren or xul:treebody...        if ((childNameSpaceID == kNameSpaceID_XUL) &&            (childNameAtom.get() == kTreeItemAtom)) {            // ...and the child is a tree item. We can do this. First,            // get the rdf:property out of the child to see what the            // relationship was between the parent and the child.            nsAutoString propertyStr;            if  (NS_FAILED(rv = child->GetAttribute(kNameSpaceID_RDF, kPropertyAtom, propertyStr))) {                NS_ERROR("severe error trying to retrieve attribute");                return rv;            }            if (rv == NS_CONTENT_ATTR_HAS_VALUE) {                // It's a relationship set up by RDF. So let's                // unassert it from the graph. First we need the                // property resource.                nsCOMPtr<nsIRDFResource> property;                if (NS_FAILED(gRDFService->GetUnicodeResource(propertyStr, getter_AddRefs(property)))) {                    NS_ERROR("unable to construct resource for property");                    return rv;                }                // And now we need the child's resource.                nsCOMPtr<nsIRDFResource> target;                if (NS_FAILED(rv = GetElementResource(child, getter_AddRefs(target)))) {                    NS_ERROR("expected child to have resource");                    return rv;                }                // We'll handle things a bit differently if we're                // tinkering with an RDF container...                if (rdf_IsContainer(mDB, resource) &&                    rdf_IsOrdinalProperty(property)) {                    rv = rdf_ContainerRemoveElement(mDB, resource, target);                }                else {                    rv = mDB->Unassert(resource, property, target);                }                if (NS_FAILED(rv)) {                    NS_ERROR("unable to remove element from DB");                    return rv;                }            }            else {                // It's a random (non-RDF inserted) element. Just use                // the content interface to remove it.                PRInt32 index;                if (NS_FAILED(rv = parent->IndexOf(child, index))) {                    NS_ERROR("unable to get index of child in parent node");                    return rv;                }                NS_ASSERTION(index >= 0, "child was already removed");                if (index >= 0) {                    rv = parent->RemoveChildAt(index, PR_TRUE);                    NS_ASSERTION(NS_SUCCEEDED(rv), "error removing child from parent");                }            }        }    }    else if ((parentNameSpaceID == kNameSpaceID_XUL) &&             (parentNameAtom.get() == kTreeItemAtom)) {        // The parent is a xul:treeitem. We really only care about        // treeitems in the body; not treeitems in the header...        NS_NOTYETIMPLEMENTED("write me");    }    else if ((parentNameSpaceID == kNameSpaceID_XUL) &&             (parentNameAtom.get() == kTreeCellAtom)) {        // The parent is a xul:treecell. We really only care about        // cells in the body; not cells in the header...        NS_NOTYETIMPLEMENTED("write me");    }    // they're trying to manipulate the DOM in some way that we don't    // care about: we should probably just call through and do the    // operation on nsIContent, but...let the XUL builder do that I    // guess.    return NS_OK;}