inputString.ReplaceSubstring(NS_LITERAL_STRING("\r\n").get(), NS_LITERAL_STRING("\n").get());
inputString.ReplaceSubstring(NS_ConvertASCIItoUCS2("\r\n"), NS_ConvertASCIItoUCS2("\n"));
nsresult nsHTMLEditor::InsertHTMLWithCharsetAndContext(const nsAReadableString & aInputString,                                                       const nsAReadableString & aCharset,                                                       const nsAReadableString & aContextStr,                                                       const nsAReadableString & aInfoStr){  if (!mRules) return NS_ERROR_NOT_INITIALIZED;/* all this is unneeded: parser handles this for us  // First, make sure there are no return chars in the document.  // Bad things happen if you insert returns (instead of dom newlines, \n)  // into an editor document.  nsAutoString inputString (aInputString);  // hope this does copy-on-write  // Windows linebreaks: Map CRLF to LF:  inputString.ReplaceSubstring(NS_LITERAL_STRING("\r\n").get(),                               NS_LITERAL_STRING("\n").get());   // Mac linebreaks: Map any remaining CR to LF:  inputString.ReplaceSubstring(NS_LITERAL_STRING("\r").get(),                               NS_LITERAL_STRING("\n").get());*/  // force IME commit; set up rules sniffing and batching  ForceCompositionEnd();  nsAutoEditBatch beginBatching(this);  nsAutoRules beginRulesSniffing(this, kOpHTMLPaste, nsIEditor::eNext);    // Get selection  nsresult res;  nsCOMPtr<nsISelection>selection;  res = GetSelection(getter_AddRefs(selection));  if (NS_FAILED(res)) return res;    // Get the first range in the selection, for context:  nsCOMPtr<nsIDOMRange> range, clone;  res = selection->GetRangeAt(0, getter_AddRefs(range));  NS_ENSURE_SUCCESS(res, res);  res = range->CloneRange(getter_AddRefs(clone));  NS_ENSURE_SUCCESS(res, res);  nsCOMPtr<nsIDOMNSRange> nsrange (do_QueryInterface(clone));  if (!nsrange)    return NS_ERROR_NO_INTERFACE;  // create a dom document fragment that represents the structure to paste  nsCOMPtr<nsIDOMNode> fragmentAsNode;  PRInt32 rangeStartHint, rangeEndHint;  res = CreateDOMFragmentFromPaste(nsrange, aInputString, aContextStr, aInfoStr,                                             address_of(fragmentAsNode),                                            &rangeStartHint, &rangeEndHint);  NS_ENSURE_SUCCESS(res, res);  // make a list of what nodes in docFrag we need to move  nsCOMPtr<nsISupportsArray> nodeList;  res = CreateListOfNodesToPaste(fragmentAsNode, address_of(nodeList), rangeStartHint, rangeEndHint);  NS_ENSURE_SUCCESS(res, res);    PRUint32 cc;  nodeList->Count(&cc);    // are there any table elements in the list?    // node and offset for insertion  nsCOMPtr<nsIDOMNode> parentNode;  PRInt32 offsetOfNewNode;    // check for table cell selection mode  PRBool cellSelectionMode = PR_FALSE;  nsCOMPtr<nsIDOMElement> cell;  res = GetFirstSelectedCell(getter_AddRefs(cell), nsnull);  if (NS_SUCCEEDED(res) && cell)  {    cellSelectionMode = PR_TRUE;  }    if (cellSelectionMode)  {    // do we have table content to paste?  If so, we want to delete    // the selected table cells and replace with new table elements;    // but if not we want to delete _contents_ of cells and replace    // with non-table elements.  Use cellSelectionMode bool to     // indicate results.    nsCOMPtr<nsISupports> isupports = dont_AddRef(nodeList->ElementAt(0));    nsCOMPtr<nsIDOMNode> firstNode( do_QueryInterface(isupports) );    if (!nsHTMLEditUtils::IsTableElement(firstNode))      cellSelectionMode = PR_FALSE;  }  if (!cellSelectionMode)  {    res = DeleteSelectionAndPrepareToCreateNode(parentNode, offsetOfNewNode);    NS_ENSURE_SUCCESS(res, res);    // pasting does not inherit local inline styles    res = RemoveAllInlineProperties();    NS_ENSURE_SUCCESS(res, res);  }  else  {    // delete whole cells: we will replace with new table content    if (1)    {      // Save current selection since DeleteTableCell perturbs it      nsAutoSelectionReset selectionResetter(selection, this);      res = DeleteTableCell(1);      NS_ENSURE_SUCCESS(res, res);    }    // colapse selection to beginning of deleted table content    selection->CollapseToStart();  }    // give rules a chance to handle or cancel  nsTextRulesInfo ruleInfo(nsTextEditRules::kInsertElement);  PRBool cancel, handled;  res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);  if (NS_FAILED(res)) return res;  if (cancel) return NS_OK; // rules canceled the operation  if (!handled)  {    // The rules code (WillDoAction above) might have changed the selection.      // refresh our memory...    res = GetStartNodeAndOffset(selection, address_of(parentNode), &offsetOfNewNode);    if (!parentNode) res = NS_ERROR_FAILURE;    if (NS_FAILED(res)) return res;        // are we in a text node?  If so, split it.    if (IsTextNode(parentNode))    {      nsCOMPtr<nsIDOMNode> temp;      res = SplitNodeDeep(parentNode, parentNode, offsetOfNewNode, &offsetOfNewNode);      if (NS_FAILED(res)) return res;      res = parentNode->GetParentNode(getter_AddRefs(temp));      if (NS_FAILED(res)) return res;      parentNode = temp;    }    // build up list of parents of first node in list that are either    // lists or tables.  First examine front of paste node list.    nsCOMPtr<nsISupportsArray> startListAndTableArray;    res = GetListAndTableParents(PR_FALSE, nodeList, address_of(startListAndTableArray));    NS_ENSURE_SUCCESS(res, res);        // remember number of lists and tables above us    PRInt32 highWaterMark = -1;    if (startListAndTableArray->ElementAt(0))    {      res = DiscoverPartialListsAndTables(nodeList, startListAndTableArray, &highWaterMark);      NS_ENSURE_SUCCESS(res, res);    }    // if we have pieces of tables or lists to be inserted, let's force the paste     // to deal with table elements right away, so that it doesn't orphan some     // table or list contents outside the table or list.    if (highWaterMark >= 0)    {      res = ReplaceOrphanedStructure(PR_FALSE, nodeList, startListAndTableArray, highWaterMark);      NS_ENSURE_SUCCESS(res, res);    }        // Now go through the same process again for the end of the paste node list.    nsCOMPtr<nsISupportsArray> endListAndTableArray;    res = GetListAndTableParents(PR_TRUE, nodeList, address_of(endListAndTableArray));    NS_ENSURE_SUCCESS(res, res);    highWaterMark = -1;       // remember number of lists and tables above us    if (endListAndTableArray->ElementAt(0))    {      res = DiscoverPartialListsAndTables(nodeList, endListAndTableArray, &highWaterMark);      NS_ENSURE_SUCCESS(res, res);    }        // don't orphan partial list or table structure    if (highWaterMark >= 0)    {      res = ReplaceOrphanedStructure(PR_TRUE, nodeList, endListAndTableArray, highWaterMark);      NS_ENSURE_SUCCESS(res, res);    }    // Loop over the node list and paste the nodes:    PRBool bDidInsert = PR_FALSE;    nsCOMPtr<nsIDOMNode> parentBlock, lastInsertNode, insertedContextParent;    PRUint32 listCount, j;    nodeList->Count(&listCount);    if (IsBlockNode(parentNode))      parentBlock = parentNode;    else      parentBlock = GetBlockNodeParent(parentNode);          for (j=0; j<listCount; j++)    {      nsCOMPtr<nsISupports> isupports = dont_AddRef(nodeList->ElementAt(j));      nsCOMPtr<nsIDOMNode> curNode( do_QueryInterface(isupports) );      nsString namestr;      curNode->GetNodeName(namestr);      NS_ENSURE_TRUE(curNode, NS_ERROR_FAILURE);      NS_ENSURE_TRUE(curNode != fragmentAsNode, NS_ERROR_FAILURE);      NS_ENSURE_TRUE(!nsTextEditUtils::IsBody(curNode), NS_ERROR_FAILURE);            if (insertedContextParent)      {        // if we had to insert something higher up in the paste heirarchy, we want to         // skip any further paste nodes that descend from that.  Else we will paste twice.        if (nsHTMLEditUtils::IsDescendantOf(curNode, insertedContextParent))          continue;      }            // give the user a hand on table element insertion.  if they have      // a table or table row on the clipboard, and are trying to insert      // into a table or table row, insert the appropriate children instead.      if (  (nsHTMLEditUtils::IsTableRow(curNode) && nsHTMLEditUtils::IsTableRow(parentNode))         && (nsHTMLEditUtils::IsTable(curNode)    || nsHTMLEditUtils::IsTable(parentNode)) )      {        nsCOMPtr<nsIDOMNode> child;        curNode->GetFirstChild(getter_AddRefs(child));        while (child)        {          res = InsertNodeAtPoint(child, address_of(parentNode), &offsetOfNewNode, PR_TRUE);          if (NS_SUCCEEDED(res))           {            bDidInsert = PR_TRUE;            lastInsertNode = child;            offsetOfNewNode++;          }          curNode->GetFirstChild(getter_AddRefs(child));        }      }      // give the user a hand on list insertion.  if they have      // a list on the clipboard, and are trying to insert      // into a list or list item, insert the appropriate children instead,      // ie, merge the lists instead of pasting in a sublist.      else if (nsHTMLEditUtils::IsList(curNode) &&               (nsHTMLEditUtils::IsList(parentNode)  || nsHTMLEditUtils::IsListItem(parentNode)) )      {        nsCOMPtr<nsIDOMNode> child, tmp;        curNode->GetFirstChild(getter_AddRefs(child));        while (child)        {          if (nsHTMLEditUtils::IsListItem(child) || nsHTMLEditUtils::IsList(child))          {            // check if we are pasting into empty list item. If so            // delete it and paste into parent list instead.            if (nsHTMLEditUtils::IsListItem(parentNode))            {              PRBool isEmpty;              res = IsEmptyNode(parentNode, &isEmpty, PR_TRUE);              if ((NS_SUCCEEDED(res)) && isEmpty)              {                nsCOMPtr<nsIDOMNode> listNode;                PRInt32 newOffset;                GetNodeLocation(parentNode, address_of(listNode), &newOffset);                if (listNode)                {                  DeleteNode(parentNode);                  parentNode = listNode;                  offsetOfNewNode = newOffset;                }              }            }             res = InsertNodeAtPoint(child, address_of(parentNode), &offsetOfNewNode, PR_TRUE);            if (NS_SUCCEEDED(res))             {              bDidInsert = PR_TRUE;              lastInsertNode = child;              offsetOfNewNode++;            }          }          else          {            curNode->RemoveChild(child, getter_AddRefs(tmp));          }          curNode->GetFirstChild(getter_AddRefs(child));        }              }      // check for pre's going into pre's.        else if (nsHTMLEditUtils::IsPre(parentBlock) && nsHTMLEditUtils::IsPre(curNode))      {        nsCOMPtr<nsIDOMNode> child, tmp;        curNode->GetFirstChild(getter_AddRefs(child));        while (child)        {          res = InsertNodeAtPoint(child, address_of(parentNode), &offsetOfNewNode, PR_TRUE);          if (NS_SUCCEEDED(res))           {            bDidInsert = PR_TRUE;            lastInsertNode = child;            offsetOfNewNode++;          }          curNode->GetFirstChild(getter_AddRefs(child));        }      }      else      {                // try to insert        res = InsertNodeAtPoint(curNode, address_of(parentNode), &offsetOfNewNode, PR_TRUE);        if (NS_SUCCEEDED(res))         {          bDidInsert = PR_TRUE;          lastInsertNode = curNode;        }                  // assume failure means no legal parent in the document heirarchy.        // try again with the parent of curNode in the paste heirarchy.        nsCOMPtr<nsIDOMNode> parent;        while (NS_FAILED(res) && curNode)        {          curNode->GetParentNode(getter_AddRefs(parent));          if (parent && !nsTextEditUtils::IsBody(parent))          {            res = InsertNodeAtPoint(parent, address_of(parentNode), &offsetOfNewNode, PR_TRUE);            if (NS_SUCCEEDED(res))             {              bDidInsert = PR_TRUE;              insertedContextParent = parent;              lastInsertNode = parent;            }          }          curNode = parent;        }      }      if (bDidInsert)      {        res = GetNodeLocation(lastInsertNode, address_of(parentNode), &offsetOfNewNode);        NS_ENSURE_SUCCESS(res, res);        offsetOfNewNode++;      }    }    // Now collapse the selection to the end of what we just inserted:    if (lastInsertNode)     {      res = GetNodeLocation(lastInsertNode, address_of(parentNode), &offsetOfNewNode);      NS_ENSURE_SUCCESS(res, res);      selection->Collapse(parentNode, offsetOfNewNode+1);    }  }    res = mRules->DidDoAction(selection, &ruleInfo, res);  return res;}