nsresult rv;    nsAutoString tmplID; rv = aChild->GetAttribute(kNameSpaceID_None, nsXULAtoms::Template, tmplID); if (rv != NS_CONTENT_ATTR_HAS_VALUE) return PR_FALSE;    nsCOMPtr<nsIDOMXULDocument> xuldoc( do_QueryInterface(mDocument) ); NS_ASSERTION(xuldoc != nsnull, "not an nsIDOMXULDocument"); if (! xuldoc) return PR_FALSE;  nsCOMPtr<nsIDOMElement> tmplele; xuldoc->GetElementById(tmplID, getter_AddRefs(tmplele)); NS_ASSERTION(tmplele != nsnull, "couldn't find template element"); if (! tmplele) return PR_FALSE;  nsCOMPtr<nsIContent> tmpl( do_QueryInterface(tmplele) ); NS_ASSERTION(tmpl != nsnull, "not an nsIContent");
nsCOMPtr<nsIContent> tmpl; mTemplateMap.GetTemplateFor(aChild, getter_AddRefs(tmpl));
nsXULTemplateBuilder::IsDirectlyContainedBy(nsIContent* aChild, nsIContent* aParent){    // This routine uses the <template> to determine if aChild is    // "directly contained by" aParent. It does so by walking up the    // template subtree in parallel with the generated subtree.    NS_PRECONDITION(aChild != nsnull, "null ptr");    if (! aChild)        return PR_FALSE;    nsresult rv;    // Every generated element has a "template" attribute that gives    // us the ID of the template node that it was created from.    nsAutoString tmplID;    rv = aChild->GetAttribute(kNameSpaceID_None, nsXULAtoms::Template, tmplID);    if (rv != NS_CONTENT_ATTR_HAS_VALUE)        return PR_FALSE;    // We've got the template ID; find the element in the content    // model.    nsCOMPtr<nsIDOMXULDocument> xuldoc( do_QueryInterface(mDocument) );    NS_ASSERTION(xuldoc != nsnull, "not an nsIDOMXULDocument");    if (! xuldoc)        return PR_FALSE;    nsCOMPtr<nsIDOMElement> tmplele;    xuldoc->GetElementById(tmplID, getter_AddRefs(tmplele));    NS_ASSERTION(tmplele != nsnull, "couldn't find template element");    if (! tmplele)        return PR_FALSE;    nsCOMPtr<nsIContent> tmpl( do_QueryInterface(tmplele) );    NS_ASSERTION(tmpl != nsnull, "not an nsIContent");    if (! tmpl)        return PR_FALSE;    // Now walk up the template subtree in parallel with the generated    // subtree.    nsCOMPtr<nsIAtom> tag;    nsCOMPtr<nsIContent> generated(aChild);    do {        // Walk up the generated tree        nsCOMPtr<nsIContent> generatedParent;        generated->GetParent(*getter_AddRefs(generatedParent));        if (! generatedParent)            return PR_FALSE;        generated = generatedParent;        // Walk up the template tree        nsCOMPtr<nsIContent> tmplParent;        tmpl->GetParent(*getter_AddRefs(tmplParent));        if (! tmplParent)            return PR_FALSE;        tmpl = tmplParent;        // The content within a template ends when we hit the        // <template> or <rule> element in the simple syntax, or the        // <action> element in the extended syntax.        tmpl->GetTag(*getter_AddRefs(tag));    } while (tag.get() != nsXULAtoms::Template &&             tag.get() != nsXULAtoms::rule &&             tag.get() != nsXULAtoms::action);    // Did we find the generated parent?    return PRBool(generated.get() == aParent);}