nsTextRulesInfo ruleInfo(nsHTMLEditRules::kInsertElement);
nsTextRulesInfo ruleInfo(nsTextEditRules::kInsertElement);
nsHTMLEditor::InsertElementAtSelection(nsIDOMElement* aElement, PRBool aDeleteSelection){  nsresult res = NS_ERROR_NOT_INITIALIZED;    if (!aElement)    return NS_ERROR_NULL_POINTER;    ForceCompositionEnd();  nsAutoEditBatch beginBatching(this);  nsAutoRules beginRulesSniffing(this, kOpInsertElement, nsIEditor::eNext);  nsCOMPtr<nsIDOMSelection>selection;  res = GetSelection(getter_AddRefs(selection));  if (!NS_SUCCEEDED(res) || !selection)    return NS_ERROR_FAILURE;  // hand off to the rules system, see if it has anything to say about this  PRBool cancel, handled;  nsTextRulesInfo ruleInfo(nsHTMLEditRules::kInsertElement);  ruleInfo.insertElement = aElement;  res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);  if (cancel || (NS_FAILED(res))) return res;  if (!handled)  {    if (aDeleteSelection)    {      nsCOMPtr<nsIDOMNode> tempNode;      PRInt32 tempOffset;      nsresult result = DeleteSelectionAndPrepareToCreateNode(tempNode,tempOffset);      if (!NS_SUCCEEDED(result))        return result;    }    // If deleting, selection will be collapsed.    // so if not, we collapse it    if (!aDeleteSelection)    {      // Named Anchor is a special case,      // We collapse to insert element BEFORE the selection      // For all other tags, we insert AFTER the selection      nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aElement);      if (IsNamedAnchorNode(node))      {        selection->CollapseToStart();      } else {        selection->CollapseToEnd();      }    }    nsCOMPtr<nsIDOMNode> parentSelectedNode;    PRInt32 offsetForInsert;    res = selection->GetAnchorNode(getter_AddRefs(parentSelectedNode));    // XXX: ERROR_HANDLING bad XPCOM usage    if (NS_SUCCEEDED(res) && NS_SUCCEEDED(selection->GetAnchorOffset(&offsetForInsert)) && parentSelectedNode)    {#ifdef DEBUG_cmanske      {      nsAutoString name;      parentSelectedNode->GetNodeName(name);      printf("InsertElement: Anchor node of selection: ");      wprintf(name.GetUnicode());      printf(" Offset: %d\n", offsetForInsert);      }#endif      nsAutoString tagName;      aElement->GetNodeName(tagName);      tagName.ToLowerCase();      nsCOMPtr<nsIDOMNode> parent = parentSelectedNode;      nsCOMPtr<nsIDOMNode> topChild = parentSelectedNode;      nsCOMPtr<nsIDOMNode> tmp;      nsAutoString parentTagName;      PRBool isRoot;      // Search up the parent chain to find a suitable container            while (!CanContainTag(parent, tagName))      {        // If the current parent is a root (body or table cell)        // then go no further - we can't insert        parent->GetNodeName(parentTagName);        res = IsRootTag(parentTagName, isRoot);        if (!NS_SUCCEEDED(res) || isRoot)          return NS_ERROR_FAILURE;        // Get the next parent        parent->GetParentNode(getter_AddRefs(tmp));        if (!tmp)          return NS_ERROR_FAILURE;        topChild = parent;        parent = tmp;      }#ifdef DEBUG_cmanske      {        nsAutoString name;        parent->GetNodeName(name);        printf("Parent node to insert under: ");        wprintf(name.GetUnicode());        printf("\n");        topChild->GetNodeName(name);        printf("TopChild to split: ");        wprintf(name.GetUnicode());        printf("\n");      }#endif      if (parent != topChild)      {        // we need to split some levels above the original selection parent        res = SplitNodeDeep(topChild, parentSelectedNode, offsetForInsert, &offsetForInsert);        if (NS_FAILED(res))          return res;      }      // Now we can insert the new node      res = InsertNode(aElement, parent, offsetForInsert);      // Set caret after element, but check for special case       //  of inserting table-related elements: set in first cell instead      if (!SetCaretInTableCell(aElement))        res = SetCaretAfterElement(aElement);    }  }  res = mRules->DidDoAction(selection, &ruleInfo, res);  return res;}