forked from mirrors/gecko-dev
		
	Rolling in the last of the NOXIF changes from the Netscape 6 branch, code mostly written by jfrancis. Fixes bugs 50742, 55806, 56000 and 55669. sr=kin, scc. r=kandrot, jst.
This commit is contained in:
		
							parent
							
								
									292cb40883
								
							
						
					
					
						commit
						17691505d4
					
				
					 14 changed files with 774 additions and 415 deletions
				
			
		| 
						 | 
					@ -84,8 +84,8 @@ public:
 | 
				
			||||||
    // (Probably not well tested for HTML output.)
 | 
					    // (Probably not well tested for HTML output.)
 | 
				
			||||||
    OutputFormatted     = 2,
 | 
					    OutputFormatted     = 2,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // OutputNoDoctype is obsolete, flag 4 available for other uses
 | 
					    // OutputRaw is used by copying text from widgets
 | 
				
			||||||
    //OutputNoDoctype     = 4,
 | 
					    OutputRaw           = 4,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // No html head tags
 | 
					    // No html head tags
 | 
				
			||||||
    OutputBodyOnly      = 8,
 | 
					    OutputBodyOnly      = 8,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,7 @@
 | 
				
			||||||
#include "nsIComponentManager.h" 
 | 
					#include "nsIComponentManager.h" 
 | 
				
			||||||
#include "nsIServiceManager.h"
 | 
					#include "nsIServiceManager.h"
 | 
				
			||||||
#include "nsIDocument.h"
 | 
					#include "nsIDocument.h"
 | 
				
			||||||
 | 
					#include "nsIHTMLDocument.h"
 | 
				
			||||||
#include "nsISelection.h"
 | 
					#include "nsISelection.h"
 | 
				
			||||||
#include "nsCOMPtr.h"
 | 
					#include "nsCOMPtr.h"
 | 
				
			||||||
#include "nsIContentSerializer.h"
 | 
					#include "nsIContentSerializer.h"
 | 
				
			||||||
| 
						 | 
					@ -48,6 +49,7 @@
 | 
				
			||||||
#include "nsITextContent.h"
 | 
					#include "nsITextContent.h"
 | 
				
			||||||
#include "nsIEnumerator.h"
 | 
					#include "nsIEnumerator.h"
 | 
				
			||||||
#include "nsISelectionPrivate.h"
 | 
					#include "nsISelectionPrivate.h"
 | 
				
			||||||
 | 
					#include "nsIFrameSelection.h"
 | 
				
			||||||
#include "nsIContentIterator.h"
 | 
					#include "nsIContentIterator.h"
 | 
				
			||||||
#include "nsISupportsArray.h"
 | 
					#include "nsISupportsArray.h"
 | 
				
			||||||
#include "nsIParserService.h"
 | 
					#include "nsIParserService.h"
 | 
				
			||||||
| 
						 | 
					@ -58,6 +60,7 @@ static NS_DEFINE_CID(kCharsetConverterManagerCID,
 | 
				
			||||||
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
 | 
					static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
nsresult NS_NewContentSubtreeIterator(nsIContentIterator** aInstancePtrResult);
 | 
					nsresult NS_NewContentSubtreeIterator(nsIContentIterator** aInstancePtrResult);
 | 
				
			||||||
 | 
					nsresult NS_NewDomSelection(nsISelection **aDomSelection);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum nsRangeIterationDirection {
 | 
					enum nsRangeIterationDirection {
 | 
				
			||||||
  kDirectionOut = -1,
 | 
					  kDirectionOut = -1,
 | 
				
			||||||
| 
						 | 
					@ -104,8 +107,9 @@ protected:
 | 
				
			||||||
  nsresult SerializeRangeToString(nsIDOMRange *aRange,
 | 
					  nsresult SerializeRangeToString(nsIDOMRange *aRange,
 | 
				
			||||||
                                  nsAWritableString& aOutputString);
 | 
					                                  nsAWritableString& aOutputString);
 | 
				
			||||||
  nsresult SerializeRangeNodes(nsIDOMRange* aRange, 
 | 
					  nsresult SerializeRangeNodes(nsIDOMRange* aRange, 
 | 
				
			||||||
                               nsIDOMNode* aCommonParent, 
 | 
					                               nsIDOMNode* aNode, 
 | 
				
			||||||
                               nsAWritableString& aString);
 | 
					                               nsAWritableString& aString,
 | 
				
			||||||
 | 
					                               PRInt32 aDepth);
 | 
				
			||||||
  nsresult SerializeRangeContextStart(const nsVoidArray& aAncestorArray,
 | 
					  nsresult SerializeRangeContextStart(const nsVoidArray& aAncestorArray,
 | 
				
			||||||
                                      nsAWritableString& aString);
 | 
					                                      nsAWritableString& aString);
 | 
				
			||||||
  nsresult SerializeRangeContextEnd(const nsVoidArray& aAncestorArray,
 | 
					  nsresult SerializeRangeContextEnd(const nsVoidArray& aAncestorArray,
 | 
				
			||||||
| 
						 | 
					@ -124,6 +128,7 @@ protected:
 | 
				
			||||||
  nsCOMPtr<nsIOutputStream>      mStream;
 | 
					  nsCOMPtr<nsIOutputStream>      mStream;
 | 
				
			||||||
  nsCOMPtr<nsIContentSerializer> mSerializer;
 | 
					  nsCOMPtr<nsIContentSerializer> mSerializer;
 | 
				
			||||||
  nsCOMPtr<nsIUnicodeEncoder>    mUnicodeEncoder;
 | 
					  nsCOMPtr<nsIUnicodeEncoder>    mUnicodeEncoder;
 | 
				
			||||||
 | 
					  nsCOMPtr<nsIDOMNode>           mCommonParent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  nsString          mMimeType;
 | 
					  nsString          mMimeType;
 | 
				
			||||||
  nsString          mCharset;
 | 
					  nsString          mCharset;
 | 
				
			||||||
| 
						 | 
					@ -131,8 +136,14 @@ protected:
 | 
				
			||||||
  PRUint32          mWrapColumn;
 | 
					  PRUint32          mWrapColumn;
 | 
				
			||||||
  PRUint32          mStartDepth;
 | 
					  PRUint32          mStartDepth;
 | 
				
			||||||
  PRUint32          mEndDepth;
 | 
					  PRUint32          mEndDepth;
 | 
				
			||||||
 | 
					  PRInt32           mStartRootIndex;
 | 
				
			||||||
 | 
					  PRInt32           mEndRootIndex;
 | 
				
			||||||
  PRBool            mHaltRangeHint;  
 | 
					  PRBool            mHaltRangeHint;  
 | 
				
			||||||
  nsVoidArray       mCommonAncestors;
 | 
					  nsVoidArray       mCommonAncestors;
 | 
				
			||||||
 | 
					  nsVoidArray       mStartNodes;
 | 
				
			||||||
 | 
					  nsVoidArray       mStartOffsets;
 | 
				
			||||||
 | 
					  nsVoidArray       mEndNodes;
 | 
				
			||||||
 | 
					  nsVoidArray       mEndOffsets;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef XP_MAC
 | 
					#ifdef XP_MAC
 | 
				
			||||||
| 
						 | 
					@ -566,25 +577,33 @@ static nsresult GetLengthOfDOMNode(nsIDOMNode *aNode, PRUint32 &aCount)
 | 
				
			||||||
nsresult
 | 
					nsresult
 | 
				
			||||||
nsDocumentEncoder::SerializeRangeNodes(nsIDOMRange* aRange, 
 | 
					nsDocumentEncoder::SerializeRangeNodes(nsIDOMRange* aRange, 
 | 
				
			||||||
                                       nsIDOMNode* aNode, 
 | 
					                                       nsIDOMNode* aNode, 
 | 
				
			||||||
                                       nsAWritableString& aString)
 | 
					                                       nsAWritableString& aString,
 | 
				
			||||||
 | 
					                                       PRInt32 aDepth)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
 | 
					  nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
 | 
				
			||||||
  NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
 | 
					  NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (IsNodeIntersectsRange(content, aRange))
 | 
					  nsresult rv=NS_OK;
 | 
				
			||||||
  {
 | 
					  
 | 
				
			||||||
    PRBool nodeBefore, nodeAfter;
 | 
					  // get start and end nodes for this recursion level
 | 
				
			||||||
    nsresult rv = CompareNodeToRange(content, aRange, &nodeBefore, &nodeAfter);
 | 
					  nsCOMPtr<nsIContent> startNode, endNode;
 | 
				
			||||||
    if (!nodeBefore && !nodeAfter) // node completely contained
 | 
					  startNode = NS_STATIC_CAST(nsIContent *, mStartNodes[mStartRootIndex - aDepth]);
 | 
				
			||||||
 | 
					  endNode   = NS_STATIC_CAST(nsIContent *, mEndNodes[mEndRootIndex - aDepth]);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  if ((startNode != content) && (endNode != content))
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
 | 
					    // node is completely contained in range.  Serialize the whole subtree
 | 
				
			||||||
 | 
					    // rooted by this node.
 | 
				
			||||||
    rv = SerializeToStringRecursive(aNode, aString);
 | 
					    rv = SerializeToStringRecursive(aNode, aString);
 | 
				
			||||||
    NS_ENSURE_SUCCESS(rv, rv);
 | 
					    NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
    else // node intersects range, but is not contained.  recurse if needed.
 | 
					  else
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
 | 
					    // due to implementation it is impossible for text node to be both start and end of 
 | 
				
			||||||
 | 
					    // range.  We would have handled that case without getting here.
 | 
				
			||||||
    if (IsTextNode(aNode))
 | 
					    if (IsTextNode(aNode))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (nodeBefore)
 | 
					      if (startNode == content)
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        PRInt32 startOffset;
 | 
					        PRInt32 startOffset;
 | 
				
			||||||
        aRange->GetStartOffset(&startOffset);
 | 
					        aRange->GetStartOffset(&startOffset);
 | 
				
			||||||
| 
						 | 
					@ -600,6 +619,8 @@ nsDocumentEncoder::SerializeRangeNodes(nsIDOMRange* aRange,
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      if (aNode != mCommonParent.get())
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        if (IncludeInContext(aNode))
 | 
					        if (IncludeInContext(aNode))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -607,22 +628,59 @@ nsDocumentEncoder::SerializeRangeNodes(nsIDOMRange* aRange,
 | 
				
			||||||
          // so paste client will include this node in paste.
 | 
					          // so paste client will include this node in paste.
 | 
				
			||||||
          mHaltRangeHint = PR_TRUE;
 | 
					          mHaltRangeHint = PR_TRUE;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (nodeBefore && !mHaltRangeHint) mStartDepth++;
 | 
					        if ((startNode == content) && !mHaltRangeHint) mStartDepth++;
 | 
				
			||||||
        if (nodeAfter && !mHaltRangeHint) mEndDepth++;
 | 
					        if ((endNode == content) && !mHaltRangeHint) mEndDepth++;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
 | 
					        // serialize the start of this node
 | 
				
			||||||
        rv = SerializeNodeStart(aNode, 0, -1, aString);
 | 
					        rv = SerializeNodeStart(aNode, 0, -1, aString);
 | 
				
			||||||
        NS_ENSURE_SUCCESS(rv, rv);
 | 
					        NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
      
 | 
					 | 
				
			||||||
        nsCOMPtr<nsIDOMNode> child, tmp;
 | 
					 | 
				
			||||||
        aNode->GetFirstChild(getter_AddRefs(child));
 | 
					 | 
				
			||||||
        while (child)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          rv = SerializeRangeNodes(aRange, child, aString);
 | 
					 | 
				
			||||||
          NS_ENSURE_SUCCESS(rv, rv);
 | 
					 | 
				
			||||||
          child->GetNextSibling(getter_AddRefs(tmp));
 | 
					 | 
				
			||||||
          child = tmp;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
 | 
					      // do some calculations that will tell us which children of this node are in the range.
 | 
				
			||||||
 | 
					      nsCOMPtr<nsIContent> child;
 | 
				
			||||||
 | 
					      nsCOMPtr<nsIDOMNode> childAsNode;
 | 
				
			||||||
 | 
					      PRInt32 startOffset = 0, endOffset = -1;
 | 
				
			||||||
 | 
					      if (startNode == content)
 | 
				
			||||||
 | 
					        startOffset = NS_REINTERPRET_CAST(PRInt32, mStartOffsets[mStartRootIndex - aDepth]);
 | 
				
			||||||
 | 
					      if (endNode == content)
 | 
				
			||||||
 | 
					        endOffset = NS_REINTERPRET_CAST(PRInt32, mEndOffsets[mEndRootIndex - aDepth]);
 | 
				
			||||||
 | 
					      // generated content will cause offset values of -1 to be returned.  
 | 
				
			||||||
 | 
					      PRInt32 j, childCount=0;
 | 
				
			||||||
 | 
					      rv = content->ChildCount(childCount);
 | 
				
			||||||
 | 
					      NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					      if (startOffset == -1) startOffset = 0;
 | 
				
			||||||
 | 
					      if (endOffset == -1) endOffset = childCount;
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        // if we are at the "tip" of the selection, endOffset is fine.
 | 
				
			||||||
 | 
					        // otherwise, we need to add one.  This is because of the semantics
 | 
				
			||||||
 | 
					        // of the offset list created by GetAncestorsAndOffsets().  The
 | 
				
			||||||
 | 
					        // intermediate points on the list use the endOffset of the 
 | 
				
			||||||
 | 
					        // location of the ancestor, rather than just past it.  So we need
 | 
				
			||||||
 | 
					        // to add one here in order to include it in the children we serialize.
 | 
				
			||||||
 | 
					        nsCOMPtr<nsIDOMNode> endParent;
 | 
				
			||||||
 | 
					        aRange->GetEndContainer(getter_AddRefs(endParent));
 | 
				
			||||||
 | 
					        if (aNode != endParent.get())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          endOffset++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      // serialize the children of this node that are in the range
 | 
				
			||||||
 | 
					      for (j=startOffset; j<endOffset; j++)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        rv = content->ChildAt(j, *getter_AddRefs(child));
 | 
				
			||||||
 | 
					        childAsNode = do_QueryInterface(child);
 | 
				
			||||||
 | 
					        NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					        if ((j==startOffset) || (j==endOffset-1))
 | 
				
			||||||
 | 
					          rv = SerializeRangeNodes(aRange, childAsNode, aString, aDepth+1);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					          rv = SerializeToStringRecursive(childAsNode, aString);
 | 
				
			||||||
 | 
					        NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // serialize the end of this node
 | 
				
			||||||
 | 
					      if (aNode != mCommonParent.get())
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
        rv = SerializeNodeEnd(aNode, aString);
 | 
					        rv = SerializeNodeEnd(aNode, aString);
 | 
				
			||||||
        NS_ENSURE_SUCCESS(rv, rv); 
 | 
					        NS_ENSURE_SUCCESS(rv, rv); 
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
| 
						 | 
					@ -693,15 +751,15 @@ nsDocumentEncoder::SerializeRangeToString(nsIDOMRange *aRange,
 | 
				
			||||||
  if (collapsed)
 | 
					  if (collapsed)
 | 
				
			||||||
    return NS_OK;
 | 
					    return NS_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  nsCOMPtr<nsIDOMNode> commonParent, startParent, endParent;
 | 
					  nsCOMPtr<nsIDOMNode> startParent, endParent;
 | 
				
			||||||
  PRInt32 startOffset, endOffset;
 | 
					  PRInt32 startOffset, endOffset;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  aRange->GetCommonAncestorContainer(getter_AddRefs(commonParent));
 | 
					  aRange->GetCommonAncestorContainer(getter_AddRefs(mCommonParent));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!commonParent)
 | 
					  if (!mCommonParent)
 | 
				
			||||||
    return NS_OK;
 | 
					    return NS_OK;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  AdjustCommonParent(&commonParent);
 | 
					  AdjustCommonParent(&mCommonParent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  aRange->GetStartContainer(getter_AddRefs(startParent));
 | 
					  aRange->GetStartContainer(getter_AddRefs(startParent));
 | 
				
			||||||
  NS_ENSURE_TRUE(startParent, NS_ERROR_FAILURE);
 | 
					  NS_ENSURE_TRUE(startParent, NS_ERROR_FAILURE);
 | 
				
			||||||
| 
						 | 
					@ -712,8 +770,17 @@ nsDocumentEncoder::SerializeRangeToString(nsIDOMRange *aRange,
 | 
				
			||||||
  aRange->GetEndOffset(&endOffset);
 | 
					  aRange->GetEndOffset(&endOffset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mCommonAncestors.Clear();
 | 
					  mCommonAncestors.Clear();
 | 
				
			||||||
 | 
					  mStartNodes.Clear();
 | 
				
			||||||
 | 
					  mStartOffsets.Clear();
 | 
				
			||||||
 | 
					  mEndNodes.Clear();
 | 
				
			||||||
 | 
					  mEndOffsets.Clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  nsRange::FillArrayWithAncestors(&mCommonAncestors, commonParent);
 | 
					  nsRange::FillArrayWithAncestors(&mCommonAncestors, mCommonParent);
 | 
				
			||||||
 | 
					  nsRange::GetAncestorsAndOffsets(startParent, startOffset, &mStartNodes, &mStartOffsets);
 | 
				
			||||||
 | 
					  nsRange::GetAncestorsAndOffsets(endParent, endOffset, &mEndNodes, &mEndOffsets);
 | 
				
			||||||
 | 
					  nsCOMPtr<nsIContent> commonContent = do_QueryInterface(mCommonParent);
 | 
				
			||||||
 | 
					  mStartRootIndex = mStartNodes.IndexOf(commonContent);
 | 
				
			||||||
 | 
					  mEndRootIndex = mEndNodes.IndexOf(commonContent);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  nsresult rv = NS_OK;
 | 
					  nsresult rv = NS_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -727,17 +794,9 @@ nsDocumentEncoder::SerializeRangeToString(nsIDOMRange *aRange,
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    nsCOMPtr<nsIDOMNode> child, tmp;
 | 
					    rv = SerializeRangeNodes(aRange, mCommonParent, aOutputString, 0);
 | 
				
			||||||
    commonParent->GetFirstChild(getter_AddRefs(child));
 | 
					 | 
				
			||||||
    while (child)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      rv = SerializeRangeNodes(aRange, child, aOutputString);
 | 
					 | 
				
			||||||
    NS_ENSURE_SUCCESS(rv, rv);
 | 
					    NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
      child->GetNextSibling(getter_AddRefs(tmp));
 | 
					 | 
				
			||||||
      child = tmp;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  rv = SerializeRangeContextEnd(mCommonAncestors, aOutputString);
 | 
					  rv = SerializeRangeContextEnd(mCommonAncestors, aOutputString);
 | 
				
			||||||
  NS_ENSURE_SUCCESS(rv, rv);
 | 
					  NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -888,12 +947,14 @@ protected:
 | 
				
			||||||
  nsCOMPtr<nsIDOMNode> GetChildAt(nsIDOMNode *aParent, PRInt32 aOffset);
 | 
					  nsCOMPtr<nsIDOMNode> GetChildAt(nsIDOMNode *aParent, PRInt32 aOffset);
 | 
				
			||||||
  PRBool IsMozBR(nsIDOMNode* aNode);
 | 
					  PRBool IsMozBR(nsIDOMNode* aNode);
 | 
				
			||||||
  nsresult GetNodeLocation(nsIDOMNode *inChild, nsCOMPtr<nsIDOMNode> *outParent, PRInt32 *outOffset);
 | 
					  nsresult GetNodeLocation(nsIDOMNode *inChild, nsCOMPtr<nsIDOMNode> *outParent, PRInt32 *outOffset);
 | 
				
			||||||
 | 
					  PRBool IsRoot(nsIDOMNode* aNode);
 | 
				
			||||||
  PRBool IsFirstNode(nsIDOMNode *aNode);
 | 
					  PRBool IsFirstNode(nsIDOMNode *aNode);
 | 
				
			||||||
  PRBool IsLastNode(nsIDOMNode *aNode);
 | 
					  PRBool IsLastNode(nsIDOMNode *aNode);
 | 
				
			||||||
  PRBool IsEmptyTextContent(nsIDOMNode* aNode);
 | 
					  PRBool IsEmptyTextContent(nsIDOMNode* aNode);
 | 
				
			||||||
  virtual PRBool IncludeInContext(nsIDOMNode *aNode);
 | 
					  virtual PRBool IncludeInContext(nsIDOMNode *aNode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  nsCOMPtr<nsIParserService> mParserService;
 | 
					  nsCOMPtr<nsIParserService> mParserService;
 | 
				
			||||||
 | 
					  PRBool mIsTextWidget;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef XP_MAC
 | 
					#ifdef XP_MAC
 | 
				
			||||||
| 
						 | 
					@ -903,6 +964,7 @@ protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
nsHTMLCopyEncoder::nsHTMLCopyEncoder()
 | 
					nsHTMLCopyEncoder::nsHTMLCopyEncoder()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  mIsTextWidget = PR_FALSE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
nsHTMLCopyEncoder::~nsHTMLCopyEncoder()
 | 
					nsHTMLCopyEncoder::~nsHTMLCopyEncoder()
 | 
				
			||||||
| 
						 | 
					@ -911,7 +973,7 @@ nsHTMLCopyEncoder::~nsHTMLCopyEncoder()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NS_IMETHODIMP
 | 
					NS_IMETHODIMP
 | 
				
			||||||
nsHTMLCopyEncoder::Init(nsIDocument* aDocument,
 | 
					nsHTMLCopyEncoder::Init(nsIDocument* aDocument,
 | 
				
			||||||
                        const nsAReadableString& aIgnored,
 | 
					                        const nsAReadableString& aMimetype,
 | 
				
			||||||
                        PRUint32 aFlags)
 | 
					                        PRUint32 aFlags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (!aDocument)
 | 
					  if (!aDocument)
 | 
				
			||||||
| 
						 | 
					@ -931,19 +993,50 @@ nsHTMLCopyEncoder::Init(nsIDocument* aDocument,
 | 
				
			||||||
NS_IMETHODIMP
 | 
					NS_IMETHODIMP
 | 
				
			||||||
nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection)
 | 
					nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  // normalize selection
 | 
					  // check for text widgets: we need to recognize these so that
 | 
				
			||||||
 | 
					  // we don't tweak the selection to be outside of the magic
 | 
				
			||||||
 | 
					  // div that ender-lite text widgets are embedded in.
 | 
				
			||||||
 | 
					  nsCOMPtr<nsIDOMNode> selNode;
 | 
				
			||||||
 | 
					  nsresult rv = aSelection->GetFocusNode(getter_AddRefs(selNode));
 | 
				
			||||||
 | 
					  NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					  nsCOMPtr<nsIContent> tmp, selContent( do_QueryInterface(selNode) );
 | 
				
			||||||
 | 
					  while (selContent)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    nsCOMPtr<nsIAtom> atom;
 | 
				
			||||||
 | 
					    selContent->GetTag(*getter_AddRefs(atom));
 | 
				
			||||||
 | 
					    if (atom.get() == nsHTMLAtoms::input ||
 | 
				
			||||||
 | 
					        atom.get() == nsHTMLAtoms::textarea)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      mIsTextWidget = PR_TRUE;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    selContent->GetParent(*getter_AddRefs(tmp));
 | 
				
			||||||
 | 
					    selContent = tmp;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // also consider ourselves in a text widget if we can't find an html document
 | 
				
			||||||
 | 
					  nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
 | 
				
			||||||
 | 
					  if (!htmlDoc) mIsTextWidget = PR_TRUE;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // normalize selection if we are not in a widget
 | 
				
			||||||
 | 
					  if (mIsTextWidget) 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    mSelection = aSelection;
 | 
				
			||||||
 | 
					    mFlags |= OutputRaw;
 | 
				
			||||||
 | 
					    return NS_OK;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // there's no Clone() for selection! fix...
 | 
					  // there's no Clone() for selection! fix...
 | 
				
			||||||
  //nsresult rv = aSelection->Clone(getter_AddRefs(mSelection);
 | 
					  //nsresult rv = aSelection->Clone(getter_AddRefs(mSelection);
 | 
				
			||||||
  //NS_ENSURE_SUCCESS(rv, rv);
 | 
					  //NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
  mSelection = aSelection;
 | 
					  NS_NewDomSelection(getter_AddRefs(mSelection));
 | 
				
			||||||
  
 | 
					  NS_ENSURE_TRUE(mSelection, NS_ERROR_FAILURE);
 | 
				
			||||||
  nsCOMPtr<nsISelectionPrivate> privSelection = do_QueryInterface(mSelection);
 | 
					  nsCOMPtr<nsISelectionPrivate> privSelection( do_QueryInterface(aSelection) );
 | 
				
			||||||
  NS_ENSURE_TRUE(privSelection, NS_ERROR_FAILURE);
 | 
					  NS_ENSURE_TRUE(privSelection, NS_ERROR_FAILURE);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // get selection range enumerator
 | 
					  // get selection range enumerator
 | 
				
			||||||
  nsCOMPtr<nsIEnumerator> enumerator;
 | 
					  nsCOMPtr<nsIEnumerator> enumerator;
 | 
				
			||||||
  nsresult rv = privSelection->GetEnumerator(getter_AddRefs(enumerator));
 | 
					  rv = privSelection->GetEnumerator(getter_AddRefs(enumerator));
 | 
				
			||||||
  NS_ENSURE_SUCCESS(rv, rv);
 | 
					  NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
  NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
 | 
					  NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -957,9 +1050,16 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection)
 | 
				
			||||||
    NS_ENSURE_TRUE(currentItem, NS_ERROR_FAILURE);
 | 
					    NS_ENSURE_TRUE(currentItem, NS_ERROR_FAILURE);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
 | 
					    nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
 | 
				
			||||||
 | 
					    NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
 | 
				
			||||||
 | 
					    nsCOMPtr<nsIDOMRange> myRange;
 | 
				
			||||||
 | 
					    range->CloneRange(getter_AddRefs(myRange));
 | 
				
			||||||
 | 
					    NS_ENSURE_TRUE(myRange, NS_ERROR_FAILURE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // adjust range to include any ancestors who's children are entirely selected
 | 
					    // adjust range to include any ancestors who's children are entirely selected
 | 
				
			||||||
    rv = PromoteRange(range);
 | 
					    rv = PromoteRange(myRange);
 | 
				
			||||||
 | 
					    NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    rv = mSelection->AddRange(myRange);
 | 
				
			||||||
    NS_ENSURE_SUCCESS(rv, rv);
 | 
					    NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enumerator->Next();
 | 
					    enumerator->Next();
 | 
				
			||||||
| 
						 | 
					@ -976,6 +1076,16 @@ nsHTMLCopyEncoder::EncodeToStringWithContext(nsAWritableString& aEncodedString,
 | 
				
			||||||
  nsresult rv = EncodeToString(aEncodedString);
 | 
					  nsresult rv = EncodeToString(aEncodedString);
 | 
				
			||||||
  NS_ENSURE_SUCCESS(rv, rv);
 | 
					  NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (mIsTextWidget) {
 | 
				
			||||||
 | 
					    aEncodedString.Insert(NS_LITERAL_STRING("<pre>"), 0);
 | 
				
			||||||
 | 
					    aEncodedString.Append(NS_LITERAL_STRING("</pre>"));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // do not encode any context info or range hints if we are not in an html document.
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // do not encode any context info or range hints if we are in a text widget.
 | 
				
			||||||
 | 
					  if (mIsTextWidget) return NS_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // now encode common ancestors into aContextString.  Note that the common ancestors
 | 
					  // now encode common ancestors into aContextString.  Note that the common ancestors
 | 
				
			||||||
  // will be for the last range in the selection in the case of multirange selections.
 | 
					  // will be for the last range in the selection in the case of multirange selections.
 | 
				
			||||||
  // encoding ancestors every range in a multirange selection in a way that could be 
 | 
					  // encoding ancestors every range in a multirange selection in a way that could be 
 | 
				
			||||||
| 
						 | 
					@ -1126,12 +1236,12 @@ nsHTMLCopyEncoder::GetPromotedPoint(Endpoint aWhere, nsIDOMNode *aNode, PRInt32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // finding the real start for this point.  look up the tree for as long as we are the 
 | 
					    // finding the real start for this point.  look up the tree for as long as we are the 
 | 
				
			||||||
    // first node in the container, and as long as we haven't hit the body node.
 | 
					    // first node in the container, and as long as we haven't hit the body node.
 | 
				
			||||||
    if (!IsTag(node, nsHTMLAtoms::body))
 | 
					    if (!IsRoot(node))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      rv = GetNodeLocation(node, &parent, &offset);
 | 
					      rv = GetNodeLocation(node, &parent, &offset);
 | 
				
			||||||
      NS_ENSURE_SUCCESS(rv, rv);
 | 
					      NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
      if (offset == -1) return NS_OK; // we hit generated content; STOP
 | 
					      if (offset == -1) return NS_OK; // we hit generated content; STOP
 | 
				
			||||||
      while ((IsFirstNode(node)) && (!IsTag(parent, nsHTMLAtoms::body)))
 | 
					      while ((IsFirstNode(node)) && (!IsRoot(parent)))
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        if (bResetPromotion)
 | 
					        if (bResetPromotion)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -1211,12 +1321,12 @@ nsHTMLCopyEncoder::GetPromotedPoint(Endpoint aWhere, nsIDOMNode *aNode, PRInt32
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // finding the real end for this point.  look up the tree for as long as we are the 
 | 
					    // finding the real end for this point.  look up the tree for as long as we are the 
 | 
				
			||||||
    // last node in the container, and as long as we haven't hit the body node.
 | 
					    // last node in the container, and as long as we haven't hit the body node.
 | 
				
			||||||
    if (!IsTag(node, nsHTMLAtoms::body))
 | 
					    if (!IsRoot(node))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      rv = GetNodeLocation(node, &parent, &offset);
 | 
					      rv = GetNodeLocation(node, &parent, &offset);
 | 
				
			||||||
      NS_ENSURE_SUCCESS(rv, rv);
 | 
					      NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
      if (offset == -1) return NS_OK; // we hit generated content; STOP
 | 
					      if (offset == -1) return NS_OK; // we hit generated content; STOP
 | 
				
			||||||
      while ((IsLastNode(node)) && (!IsTag(parent, nsHTMLAtoms::body)))
 | 
					      while ((IsLastNode(node)) && (!IsRoot(parent)))
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        if (bResetPromotion)
 | 
					        if (bResetPromotion)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -1325,6 +1435,19 @@ nsHTMLCopyEncoder::GetNodeLocation(nsIDOMNode *inChild, nsCOMPtr<nsIDOMNode> *ou
 | 
				
			||||||
  return result;
 | 
					  return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PRBool
 | 
				
			||||||
 | 
					nsHTMLCopyEncoder::IsRoot(nsIDOMNode* aNode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (aNode)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    if (mIsTextWidget) 
 | 
				
			||||||
 | 
					      return (IsTag(aNode, nsHTMLAtoms::div));
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      return (IsTag(aNode, nsHTMLAtoms::body));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return PR_FALSE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PRBool
 | 
					PRBool
 | 
				
			||||||
nsHTMLCopyEncoder::IsFirstNode(nsIDOMNode *aNode)
 | 
					nsHTMLCopyEncoder::IsFirstNode(nsIDOMNode *aNode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,7 @@
 | 
				
			||||||
#include "nsHTMLAtoms.h"
 | 
					#include "nsHTMLAtoms.h"
 | 
				
			||||||
#include "nsIURI.h"
 | 
					#include "nsIURI.h"
 | 
				
			||||||
#include "nsNetUtil.h"
 | 
					#include "nsNetUtil.h"
 | 
				
			||||||
 | 
					#include "nsEscape.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
 | 
					static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
 | 
				
			||||||
static NS_DEFINE_CID(kEntityConverterCID, NS_ENTITYCONVERTER_CID);
 | 
					static NS_DEFINE_CID(kEntityConverterCID, NS_ENTITYCONVERTER_CID);
 | 
				
			||||||
| 
						 | 
					@ -68,21 +69,6 @@ nsHTMLContentSerializer::~nsHTMLContentSerializer()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
nsresult
 | 
					 | 
				
			||||||
nsHTMLContentSerializer::GetEntityConverter(nsIEntityConverter** aConverter)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  if (!mEntityConverter) {
 | 
					 | 
				
			||||||
    nsresult rv;
 | 
					 | 
				
			||||||
    rv = nsComponentManager::CreateInstance(kEntityConverterCID, NULL, 
 | 
					 | 
				
			||||||
                                            NS_GET_IID(nsIEntityConverter),
 | 
					 | 
				
			||||||
                                            getter_AddRefs(mEntityConverter));
 | 
					 | 
				
			||||||
    if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  CallQueryInterface(mEntityConverter.get(), aConverter);
 | 
					 | 
				
			||||||
  return NS_OK;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
nsresult
 | 
					nsresult
 | 
				
			||||||
nsHTMLContentSerializer::GetParserService(nsIParserService** aParserService)
 | 
					nsHTMLContentSerializer::GetParserService(nsIParserService** aParserService)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -149,7 +135,8 @@ nsHTMLContentSerializer::AppendText(nsIDOMText* aText,
 | 
				
			||||||
  PRInt32 lastNewlineOffset = kNotFound;
 | 
					  PRInt32 lastNewlineOffset = kNotFound;
 | 
				
			||||||
  PRBool hasLongLines = HasLongLines(data, lastNewlineOffset);
 | 
					  PRBool hasLongLines = HasLongLines(data, lastNewlineOffset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (mPreLevel || (!mDoFormat && !hasLongLines)) {
 | 
					  if (mPreLevel || (!mDoFormat && !hasLongLines) ||
 | 
				
			||||||
 | 
					      (mFlags & nsIDocumentEncoder::OutputRaw)) {
 | 
				
			||||||
    AppendToString(data, aStr);
 | 
					    AppendToString(data, aStr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (lastNewlineOffset != kNotFound) {
 | 
					    if (lastNewlineOffset != kNotFound) {
 | 
				
			||||||
| 
						 | 
					@ -378,7 +365,6 @@ nsHTMLContentSerializer::AppendToStringWrapped(const nsAReadableString& aStr,
 | 
				
			||||||
  PRBool    done = PR_FALSE;
 | 
					  PRBool    done = PR_FALSE;
 | 
				
			||||||
  PRInt32   indx = 0;
 | 
					  PRInt32   indx = 0;
 | 
				
			||||||
  PRInt32   strOffset = 0;
 | 
					  PRInt32   strOffset = 0;
 | 
				
			||||||
  PRInt32   oldLineOffset = 0;
 | 
					 | 
				
			||||||
  PRInt32   lineLength, oldLineEnd;
 | 
					  PRInt32   lineLength, oldLineEnd;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // Make sure we haven't gone too far already
 | 
					  // Make sure we haven't gone too far already
 | 
				
			||||||
| 
						 | 
					@ -468,28 +454,19 @@ nsHTMLContentSerializer::AppendToString(const nsAReadableString& aStr,
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  nsresult rv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (aIncrColumn) {
 | 
					  if (aIncrColumn) {
 | 
				
			||||||
    mColPos += aStr.Length();
 | 
					    mColPos += aStr.Length();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if (aTranslateEntities) {
 | 
					  if (aTranslateEntities) {
 | 
				
			||||||
    nsCOMPtr<nsIEntityConverter> converter;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    GetEntityConverter(getter_AddRefs(converter));
 | 
					 | 
				
			||||||
    if (converter) {
 | 
					 | 
				
			||||||
    PRUnichar *encodedBuffer;
 | 
					    PRUnichar *encodedBuffer;
 | 
				
			||||||
      rv = mEntityConverter->ConvertToEntities(nsPromiseFlatString(aStr),
 | 
					    encodedBuffer = nsEscapeHTML2(nsPromiseFlatString(aStr), aStr.Length());
 | 
				
			||||||
                                               nsIEntityConverter::html40Latin1,
 | 
					    if (encodedBuffer) {
 | 
				
			||||||
                                               &encodedBuffer);
 | 
					 | 
				
			||||||
      if (NS_SUCCEEDED(rv)) {
 | 
					 | 
				
			||||||
      aOutputStr.Append(encodedBuffer);
 | 
					      aOutputStr.Append(encodedBuffer);
 | 
				
			||||||
      nsCRT::free(encodedBuffer);
 | 
					      nsCRT::free(encodedBuffer);
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  aOutputStr.Append(aStr);
 | 
					  aOutputStr.Append(aStr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -513,7 +490,8 @@ PRBool
 | 
				
			||||||
nsHTMLContentSerializer::LineBreakBeforeOpen(nsIAtom* aName, 
 | 
					nsHTMLContentSerializer::LineBreakBeforeOpen(nsIAtom* aName, 
 | 
				
			||||||
                                             PRBool aHasDirtyAttr)
 | 
					                                             PRBool aHasDirtyAttr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel || !mColPos) {
 | 
					  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel || !mColPos ||
 | 
				
			||||||
 | 
					      (mFlags & nsIDocumentEncoder::OutputRaw)) {
 | 
				
			||||||
    return PR_FALSE;
 | 
					    return PR_FALSE;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
| 
						 | 
					@ -548,7 +526,8 @@ PRBool
 | 
				
			||||||
nsHTMLContentSerializer::LineBreakAfterOpen(nsIAtom* aName, 
 | 
					nsHTMLContentSerializer::LineBreakAfterOpen(nsIAtom* aName, 
 | 
				
			||||||
                                            PRBool aHasDirtyAttr)
 | 
					                                            PRBool aHasDirtyAttr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel) {
 | 
					  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel ||
 | 
				
			||||||
 | 
					      (mFlags & nsIDocumentEncoder::OutputRaw)) {
 | 
				
			||||||
    return PR_FALSE;
 | 
					    return PR_FALSE;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -576,7 +555,8 @@ PRBool
 | 
				
			||||||
nsHTMLContentSerializer::LineBreakBeforeClose(nsIAtom* aName, 
 | 
					nsHTMLContentSerializer::LineBreakBeforeClose(nsIAtom* aName, 
 | 
				
			||||||
                                              PRBool aHasDirtyAttr)
 | 
					                                              PRBool aHasDirtyAttr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel || !mColPos) {
 | 
					  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel || !mColPos ||
 | 
				
			||||||
 | 
					      (mFlags & nsIDocumentEncoder::OutputRaw)) {
 | 
				
			||||||
    return PR_FALSE;
 | 
					    return PR_FALSE;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -598,7 +578,8 @@ PRBool
 | 
				
			||||||
nsHTMLContentSerializer::LineBreakAfterClose(nsIAtom* aName, 
 | 
					nsHTMLContentSerializer::LineBreakAfterClose(nsIAtom* aName, 
 | 
				
			||||||
                                             PRBool aHasDirtyAttr)
 | 
					                                             PRBool aHasDirtyAttr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel) {
 | 
					  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel ||
 | 
				
			||||||
 | 
					      (mFlags & nsIDocumentEncoder::OutputRaw)) {
 | 
				
			||||||
    return PR_FALSE;
 | 
					    return PR_FALSE;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -281,6 +281,9 @@ nsPlainTextSerializer::AppendElementStart(nsIDOMElement *aElement,
 | 
				
			||||||
  mContent = 0;
 | 
					  mContent = 0;
 | 
				
			||||||
  mOutputString = nsnull;
 | 
					  mOutputString = nsnull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!mInHead && id == eHTMLTag_head)
 | 
				
			||||||
 | 
					    mInHead = PR_TRUE;    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return rv;
 | 
					  return rv;
 | 
				
			||||||
} 
 | 
					} 
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
| 
						 | 
					@ -310,6 +313,9 @@ nsPlainTextSerializer::AppendElementEnd(nsIDOMElement *aElement,
 | 
				
			||||||
  mContent = 0;
 | 
					  mContent = 0;
 | 
				
			||||||
  mOutputString = nsnull;
 | 
					  mOutputString = nsnull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (mInHead && id == eHTMLTag_head)
 | 
				
			||||||
 | 
					    mInHead = PR_FALSE;    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return rv;
 | 
					  return rv;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -326,8 +332,6 @@ NS_IMETHODIMP
 | 
				
			||||||
nsPlainTextSerializer::OpenContainer(const nsIParserNode& aNode)
 | 
					nsPlainTextSerializer::OpenContainer(const nsIParserNode& aNode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PRInt32 type = aNode.GetNodeType();
 | 
					  PRInt32 type = aNode.GetNodeType();
 | 
				
			||||||
  const nsString&   namestr = aNode.GetText();
 | 
					 | 
				
			||||||
  nsCOMPtr<nsIAtom> name = dont_AddRef(NS_NewAtom(namestr));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mParserNode = NS_CONST_CAST(nsIParserNode *, &aNode);
 | 
					  mParserNode = NS_CONST_CAST(nsIParserNode *, &aNode);
 | 
				
			||||||
  return DoOpenContainer(type);
 | 
					  return DoOpenContainer(type);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -150,6 +150,8 @@ public:
 | 
				
			||||||
  static PRBool        InSameDoc(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
 | 
					  static PRBool        InSameDoc(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
 | 
				
			||||||
  static PRInt32       IndexOf(nsIDOMNode* aNode);
 | 
					  static PRInt32       IndexOf(nsIDOMNode* aNode);
 | 
				
			||||||
  static PRInt32       FillArrayWithAncestors(nsVoidArray* aArray,nsIDOMNode* aNode);
 | 
					  static PRInt32       FillArrayWithAncestors(nsVoidArray* aArray,nsIDOMNode* aNode);
 | 
				
			||||||
 | 
					  static PRInt32       GetAncestorsAndOffsets(nsIDOMNode* aNode, PRInt32 aOffset,
 | 
				
			||||||
 | 
					                                              nsVoidArray* aAncestorNodes, nsVoidArray* aAncestorOffsets);
 | 
				
			||||||
  static nsCOMPtr<nsIDOMNode>   CommonParent(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
 | 
					  static nsCOMPtr<nsIDOMNode>   CommonParent(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
 | 
				
			||||||
  static nsresult      GetDOMNodeFromContent(nsIContent* inContentNode, nsCOMPtr<nsIDOMNode>* outDomNode);
 | 
					  static nsresult      GetDOMNodeFromContent(nsIContent* inContentNode, nsCOMPtr<nsIDOMNode>* outDomNode);
 | 
				
			||||||
  static nsresult      GetContentFromDOMNode(nsIDOMNode* inDomNode, nsCOMPtr<nsIContent>* outContentNode);
 | 
					  static nsresult      GetContentFromDOMNode(nsIDOMNode* inDomNode, nsCOMPtr<nsIContent>* outContentNode);
 | 
				
			||||||
| 
						 | 
					@ -173,9 +175,6 @@ public:
 | 
				
			||||||
  nsresult      ComparePointToRange(nsIDOMNode* aParent, PRInt32 aOffset, PRInt32* aResult);
 | 
					  nsresult      ComparePointToRange(nsIDOMNode* aParent, PRInt32 aOffset, PRInt32* aResult);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  PRInt32       GetAncestorsAndOffsets(nsIDOMNode* aNode, PRInt32 aOffset,
 | 
					 | 
				
			||||||
                        nsVoidArray* aAncestorNodes, nsVoidArray* aAncestorOffsets);
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  nsresult      AddToListOf(nsIDOMNode* aNode);
 | 
					  nsresult      AddToListOf(nsIDOMNode* aNode);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  nsresult      RemoveFromListOf(nsIDOMNode* aNode);
 | 
					  nsresult      RemoveFromListOf(nsIDOMNode* aNode);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2417,6 +2417,36 @@ NS_IMETHODIMP nsHTMLEditor::InsertText(const nsString& aStringToInsert)
 | 
				
			||||||
  return result;
 | 
					  return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static nsCOMPtr<nsIDOMNode> GetListParent(nsIDOMNode* aNode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (!aNode) return nsnull;
 | 
				
			||||||
 | 
					  nsCOMPtr<nsIDOMNode> parent, tmp;
 | 
				
			||||||
 | 
					  aNode->GetParentNode(getter_AddRefs(parent));
 | 
				
			||||||
 | 
					  while (parent)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    if (nsHTMLEditUtils::IsList(parent)) return parent;
 | 
				
			||||||
 | 
					    parent->GetParentNode(getter_AddRefs(tmp));
 | 
				
			||||||
 | 
					    parent = tmp;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return nsnull;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static nsCOMPtr<nsIDOMNode> GetTableParent(nsIDOMNode* aNode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (!aNode) return nsnull;
 | 
				
			||||||
 | 
					  nsCOMPtr<nsIDOMNode> parent, tmp;
 | 
				
			||||||
 | 
					  aNode->GetParentNode(getter_AddRefs(parent));
 | 
				
			||||||
 | 
					  while (parent)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    if (nsHTMLEditUtils::IsTable(parent)) return parent;
 | 
				
			||||||
 | 
					    parent->GetParentNode(getter_AddRefs(tmp));
 | 
				
			||||||
 | 
					    parent = tmp;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return nsnull;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NS_IMETHODIMP nsHTMLEditor::InsertHTML(const nsString& aInputString)
 | 
					NS_IMETHODIMP nsHTMLEditor::InsertHTML(const nsString& aInputString)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  nsAutoString charset;
 | 
					  nsAutoString charset;
 | 
				
			||||||
| 
						 | 
					@ -2476,8 +2506,7 @@ nsresult nsHTMLEditor::InsertHTMLWithCharsetAndContext(const nsString& aInputStr
 | 
				
			||||||
  nsCOMPtr<nsIDOMNSRange> nsrange (do_QueryInterface(range));
 | 
					  nsCOMPtr<nsIDOMNSRange> nsrange (do_QueryInterface(range));
 | 
				
			||||||
  if (!nsrange)
 | 
					  if (!nsrange)
 | 
				
			||||||
    return NS_ERROR_NO_INTERFACE;
 | 
					    return NS_ERROR_NO_INTERFACE;
 | 
				
			||||||
nsCAutoString foo; foo.AssignWithConversion(inputString);
 | 
					
 | 
				
			||||||
printf ("fff = '%s'\n", (const char *)foo);
 | 
					 | 
				
			||||||
  // create a dom document fragment that represents the structure to paste
 | 
					  // create a dom document fragment that represents the structure to paste
 | 
				
			||||||
  nsCOMPtr<nsIDOMDocumentFragment> docfrag;
 | 
					  nsCOMPtr<nsIDOMDocumentFragment> docfrag;
 | 
				
			||||||
  res = nsrange->CreateContextualFragment(inputString,
 | 
					  res = nsrange->CreateContextualFragment(inputString,
 | 
				
			||||||
| 
						 | 
					@ -2485,11 +2514,6 @@ printf ("fff = '%s'\n", (const char *)foo);
 | 
				
			||||||
  NS_ENSURE_SUCCESS(res, res);
 | 
					  NS_ENSURE_SUCCESS(res, res);
 | 
				
			||||||
  nsCOMPtr<nsIDOMNode> fragmentAsNode (do_QueryInterface(docfrag));
 | 
					  nsCOMPtr<nsIDOMNode> fragmentAsNode (do_QueryInterface(docfrag));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PRInt32 bar;
 | 
					 | 
				
			||||||
  nsCOMPtr<nsIContent> f(do_QueryInterface(docfrag));
 | 
					 | 
				
			||||||
  f->ChildCount(bar);
 | 
					 | 
				
			||||||
printf ("Child count %d\n", bar);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  res = StripFormattingNodes(fragmentAsNode);
 | 
					  res = StripFormattingNodes(fragmentAsNode);
 | 
				
			||||||
  NS_ENSURE_SUCCESS(res, res);
 | 
					  NS_ENSURE_SUCCESS(res, res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2657,10 +2681,34 @@ printf ("Child count %d\n", bar);
 | 
				
			||||||
      parentNode = temp;
 | 
					      parentNode = temp;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // scan insertion list for table elements (other than table).  
 | 
					    // build up list of parents of first node in lst that are either:
 | 
				
			||||||
    PRBool bHaveTableGuts = PR_FALSE;
 | 
					    // lists, or tables.  
 | 
				
			||||||
    PRBool bHaveListGuts  = PR_FALSE;
 | 
					    nsCOMPtr<nsISupports> isup = nodeList->ElementAt(0);
 | 
				
			||||||
 | 
					    nsCOMPtr<nsIDOMNode>  pNode( do_QueryInterface(isup) );
 | 
				
			||||||
 | 
					    nsCOMPtr<nsISupportsArray> listAndTableArray;
 | 
				
			||||||
 | 
					    res = NS_NewISupportsArray(getter_AddRefs(listAndTableArray));
 | 
				
			||||||
 | 
					    NS_ENSURE_SUCCESS(res, res);
 | 
				
			||||||
 | 
					    while (pNode)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      if (nsHTMLEditUtils::IsList(pNode) || nsHTMLEditUtils::IsTable(pNode))
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        isup = do_QueryInterface(pNode);
 | 
				
			||||||
 | 
					        listAndTableArray->AppendElement(isup);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      nsCOMPtr<nsIDOMNode> parent;
 | 
				
			||||||
 | 
					      pNode->GetParentNode(getter_AddRefs(parent));
 | 
				
			||||||
 | 
					      pNode = parent;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // remember number of lists and tables above us
 | 
				
			||||||
 | 
					    PRUint32 listAndTableParents;
 | 
				
			||||||
 | 
					    PRInt32 highWaterMark = -1;
 | 
				
			||||||
 | 
					    listAndTableArray->Count(&listAndTableParents);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    PRUint32 listCount, j;
 | 
					    PRUint32 listCount, j;
 | 
				
			||||||
 | 
					    if (listAndTableParents)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      // scan insertion list for table elements (other than table).  
 | 
				
			||||||
      nodeList->Count(&listCount);
 | 
					      nodeList->Count(&listCount);
 | 
				
			||||||
      for (j=0; j<listCount; j++)
 | 
					      for (j=0; j<listCount; j++)
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
| 
						 | 
					@ -2670,31 +2718,96 @@ printf ("Child count %d\n", bar);
 | 
				
			||||||
        NS_ENSURE_TRUE(curNode, NS_ERROR_FAILURE);
 | 
					        NS_ENSURE_TRUE(curNode, NS_ERROR_FAILURE);
 | 
				
			||||||
        if (nsHTMLEditUtils::IsTableElement(curNode) && !nsHTMLEditUtils::IsTable(curNode))
 | 
					        if (nsHTMLEditUtils::IsTableElement(curNode) && !nsHTMLEditUtils::IsTable(curNode))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
        bHaveTableGuts = PR_TRUE;
 | 
					          nsCOMPtr<nsIDOMNode> theTable = GetTableParent(curNode);
 | 
				
			||||||
 | 
					          if (theTable)
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            nsCOMPtr<nsISupports> isupTable(do_QueryInterface(theTable));
 | 
				
			||||||
 | 
					            PRInt32 indexT = listAndTableArray->IndexOf(isupTable);
 | 
				
			||||||
 | 
					            if (indexT >= 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              highWaterMark = indexT;
 | 
				
			||||||
 | 
					              if ((PRUint32)highWaterMark == listAndTableParents-1) break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (nsHTMLEditUtils::IsListItem(curNode))
 | 
					        if (nsHTMLEditUtils::IsListItem(curNode))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
        bHaveListGuts = PR_TRUE;
 | 
					          nsCOMPtr<nsIDOMNode> theList = GetListParent(curNode);
 | 
				
			||||||
 | 
					          if (theList)
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            nsCOMPtr<nsISupports> isupList(do_QueryInterface(theList));
 | 
				
			||||||
 | 
					            PRInt32 indexL = listAndTableArray->IndexOf(isupList);
 | 
				
			||||||
 | 
					            if (indexL >= 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              highWaterMark = indexL;
 | 
				
			||||||
 | 
					              if ((PRUint32)highWaterMark == listAndTableParents-1) break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // 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)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      nsCOMPtr<nsISupports> isupports = listAndTableArray->ElementAt(highWaterMark);
 | 
				
			||||||
 | 
					      nsCOMPtr<nsIDOMNode> curNode( do_QueryInterface(isupports) );
 | 
				
			||||||
 | 
					      nsCOMPtr<nsIDOMNode> replaceNode;
 | 
				
			||||||
 | 
					      if (nsHTMLEditUtils::IsTable(curNode))
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        // look upward from curNode for a piece of this table
 | 
				
			||||||
 | 
					        isup  = nodeList->ElementAt(0);
 | 
				
			||||||
 | 
					        pNode = do_QueryInterface(isup);
 | 
				
			||||||
 | 
					        while (pNode)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          if (nsHTMLEditUtils::IsTableElement(pNode) && !nsHTMLEditUtils::IsTable(pNode))
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            nsCOMPtr<nsIDOMNode> tableP = GetTableParent(pNode);
 | 
				
			||||||
 | 
					            if (tableP == curNode)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              replaceNode = pNode;
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          nsCOMPtr<nsIDOMNode> parent;
 | 
				
			||||||
 | 
					          pNode->GetParentNode(getter_AddRefs(parent));
 | 
				
			||||||
 | 
					          pNode = parent;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else // list case
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        // look upward from curNode for a piece of this list
 | 
				
			||||||
 | 
					        isup  = nodeList->ElementAt(0);
 | 
				
			||||||
 | 
					        pNode = do_QueryInterface(isup);
 | 
				
			||||||
 | 
					        while (pNode)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          if (nsHTMLEditUtils::IsListItem(pNode))
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            nsCOMPtr<nsIDOMNode> listP = GetListParent(pNode);
 | 
				
			||||||
 | 
					            if (listP == curNode)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              replaceNode = pNode;
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          nsCOMPtr<nsIDOMNode> parent;
 | 
				
			||||||
 | 
					          pNode->GetParentNode(getter_AddRefs(parent));
 | 
				
			||||||
 | 
					          pNode = parent;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      if (bHaveTableGuts && bHaveListGuts) break; // no need to continue
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
    // if we have pieces of tables to be inserted, then make sure beginning content
 | 
					      if (replaceNode)
 | 
				
			||||||
    // is not in a table.  If it is, let's force the paste to deal with table elements
 | 
					 | 
				
			||||||
    // right away, so that it doesn't orphan some table contents outside the table.
 | 
					 | 
				
			||||||
    if (bHaveTableGuts)
 | 
					 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
      nsCOMPtr<nsISupports> isupports = nodeList->ElementAt(0);
 | 
					        isupports = do_QueryInterface(replaceNode);
 | 
				
			||||||
      nsCOMPtr<nsIDOMNode> curNode( do_QueryInterface(isupports) );
 | 
					 | 
				
			||||||
      if (!nsHTMLEditUtils::IsTableElement(curNode))
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        nsCOMPtr<nsIDOMNode> parent, tmp;
 | 
					 | 
				
			||||||
        curNode->GetParentNode(getter_AddRefs(parent));
 | 
					 | 
				
			||||||
        while (parent)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          if (nsHTMLEditUtils::IsTableElement(parent))
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            isupports = do_QueryInterface(parent);
 | 
					 | 
				
			||||||
        nodeList->ReplaceElementAt(isupports, 0);
 | 
					        nodeList->ReplaceElementAt(isupports, 0);
 | 
				
			||||||
        // postprocess list to remove any descendants of this node
 | 
					        // postprocess list to remove any descendants of this node
 | 
				
			||||||
        // so that we dont insert them twice.
 | 
					        // so that we dont insert them twice.
 | 
				
			||||||
| 
						 | 
					@ -2702,55 +2815,18 @@ printf ("Child count %d\n", bar);
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          isupports = nodeList->ElementAt(1);
 | 
					          isupports = nodeList->ElementAt(1);
 | 
				
			||||||
          tmp = do_QueryInterface(isupports);
 | 
					          tmp = do_QueryInterface(isupports);
 | 
				
			||||||
              if (nsHTMLEditUtils::IsDescendantOf(tmp, parent))
 | 
					          if (tmp && nsHTMLEditUtils::IsDescendantOf(tmp, replaceNode))
 | 
				
			||||||
            nodeList->RemoveElementAt(1);
 | 
					            nodeList->RemoveElementAt(1);
 | 
				
			||||||
          else
 | 
					          else
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        } while(tmp);
 | 
					        } while(tmp);
 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          parent->GetParentNode(getter_AddRefs(curNode));
 | 
					 | 
				
			||||||
          parent = curNode;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // same story as above, only for pieces of lists.
 | 
					 | 
				
			||||||
    if (bHaveListGuts)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      nsCOMPtr<nsISupports> isupports = nodeList->ElementAt(0);
 | 
					 | 
				
			||||||
      nsCOMPtr<nsIDOMNode> curNode( do_QueryInterface(isupports) );
 | 
					 | 
				
			||||||
      if (!nsHTMLEditUtils::IsListItem(curNode))
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        nsCOMPtr<nsIDOMNode> parent;
 | 
					 | 
				
			||||||
        curNode->GetParentNode(getter_AddRefs(parent));
 | 
					 | 
				
			||||||
        while (parent)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          if (nsHTMLEditUtils::IsListItem(parent))
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            isupports = do_QueryInterface(parent);
 | 
					 | 
				
			||||||
            nodeList->ReplaceElementAt(isupports, 0);
 | 
					 | 
				
			||||||
            // postprocess list to remove any descendants of this node
 | 
					 | 
				
			||||||
            // so that we dont insert them twice.
 | 
					 | 
				
			||||||
            do
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              isupports = nodeList->ElementAt(1);
 | 
					 | 
				
			||||||
              tmp = do_QueryInterface(isupports);
 | 
					 | 
				
			||||||
              if (nsHTMLEditUtils::IsDescendantOf(tmp, parent))
 | 
					 | 
				
			||||||
                nodeList->RemoveElementAt(1);
 | 
					 | 
				
			||||||
              else
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            } while(tmp);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          parent->GetParentNode(getter_AddRefs(curNode));
 | 
					 | 
				
			||||||
          parent = curNode;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Loop over the node list and paste the nodes:
 | 
					    // Loop over the node list and paste the nodes:
 | 
				
			||||||
    PRBool bDidInsert = PR_FALSE;
 | 
					    PRBool bDidInsert = PR_FALSE;
 | 
				
			||||||
    nsCOMPtr<nsIDOMNode> lastInsertNode, insertedContextParent;
 | 
					    nsCOMPtr<nsIDOMNode> lastInsertNode, insertedContextParent;
 | 
				
			||||||
 | 
					    nodeList->Count(&listCount);
 | 
				
			||||||
    for (j=0; j<listCount; j++)
 | 
					    for (j=0; j<listCount; j++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      nsCOMPtr<nsISupports> isupports = nodeList->ElementAt(j);
 | 
					      nsCOMPtr<nsISupports> isupports = nodeList->ElementAt(j);
 | 
				
			||||||
| 
						 | 
					@ -6147,8 +6223,6 @@ NS_IMETHODIMP nsHTMLEditor::OutputToString(nsAWritableString& aOutputString,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (nsHTMLEditUtils::IsBody(rootElement))
 | 
					    else if (nsHTMLEditUtils::IsBody(rootElement))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      nsresult rv = NS_OK;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      nsCOMPtr<nsIDocumentEncoder> encoder;
 | 
					      nsCOMPtr<nsIDocumentEncoder> encoder;
 | 
				
			||||||
      nsCAutoString formatType(NS_DOC_ENCODER_CONTRACTID_BASE);
 | 
					      nsCAutoString formatType(NS_DOC_ENCODER_CONTRACTID_BASE);
 | 
				
			||||||
      formatType.AppendWithConversion(aFormatType);
 | 
					      formatType.AppendWithConversion(aFormatType);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2417,6 +2417,36 @@ NS_IMETHODIMP nsHTMLEditor::InsertText(const nsString& aStringToInsert)
 | 
				
			||||||
  return result;
 | 
					  return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static nsCOMPtr<nsIDOMNode> GetListParent(nsIDOMNode* aNode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (!aNode) return nsnull;
 | 
				
			||||||
 | 
					  nsCOMPtr<nsIDOMNode> parent, tmp;
 | 
				
			||||||
 | 
					  aNode->GetParentNode(getter_AddRefs(parent));
 | 
				
			||||||
 | 
					  while (parent)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    if (nsHTMLEditUtils::IsList(parent)) return parent;
 | 
				
			||||||
 | 
					    parent->GetParentNode(getter_AddRefs(tmp));
 | 
				
			||||||
 | 
					    parent = tmp;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return nsnull;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static nsCOMPtr<nsIDOMNode> GetTableParent(nsIDOMNode* aNode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (!aNode) return nsnull;
 | 
				
			||||||
 | 
					  nsCOMPtr<nsIDOMNode> parent, tmp;
 | 
				
			||||||
 | 
					  aNode->GetParentNode(getter_AddRefs(parent));
 | 
				
			||||||
 | 
					  while (parent)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    if (nsHTMLEditUtils::IsTable(parent)) return parent;
 | 
				
			||||||
 | 
					    parent->GetParentNode(getter_AddRefs(tmp));
 | 
				
			||||||
 | 
					    parent = tmp;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return nsnull;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NS_IMETHODIMP nsHTMLEditor::InsertHTML(const nsString& aInputString)
 | 
					NS_IMETHODIMP nsHTMLEditor::InsertHTML(const nsString& aInputString)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  nsAutoString charset;
 | 
					  nsAutoString charset;
 | 
				
			||||||
| 
						 | 
					@ -2476,8 +2506,7 @@ nsresult nsHTMLEditor::InsertHTMLWithCharsetAndContext(const nsString& aInputStr
 | 
				
			||||||
  nsCOMPtr<nsIDOMNSRange> nsrange (do_QueryInterface(range));
 | 
					  nsCOMPtr<nsIDOMNSRange> nsrange (do_QueryInterface(range));
 | 
				
			||||||
  if (!nsrange)
 | 
					  if (!nsrange)
 | 
				
			||||||
    return NS_ERROR_NO_INTERFACE;
 | 
					    return NS_ERROR_NO_INTERFACE;
 | 
				
			||||||
nsCAutoString foo; foo.AssignWithConversion(inputString);
 | 
					
 | 
				
			||||||
printf ("fff = '%s'\n", (const char *)foo);
 | 
					 | 
				
			||||||
  // create a dom document fragment that represents the structure to paste
 | 
					  // create a dom document fragment that represents the structure to paste
 | 
				
			||||||
  nsCOMPtr<nsIDOMDocumentFragment> docfrag;
 | 
					  nsCOMPtr<nsIDOMDocumentFragment> docfrag;
 | 
				
			||||||
  res = nsrange->CreateContextualFragment(inputString,
 | 
					  res = nsrange->CreateContextualFragment(inputString,
 | 
				
			||||||
| 
						 | 
					@ -2485,11 +2514,6 @@ printf ("fff = '%s'\n", (const char *)foo);
 | 
				
			||||||
  NS_ENSURE_SUCCESS(res, res);
 | 
					  NS_ENSURE_SUCCESS(res, res);
 | 
				
			||||||
  nsCOMPtr<nsIDOMNode> fragmentAsNode (do_QueryInterface(docfrag));
 | 
					  nsCOMPtr<nsIDOMNode> fragmentAsNode (do_QueryInterface(docfrag));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PRInt32 bar;
 | 
					 | 
				
			||||||
  nsCOMPtr<nsIContent> f(do_QueryInterface(docfrag));
 | 
					 | 
				
			||||||
  f->ChildCount(bar);
 | 
					 | 
				
			||||||
printf ("Child count %d\n", bar);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  res = StripFormattingNodes(fragmentAsNode);
 | 
					  res = StripFormattingNodes(fragmentAsNode);
 | 
				
			||||||
  NS_ENSURE_SUCCESS(res, res);
 | 
					  NS_ENSURE_SUCCESS(res, res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2657,10 +2681,34 @@ printf ("Child count %d\n", bar);
 | 
				
			||||||
      parentNode = temp;
 | 
					      parentNode = temp;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // scan insertion list for table elements (other than table).  
 | 
					    // build up list of parents of first node in lst that are either:
 | 
				
			||||||
    PRBool bHaveTableGuts = PR_FALSE;
 | 
					    // lists, or tables.  
 | 
				
			||||||
    PRBool bHaveListGuts  = PR_FALSE;
 | 
					    nsCOMPtr<nsISupports> isup = nodeList->ElementAt(0);
 | 
				
			||||||
 | 
					    nsCOMPtr<nsIDOMNode>  pNode( do_QueryInterface(isup) );
 | 
				
			||||||
 | 
					    nsCOMPtr<nsISupportsArray> listAndTableArray;
 | 
				
			||||||
 | 
					    res = NS_NewISupportsArray(getter_AddRefs(listAndTableArray));
 | 
				
			||||||
 | 
					    NS_ENSURE_SUCCESS(res, res);
 | 
				
			||||||
 | 
					    while (pNode)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      if (nsHTMLEditUtils::IsList(pNode) || nsHTMLEditUtils::IsTable(pNode))
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        isup = do_QueryInterface(pNode);
 | 
				
			||||||
 | 
					        listAndTableArray->AppendElement(isup);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      nsCOMPtr<nsIDOMNode> parent;
 | 
				
			||||||
 | 
					      pNode->GetParentNode(getter_AddRefs(parent));
 | 
				
			||||||
 | 
					      pNode = parent;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // remember number of lists and tables above us
 | 
				
			||||||
 | 
					    PRUint32 listAndTableParents;
 | 
				
			||||||
 | 
					    PRInt32 highWaterMark = -1;
 | 
				
			||||||
 | 
					    listAndTableArray->Count(&listAndTableParents);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    PRUint32 listCount, j;
 | 
					    PRUint32 listCount, j;
 | 
				
			||||||
 | 
					    if (listAndTableParents)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      // scan insertion list for table elements (other than table).  
 | 
				
			||||||
      nodeList->Count(&listCount);
 | 
					      nodeList->Count(&listCount);
 | 
				
			||||||
      for (j=0; j<listCount; j++)
 | 
					      for (j=0; j<listCount; j++)
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
| 
						 | 
					@ -2670,31 +2718,96 @@ printf ("Child count %d\n", bar);
 | 
				
			||||||
        NS_ENSURE_TRUE(curNode, NS_ERROR_FAILURE);
 | 
					        NS_ENSURE_TRUE(curNode, NS_ERROR_FAILURE);
 | 
				
			||||||
        if (nsHTMLEditUtils::IsTableElement(curNode) && !nsHTMLEditUtils::IsTable(curNode))
 | 
					        if (nsHTMLEditUtils::IsTableElement(curNode) && !nsHTMLEditUtils::IsTable(curNode))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
        bHaveTableGuts = PR_TRUE;
 | 
					          nsCOMPtr<nsIDOMNode> theTable = GetTableParent(curNode);
 | 
				
			||||||
 | 
					          if (theTable)
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            nsCOMPtr<nsISupports> isupTable(do_QueryInterface(theTable));
 | 
				
			||||||
 | 
					            PRInt32 indexT = listAndTableArray->IndexOf(isupTable);
 | 
				
			||||||
 | 
					            if (indexT >= 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              highWaterMark = indexT;
 | 
				
			||||||
 | 
					              if ((PRUint32)highWaterMark == listAndTableParents-1) break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (nsHTMLEditUtils::IsListItem(curNode))
 | 
					        if (nsHTMLEditUtils::IsListItem(curNode))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
        bHaveListGuts = PR_TRUE;
 | 
					          nsCOMPtr<nsIDOMNode> theList = GetListParent(curNode);
 | 
				
			||||||
 | 
					          if (theList)
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            nsCOMPtr<nsISupports> isupList(do_QueryInterface(theList));
 | 
				
			||||||
 | 
					            PRInt32 indexL = listAndTableArray->IndexOf(isupList);
 | 
				
			||||||
 | 
					            if (indexL >= 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              highWaterMark = indexL;
 | 
				
			||||||
 | 
					              if ((PRUint32)highWaterMark == listAndTableParents-1) break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // 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)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      nsCOMPtr<nsISupports> isupports = listAndTableArray->ElementAt(highWaterMark);
 | 
				
			||||||
 | 
					      nsCOMPtr<nsIDOMNode> curNode( do_QueryInterface(isupports) );
 | 
				
			||||||
 | 
					      nsCOMPtr<nsIDOMNode> replaceNode;
 | 
				
			||||||
 | 
					      if (nsHTMLEditUtils::IsTable(curNode))
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        // look upward from curNode for a piece of this table
 | 
				
			||||||
 | 
					        isup  = nodeList->ElementAt(0);
 | 
				
			||||||
 | 
					        pNode = do_QueryInterface(isup);
 | 
				
			||||||
 | 
					        while (pNode)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          if (nsHTMLEditUtils::IsTableElement(pNode) && !nsHTMLEditUtils::IsTable(pNode))
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            nsCOMPtr<nsIDOMNode> tableP = GetTableParent(pNode);
 | 
				
			||||||
 | 
					            if (tableP == curNode)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              replaceNode = pNode;
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          nsCOMPtr<nsIDOMNode> parent;
 | 
				
			||||||
 | 
					          pNode->GetParentNode(getter_AddRefs(parent));
 | 
				
			||||||
 | 
					          pNode = parent;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else // list case
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        // look upward from curNode for a piece of this list
 | 
				
			||||||
 | 
					        isup  = nodeList->ElementAt(0);
 | 
				
			||||||
 | 
					        pNode = do_QueryInterface(isup);
 | 
				
			||||||
 | 
					        while (pNode)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          if (nsHTMLEditUtils::IsListItem(pNode))
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            nsCOMPtr<nsIDOMNode> listP = GetListParent(pNode);
 | 
				
			||||||
 | 
					            if (listP == curNode)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              replaceNode = pNode;
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          nsCOMPtr<nsIDOMNode> parent;
 | 
				
			||||||
 | 
					          pNode->GetParentNode(getter_AddRefs(parent));
 | 
				
			||||||
 | 
					          pNode = parent;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      if (bHaveTableGuts && bHaveListGuts) break; // no need to continue
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
    // if we have pieces of tables to be inserted, then make sure beginning content
 | 
					      if (replaceNode)
 | 
				
			||||||
    // is not in a table.  If it is, let's force the paste to deal with table elements
 | 
					 | 
				
			||||||
    // right away, so that it doesn't orphan some table contents outside the table.
 | 
					 | 
				
			||||||
    if (bHaveTableGuts)
 | 
					 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
      nsCOMPtr<nsISupports> isupports = nodeList->ElementAt(0);
 | 
					        isupports = do_QueryInterface(replaceNode);
 | 
				
			||||||
      nsCOMPtr<nsIDOMNode> curNode( do_QueryInterface(isupports) );
 | 
					 | 
				
			||||||
      if (!nsHTMLEditUtils::IsTableElement(curNode))
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        nsCOMPtr<nsIDOMNode> parent, tmp;
 | 
					 | 
				
			||||||
        curNode->GetParentNode(getter_AddRefs(parent));
 | 
					 | 
				
			||||||
        while (parent)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          if (nsHTMLEditUtils::IsTableElement(parent))
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            isupports = do_QueryInterface(parent);
 | 
					 | 
				
			||||||
        nodeList->ReplaceElementAt(isupports, 0);
 | 
					        nodeList->ReplaceElementAt(isupports, 0);
 | 
				
			||||||
        // postprocess list to remove any descendants of this node
 | 
					        // postprocess list to remove any descendants of this node
 | 
				
			||||||
        // so that we dont insert them twice.
 | 
					        // so that we dont insert them twice.
 | 
				
			||||||
| 
						 | 
					@ -2702,55 +2815,18 @@ printf ("Child count %d\n", bar);
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          isupports = nodeList->ElementAt(1);
 | 
					          isupports = nodeList->ElementAt(1);
 | 
				
			||||||
          tmp = do_QueryInterface(isupports);
 | 
					          tmp = do_QueryInterface(isupports);
 | 
				
			||||||
              if (nsHTMLEditUtils::IsDescendantOf(tmp, parent))
 | 
					          if (tmp && nsHTMLEditUtils::IsDescendantOf(tmp, replaceNode))
 | 
				
			||||||
            nodeList->RemoveElementAt(1);
 | 
					            nodeList->RemoveElementAt(1);
 | 
				
			||||||
          else
 | 
					          else
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        } while(tmp);
 | 
					        } while(tmp);
 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          parent->GetParentNode(getter_AddRefs(curNode));
 | 
					 | 
				
			||||||
          parent = curNode;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // same story as above, only for pieces of lists.
 | 
					 | 
				
			||||||
    if (bHaveListGuts)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      nsCOMPtr<nsISupports> isupports = nodeList->ElementAt(0);
 | 
					 | 
				
			||||||
      nsCOMPtr<nsIDOMNode> curNode( do_QueryInterface(isupports) );
 | 
					 | 
				
			||||||
      if (!nsHTMLEditUtils::IsListItem(curNode))
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        nsCOMPtr<nsIDOMNode> parent;
 | 
					 | 
				
			||||||
        curNode->GetParentNode(getter_AddRefs(parent));
 | 
					 | 
				
			||||||
        while (parent)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          if (nsHTMLEditUtils::IsListItem(parent))
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            isupports = do_QueryInterface(parent);
 | 
					 | 
				
			||||||
            nodeList->ReplaceElementAt(isupports, 0);
 | 
					 | 
				
			||||||
            // postprocess list to remove any descendants of this node
 | 
					 | 
				
			||||||
            // so that we dont insert them twice.
 | 
					 | 
				
			||||||
            do
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              isupports = nodeList->ElementAt(1);
 | 
					 | 
				
			||||||
              tmp = do_QueryInterface(isupports);
 | 
					 | 
				
			||||||
              if (nsHTMLEditUtils::IsDescendantOf(tmp, parent))
 | 
					 | 
				
			||||||
                nodeList->RemoveElementAt(1);
 | 
					 | 
				
			||||||
              else
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            } while(tmp);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          parent->GetParentNode(getter_AddRefs(curNode));
 | 
					 | 
				
			||||||
          parent = curNode;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Loop over the node list and paste the nodes:
 | 
					    // Loop over the node list and paste the nodes:
 | 
				
			||||||
    PRBool bDidInsert = PR_FALSE;
 | 
					    PRBool bDidInsert = PR_FALSE;
 | 
				
			||||||
    nsCOMPtr<nsIDOMNode> lastInsertNode, insertedContextParent;
 | 
					    nsCOMPtr<nsIDOMNode> lastInsertNode, insertedContextParent;
 | 
				
			||||||
 | 
					    nodeList->Count(&listCount);
 | 
				
			||||||
    for (j=0; j<listCount; j++)
 | 
					    for (j=0; j<listCount; j++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      nsCOMPtr<nsISupports> isupports = nodeList->ElementAt(j);
 | 
					      nsCOMPtr<nsISupports> isupports = nodeList->ElementAt(j);
 | 
				
			||||||
| 
						 | 
					@ -6147,8 +6223,6 @@ NS_IMETHODIMP nsHTMLEditor::OutputToString(nsAWritableString& aOutputString,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (nsHTMLEditUtils::IsBody(rootElement))
 | 
					    else if (nsHTMLEditUtils::IsBody(rootElement))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      nsresult rv = NS_OK;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      nsCOMPtr<nsIDocumentEncoder> encoder;
 | 
					      nsCOMPtr<nsIDocumentEncoder> encoder;
 | 
				
			||||||
      nsCAutoString formatType(NS_DOC_ENCODER_CONTRACTID_BASE);
 | 
					      nsCAutoString formatType(NS_DOC_ENCODER_CONTRACTID_BASE);
 | 
				
			||||||
      formatType.AppendWithConversion(aFormatType);
 | 
					      formatType.AppendWithConversion(aFormatType);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,8 +84,8 @@ public:
 | 
				
			||||||
    // (Probably not well tested for HTML output.)
 | 
					    // (Probably not well tested for HTML output.)
 | 
				
			||||||
    OutputFormatted     = 2,
 | 
					    OutputFormatted     = 2,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // OutputNoDoctype is obsolete, flag 4 available for other uses
 | 
					    // OutputRaw is used by copying text from widgets
 | 
				
			||||||
    //OutputNoDoctype     = 4,
 | 
					    OutputRaw           = 4,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // No html head tags
 | 
					    // No html head tags
 | 
				
			||||||
    OutputBodyOnly      = 8,
 | 
					    OutputBodyOnly      = 8,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,7 @@
 | 
				
			||||||
#include "nsIComponentManager.h" 
 | 
					#include "nsIComponentManager.h" 
 | 
				
			||||||
#include "nsIServiceManager.h"
 | 
					#include "nsIServiceManager.h"
 | 
				
			||||||
#include "nsIDocument.h"
 | 
					#include "nsIDocument.h"
 | 
				
			||||||
 | 
					#include "nsIHTMLDocument.h"
 | 
				
			||||||
#include "nsISelection.h"
 | 
					#include "nsISelection.h"
 | 
				
			||||||
#include "nsCOMPtr.h"
 | 
					#include "nsCOMPtr.h"
 | 
				
			||||||
#include "nsIContentSerializer.h"
 | 
					#include "nsIContentSerializer.h"
 | 
				
			||||||
| 
						 | 
					@ -48,6 +49,7 @@
 | 
				
			||||||
#include "nsITextContent.h"
 | 
					#include "nsITextContent.h"
 | 
				
			||||||
#include "nsIEnumerator.h"
 | 
					#include "nsIEnumerator.h"
 | 
				
			||||||
#include "nsISelectionPrivate.h"
 | 
					#include "nsISelectionPrivate.h"
 | 
				
			||||||
 | 
					#include "nsIFrameSelection.h"
 | 
				
			||||||
#include "nsIContentIterator.h"
 | 
					#include "nsIContentIterator.h"
 | 
				
			||||||
#include "nsISupportsArray.h"
 | 
					#include "nsISupportsArray.h"
 | 
				
			||||||
#include "nsIParserService.h"
 | 
					#include "nsIParserService.h"
 | 
				
			||||||
| 
						 | 
					@ -58,6 +60,7 @@ static NS_DEFINE_CID(kCharsetConverterManagerCID,
 | 
				
			||||||
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
 | 
					static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
nsresult NS_NewContentSubtreeIterator(nsIContentIterator** aInstancePtrResult);
 | 
					nsresult NS_NewContentSubtreeIterator(nsIContentIterator** aInstancePtrResult);
 | 
				
			||||||
 | 
					nsresult NS_NewDomSelection(nsISelection **aDomSelection);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum nsRangeIterationDirection {
 | 
					enum nsRangeIterationDirection {
 | 
				
			||||||
  kDirectionOut = -1,
 | 
					  kDirectionOut = -1,
 | 
				
			||||||
| 
						 | 
					@ -104,8 +107,9 @@ protected:
 | 
				
			||||||
  nsresult SerializeRangeToString(nsIDOMRange *aRange,
 | 
					  nsresult SerializeRangeToString(nsIDOMRange *aRange,
 | 
				
			||||||
                                  nsAWritableString& aOutputString);
 | 
					                                  nsAWritableString& aOutputString);
 | 
				
			||||||
  nsresult SerializeRangeNodes(nsIDOMRange* aRange, 
 | 
					  nsresult SerializeRangeNodes(nsIDOMRange* aRange, 
 | 
				
			||||||
                               nsIDOMNode* aCommonParent, 
 | 
					                               nsIDOMNode* aNode, 
 | 
				
			||||||
                               nsAWritableString& aString);
 | 
					                               nsAWritableString& aString,
 | 
				
			||||||
 | 
					                               PRInt32 aDepth);
 | 
				
			||||||
  nsresult SerializeRangeContextStart(const nsVoidArray& aAncestorArray,
 | 
					  nsresult SerializeRangeContextStart(const nsVoidArray& aAncestorArray,
 | 
				
			||||||
                                      nsAWritableString& aString);
 | 
					                                      nsAWritableString& aString);
 | 
				
			||||||
  nsresult SerializeRangeContextEnd(const nsVoidArray& aAncestorArray,
 | 
					  nsresult SerializeRangeContextEnd(const nsVoidArray& aAncestorArray,
 | 
				
			||||||
| 
						 | 
					@ -124,6 +128,7 @@ protected:
 | 
				
			||||||
  nsCOMPtr<nsIOutputStream>      mStream;
 | 
					  nsCOMPtr<nsIOutputStream>      mStream;
 | 
				
			||||||
  nsCOMPtr<nsIContentSerializer> mSerializer;
 | 
					  nsCOMPtr<nsIContentSerializer> mSerializer;
 | 
				
			||||||
  nsCOMPtr<nsIUnicodeEncoder>    mUnicodeEncoder;
 | 
					  nsCOMPtr<nsIUnicodeEncoder>    mUnicodeEncoder;
 | 
				
			||||||
 | 
					  nsCOMPtr<nsIDOMNode>           mCommonParent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  nsString          mMimeType;
 | 
					  nsString          mMimeType;
 | 
				
			||||||
  nsString          mCharset;
 | 
					  nsString          mCharset;
 | 
				
			||||||
| 
						 | 
					@ -131,8 +136,14 @@ protected:
 | 
				
			||||||
  PRUint32          mWrapColumn;
 | 
					  PRUint32          mWrapColumn;
 | 
				
			||||||
  PRUint32          mStartDepth;
 | 
					  PRUint32          mStartDepth;
 | 
				
			||||||
  PRUint32          mEndDepth;
 | 
					  PRUint32          mEndDepth;
 | 
				
			||||||
 | 
					  PRInt32           mStartRootIndex;
 | 
				
			||||||
 | 
					  PRInt32           mEndRootIndex;
 | 
				
			||||||
  PRBool            mHaltRangeHint;  
 | 
					  PRBool            mHaltRangeHint;  
 | 
				
			||||||
  nsVoidArray       mCommonAncestors;
 | 
					  nsVoidArray       mCommonAncestors;
 | 
				
			||||||
 | 
					  nsVoidArray       mStartNodes;
 | 
				
			||||||
 | 
					  nsVoidArray       mStartOffsets;
 | 
				
			||||||
 | 
					  nsVoidArray       mEndNodes;
 | 
				
			||||||
 | 
					  nsVoidArray       mEndOffsets;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef XP_MAC
 | 
					#ifdef XP_MAC
 | 
				
			||||||
| 
						 | 
					@ -566,25 +577,33 @@ static nsresult GetLengthOfDOMNode(nsIDOMNode *aNode, PRUint32 &aCount)
 | 
				
			||||||
nsresult
 | 
					nsresult
 | 
				
			||||||
nsDocumentEncoder::SerializeRangeNodes(nsIDOMRange* aRange, 
 | 
					nsDocumentEncoder::SerializeRangeNodes(nsIDOMRange* aRange, 
 | 
				
			||||||
                                       nsIDOMNode* aNode, 
 | 
					                                       nsIDOMNode* aNode, 
 | 
				
			||||||
                                       nsAWritableString& aString)
 | 
					                                       nsAWritableString& aString,
 | 
				
			||||||
 | 
					                                       PRInt32 aDepth)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
 | 
					  nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
 | 
				
			||||||
  NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
 | 
					  NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (IsNodeIntersectsRange(content, aRange))
 | 
					  nsresult rv=NS_OK;
 | 
				
			||||||
  {
 | 
					  
 | 
				
			||||||
    PRBool nodeBefore, nodeAfter;
 | 
					  // get start and end nodes for this recursion level
 | 
				
			||||||
    nsresult rv = CompareNodeToRange(content, aRange, &nodeBefore, &nodeAfter);
 | 
					  nsCOMPtr<nsIContent> startNode, endNode;
 | 
				
			||||||
    if (!nodeBefore && !nodeAfter) // node completely contained
 | 
					  startNode = NS_STATIC_CAST(nsIContent *, mStartNodes[mStartRootIndex - aDepth]);
 | 
				
			||||||
 | 
					  endNode   = NS_STATIC_CAST(nsIContent *, mEndNodes[mEndRootIndex - aDepth]);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  if ((startNode != content) && (endNode != content))
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
 | 
					    // node is completely contained in range.  Serialize the whole subtree
 | 
				
			||||||
 | 
					    // rooted by this node.
 | 
				
			||||||
    rv = SerializeToStringRecursive(aNode, aString);
 | 
					    rv = SerializeToStringRecursive(aNode, aString);
 | 
				
			||||||
    NS_ENSURE_SUCCESS(rv, rv);
 | 
					    NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
    else // node intersects range, but is not contained.  recurse if needed.
 | 
					  else
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
 | 
					    // due to implementation it is impossible for text node to be both start and end of 
 | 
				
			||||||
 | 
					    // range.  We would have handled that case without getting here.
 | 
				
			||||||
    if (IsTextNode(aNode))
 | 
					    if (IsTextNode(aNode))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (nodeBefore)
 | 
					      if (startNode == content)
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        PRInt32 startOffset;
 | 
					        PRInt32 startOffset;
 | 
				
			||||||
        aRange->GetStartOffset(&startOffset);
 | 
					        aRange->GetStartOffset(&startOffset);
 | 
				
			||||||
| 
						 | 
					@ -600,6 +619,8 @@ nsDocumentEncoder::SerializeRangeNodes(nsIDOMRange* aRange,
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      if (aNode != mCommonParent.get())
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        if (IncludeInContext(aNode))
 | 
					        if (IncludeInContext(aNode))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -607,22 +628,59 @@ nsDocumentEncoder::SerializeRangeNodes(nsIDOMRange* aRange,
 | 
				
			||||||
          // so paste client will include this node in paste.
 | 
					          // so paste client will include this node in paste.
 | 
				
			||||||
          mHaltRangeHint = PR_TRUE;
 | 
					          mHaltRangeHint = PR_TRUE;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (nodeBefore && !mHaltRangeHint) mStartDepth++;
 | 
					        if ((startNode == content) && !mHaltRangeHint) mStartDepth++;
 | 
				
			||||||
        if (nodeAfter && !mHaltRangeHint) mEndDepth++;
 | 
					        if ((endNode == content) && !mHaltRangeHint) mEndDepth++;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
 | 
					        // serialize the start of this node
 | 
				
			||||||
        rv = SerializeNodeStart(aNode, 0, -1, aString);
 | 
					        rv = SerializeNodeStart(aNode, 0, -1, aString);
 | 
				
			||||||
        NS_ENSURE_SUCCESS(rv, rv);
 | 
					        NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
      
 | 
					 | 
				
			||||||
        nsCOMPtr<nsIDOMNode> child, tmp;
 | 
					 | 
				
			||||||
        aNode->GetFirstChild(getter_AddRefs(child));
 | 
					 | 
				
			||||||
        while (child)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          rv = SerializeRangeNodes(aRange, child, aString);
 | 
					 | 
				
			||||||
          NS_ENSURE_SUCCESS(rv, rv);
 | 
					 | 
				
			||||||
          child->GetNextSibling(getter_AddRefs(tmp));
 | 
					 | 
				
			||||||
          child = tmp;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
 | 
					      // do some calculations that will tell us which children of this node are in the range.
 | 
				
			||||||
 | 
					      nsCOMPtr<nsIContent> child;
 | 
				
			||||||
 | 
					      nsCOMPtr<nsIDOMNode> childAsNode;
 | 
				
			||||||
 | 
					      PRInt32 startOffset = 0, endOffset = -1;
 | 
				
			||||||
 | 
					      if (startNode == content)
 | 
				
			||||||
 | 
					        startOffset = NS_REINTERPRET_CAST(PRInt32, mStartOffsets[mStartRootIndex - aDepth]);
 | 
				
			||||||
 | 
					      if (endNode == content)
 | 
				
			||||||
 | 
					        endOffset = NS_REINTERPRET_CAST(PRInt32, mEndOffsets[mEndRootIndex - aDepth]);
 | 
				
			||||||
 | 
					      // generated content will cause offset values of -1 to be returned.  
 | 
				
			||||||
 | 
					      PRInt32 j, childCount=0;
 | 
				
			||||||
 | 
					      rv = content->ChildCount(childCount);
 | 
				
			||||||
 | 
					      NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					      if (startOffset == -1) startOffset = 0;
 | 
				
			||||||
 | 
					      if (endOffset == -1) endOffset = childCount;
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        // if we are at the "tip" of the selection, endOffset is fine.
 | 
				
			||||||
 | 
					        // otherwise, we need to add one.  This is because of the semantics
 | 
				
			||||||
 | 
					        // of the offset list created by GetAncestorsAndOffsets().  The
 | 
				
			||||||
 | 
					        // intermediate points on the list use the endOffset of the 
 | 
				
			||||||
 | 
					        // location of the ancestor, rather than just past it.  So we need
 | 
				
			||||||
 | 
					        // to add one here in order to include it in the children we serialize.
 | 
				
			||||||
 | 
					        nsCOMPtr<nsIDOMNode> endParent;
 | 
				
			||||||
 | 
					        aRange->GetEndContainer(getter_AddRefs(endParent));
 | 
				
			||||||
 | 
					        if (aNode != endParent.get())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          endOffset++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      // serialize the children of this node that are in the range
 | 
				
			||||||
 | 
					      for (j=startOffset; j<endOffset; j++)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        rv = content->ChildAt(j, *getter_AddRefs(child));
 | 
				
			||||||
 | 
					        childAsNode = do_QueryInterface(child);
 | 
				
			||||||
 | 
					        NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					        if ((j==startOffset) || (j==endOffset-1))
 | 
				
			||||||
 | 
					          rv = SerializeRangeNodes(aRange, childAsNode, aString, aDepth+1);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					          rv = SerializeToStringRecursive(childAsNode, aString);
 | 
				
			||||||
 | 
					        NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // serialize the end of this node
 | 
				
			||||||
 | 
					      if (aNode != mCommonParent.get())
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
        rv = SerializeNodeEnd(aNode, aString);
 | 
					        rv = SerializeNodeEnd(aNode, aString);
 | 
				
			||||||
        NS_ENSURE_SUCCESS(rv, rv); 
 | 
					        NS_ENSURE_SUCCESS(rv, rv); 
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
| 
						 | 
					@ -693,15 +751,15 @@ nsDocumentEncoder::SerializeRangeToString(nsIDOMRange *aRange,
 | 
				
			||||||
  if (collapsed)
 | 
					  if (collapsed)
 | 
				
			||||||
    return NS_OK;
 | 
					    return NS_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  nsCOMPtr<nsIDOMNode> commonParent, startParent, endParent;
 | 
					  nsCOMPtr<nsIDOMNode> startParent, endParent;
 | 
				
			||||||
  PRInt32 startOffset, endOffset;
 | 
					  PRInt32 startOffset, endOffset;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  aRange->GetCommonAncestorContainer(getter_AddRefs(commonParent));
 | 
					  aRange->GetCommonAncestorContainer(getter_AddRefs(mCommonParent));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!commonParent)
 | 
					  if (!mCommonParent)
 | 
				
			||||||
    return NS_OK;
 | 
					    return NS_OK;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  AdjustCommonParent(&commonParent);
 | 
					  AdjustCommonParent(&mCommonParent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  aRange->GetStartContainer(getter_AddRefs(startParent));
 | 
					  aRange->GetStartContainer(getter_AddRefs(startParent));
 | 
				
			||||||
  NS_ENSURE_TRUE(startParent, NS_ERROR_FAILURE);
 | 
					  NS_ENSURE_TRUE(startParent, NS_ERROR_FAILURE);
 | 
				
			||||||
| 
						 | 
					@ -712,8 +770,17 @@ nsDocumentEncoder::SerializeRangeToString(nsIDOMRange *aRange,
 | 
				
			||||||
  aRange->GetEndOffset(&endOffset);
 | 
					  aRange->GetEndOffset(&endOffset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mCommonAncestors.Clear();
 | 
					  mCommonAncestors.Clear();
 | 
				
			||||||
 | 
					  mStartNodes.Clear();
 | 
				
			||||||
 | 
					  mStartOffsets.Clear();
 | 
				
			||||||
 | 
					  mEndNodes.Clear();
 | 
				
			||||||
 | 
					  mEndOffsets.Clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  nsRange::FillArrayWithAncestors(&mCommonAncestors, commonParent);
 | 
					  nsRange::FillArrayWithAncestors(&mCommonAncestors, mCommonParent);
 | 
				
			||||||
 | 
					  nsRange::GetAncestorsAndOffsets(startParent, startOffset, &mStartNodes, &mStartOffsets);
 | 
				
			||||||
 | 
					  nsRange::GetAncestorsAndOffsets(endParent, endOffset, &mEndNodes, &mEndOffsets);
 | 
				
			||||||
 | 
					  nsCOMPtr<nsIContent> commonContent = do_QueryInterface(mCommonParent);
 | 
				
			||||||
 | 
					  mStartRootIndex = mStartNodes.IndexOf(commonContent);
 | 
				
			||||||
 | 
					  mEndRootIndex = mEndNodes.IndexOf(commonContent);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  nsresult rv = NS_OK;
 | 
					  nsresult rv = NS_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -727,17 +794,9 @@ nsDocumentEncoder::SerializeRangeToString(nsIDOMRange *aRange,
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    nsCOMPtr<nsIDOMNode> child, tmp;
 | 
					    rv = SerializeRangeNodes(aRange, mCommonParent, aOutputString, 0);
 | 
				
			||||||
    commonParent->GetFirstChild(getter_AddRefs(child));
 | 
					 | 
				
			||||||
    while (child)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      rv = SerializeRangeNodes(aRange, child, aOutputString);
 | 
					 | 
				
			||||||
    NS_ENSURE_SUCCESS(rv, rv);
 | 
					    NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
      child->GetNextSibling(getter_AddRefs(tmp));
 | 
					 | 
				
			||||||
      child = tmp;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  rv = SerializeRangeContextEnd(mCommonAncestors, aOutputString);
 | 
					  rv = SerializeRangeContextEnd(mCommonAncestors, aOutputString);
 | 
				
			||||||
  NS_ENSURE_SUCCESS(rv, rv);
 | 
					  NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -888,12 +947,14 @@ protected:
 | 
				
			||||||
  nsCOMPtr<nsIDOMNode> GetChildAt(nsIDOMNode *aParent, PRInt32 aOffset);
 | 
					  nsCOMPtr<nsIDOMNode> GetChildAt(nsIDOMNode *aParent, PRInt32 aOffset);
 | 
				
			||||||
  PRBool IsMozBR(nsIDOMNode* aNode);
 | 
					  PRBool IsMozBR(nsIDOMNode* aNode);
 | 
				
			||||||
  nsresult GetNodeLocation(nsIDOMNode *inChild, nsCOMPtr<nsIDOMNode> *outParent, PRInt32 *outOffset);
 | 
					  nsresult GetNodeLocation(nsIDOMNode *inChild, nsCOMPtr<nsIDOMNode> *outParent, PRInt32 *outOffset);
 | 
				
			||||||
 | 
					  PRBool IsRoot(nsIDOMNode* aNode);
 | 
				
			||||||
  PRBool IsFirstNode(nsIDOMNode *aNode);
 | 
					  PRBool IsFirstNode(nsIDOMNode *aNode);
 | 
				
			||||||
  PRBool IsLastNode(nsIDOMNode *aNode);
 | 
					  PRBool IsLastNode(nsIDOMNode *aNode);
 | 
				
			||||||
  PRBool IsEmptyTextContent(nsIDOMNode* aNode);
 | 
					  PRBool IsEmptyTextContent(nsIDOMNode* aNode);
 | 
				
			||||||
  virtual PRBool IncludeInContext(nsIDOMNode *aNode);
 | 
					  virtual PRBool IncludeInContext(nsIDOMNode *aNode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  nsCOMPtr<nsIParserService> mParserService;
 | 
					  nsCOMPtr<nsIParserService> mParserService;
 | 
				
			||||||
 | 
					  PRBool mIsTextWidget;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef XP_MAC
 | 
					#ifdef XP_MAC
 | 
				
			||||||
| 
						 | 
					@ -903,6 +964,7 @@ protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
nsHTMLCopyEncoder::nsHTMLCopyEncoder()
 | 
					nsHTMLCopyEncoder::nsHTMLCopyEncoder()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  mIsTextWidget = PR_FALSE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
nsHTMLCopyEncoder::~nsHTMLCopyEncoder()
 | 
					nsHTMLCopyEncoder::~nsHTMLCopyEncoder()
 | 
				
			||||||
| 
						 | 
					@ -911,7 +973,7 @@ nsHTMLCopyEncoder::~nsHTMLCopyEncoder()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NS_IMETHODIMP
 | 
					NS_IMETHODIMP
 | 
				
			||||||
nsHTMLCopyEncoder::Init(nsIDocument* aDocument,
 | 
					nsHTMLCopyEncoder::Init(nsIDocument* aDocument,
 | 
				
			||||||
                        const nsAReadableString& aIgnored,
 | 
					                        const nsAReadableString& aMimetype,
 | 
				
			||||||
                        PRUint32 aFlags)
 | 
					                        PRUint32 aFlags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (!aDocument)
 | 
					  if (!aDocument)
 | 
				
			||||||
| 
						 | 
					@ -931,19 +993,50 @@ nsHTMLCopyEncoder::Init(nsIDocument* aDocument,
 | 
				
			||||||
NS_IMETHODIMP
 | 
					NS_IMETHODIMP
 | 
				
			||||||
nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection)
 | 
					nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  // normalize selection
 | 
					  // check for text widgets: we need to recognize these so that
 | 
				
			||||||
 | 
					  // we don't tweak the selection to be outside of the magic
 | 
				
			||||||
 | 
					  // div that ender-lite text widgets are embedded in.
 | 
				
			||||||
 | 
					  nsCOMPtr<nsIDOMNode> selNode;
 | 
				
			||||||
 | 
					  nsresult rv = aSelection->GetFocusNode(getter_AddRefs(selNode));
 | 
				
			||||||
 | 
					  NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					  nsCOMPtr<nsIContent> tmp, selContent( do_QueryInterface(selNode) );
 | 
				
			||||||
 | 
					  while (selContent)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    nsCOMPtr<nsIAtom> atom;
 | 
				
			||||||
 | 
					    selContent->GetTag(*getter_AddRefs(atom));
 | 
				
			||||||
 | 
					    if (atom.get() == nsHTMLAtoms::input ||
 | 
				
			||||||
 | 
					        atom.get() == nsHTMLAtoms::textarea)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      mIsTextWidget = PR_TRUE;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    selContent->GetParent(*getter_AddRefs(tmp));
 | 
				
			||||||
 | 
					    selContent = tmp;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // also consider ourselves in a text widget if we can't find an html document
 | 
				
			||||||
 | 
					  nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
 | 
				
			||||||
 | 
					  if (!htmlDoc) mIsTextWidget = PR_TRUE;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // normalize selection if we are not in a widget
 | 
				
			||||||
 | 
					  if (mIsTextWidget) 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    mSelection = aSelection;
 | 
				
			||||||
 | 
					    mFlags |= OutputRaw;
 | 
				
			||||||
 | 
					    return NS_OK;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // there's no Clone() for selection! fix...
 | 
					  // there's no Clone() for selection! fix...
 | 
				
			||||||
  //nsresult rv = aSelection->Clone(getter_AddRefs(mSelection);
 | 
					  //nsresult rv = aSelection->Clone(getter_AddRefs(mSelection);
 | 
				
			||||||
  //NS_ENSURE_SUCCESS(rv, rv);
 | 
					  //NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
  mSelection = aSelection;
 | 
					  NS_NewDomSelection(getter_AddRefs(mSelection));
 | 
				
			||||||
  
 | 
					  NS_ENSURE_TRUE(mSelection, NS_ERROR_FAILURE);
 | 
				
			||||||
  nsCOMPtr<nsISelectionPrivate> privSelection = do_QueryInterface(mSelection);
 | 
					  nsCOMPtr<nsISelectionPrivate> privSelection( do_QueryInterface(aSelection) );
 | 
				
			||||||
  NS_ENSURE_TRUE(privSelection, NS_ERROR_FAILURE);
 | 
					  NS_ENSURE_TRUE(privSelection, NS_ERROR_FAILURE);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // get selection range enumerator
 | 
					  // get selection range enumerator
 | 
				
			||||||
  nsCOMPtr<nsIEnumerator> enumerator;
 | 
					  nsCOMPtr<nsIEnumerator> enumerator;
 | 
				
			||||||
  nsresult rv = privSelection->GetEnumerator(getter_AddRefs(enumerator));
 | 
					  rv = privSelection->GetEnumerator(getter_AddRefs(enumerator));
 | 
				
			||||||
  NS_ENSURE_SUCCESS(rv, rv);
 | 
					  NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
  NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
 | 
					  NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -957,9 +1050,16 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection)
 | 
				
			||||||
    NS_ENSURE_TRUE(currentItem, NS_ERROR_FAILURE);
 | 
					    NS_ENSURE_TRUE(currentItem, NS_ERROR_FAILURE);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
 | 
					    nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
 | 
				
			||||||
 | 
					    NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
 | 
				
			||||||
 | 
					    nsCOMPtr<nsIDOMRange> myRange;
 | 
				
			||||||
 | 
					    range->CloneRange(getter_AddRefs(myRange));
 | 
				
			||||||
 | 
					    NS_ENSURE_TRUE(myRange, NS_ERROR_FAILURE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // adjust range to include any ancestors who's children are entirely selected
 | 
					    // adjust range to include any ancestors who's children are entirely selected
 | 
				
			||||||
    rv = PromoteRange(range);
 | 
					    rv = PromoteRange(myRange);
 | 
				
			||||||
 | 
					    NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    rv = mSelection->AddRange(myRange);
 | 
				
			||||||
    NS_ENSURE_SUCCESS(rv, rv);
 | 
					    NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enumerator->Next();
 | 
					    enumerator->Next();
 | 
				
			||||||
| 
						 | 
					@ -976,6 +1076,16 @@ nsHTMLCopyEncoder::EncodeToStringWithContext(nsAWritableString& aEncodedString,
 | 
				
			||||||
  nsresult rv = EncodeToString(aEncodedString);
 | 
					  nsresult rv = EncodeToString(aEncodedString);
 | 
				
			||||||
  NS_ENSURE_SUCCESS(rv, rv);
 | 
					  NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (mIsTextWidget) {
 | 
				
			||||||
 | 
					    aEncodedString.Insert(NS_LITERAL_STRING("<pre>"), 0);
 | 
				
			||||||
 | 
					    aEncodedString.Append(NS_LITERAL_STRING("</pre>"));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // do not encode any context info or range hints if we are not in an html document.
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // do not encode any context info or range hints if we are in a text widget.
 | 
				
			||||||
 | 
					  if (mIsTextWidget) return NS_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // now encode common ancestors into aContextString.  Note that the common ancestors
 | 
					  // now encode common ancestors into aContextString.  Note that the common ancestors
 | 
				
			||||||
  // will be for the last range in the selection in the case of multirange selections.
 | 
					  // will be for the last range in the selection in the case of multirange selections.
 | 
				
			||||||
  // encoding ancestors every range in a multirange selection in a way that could be 
 | 
					  // encoding ancestors every range in a multirange selection in a way that could be 
 | 
				
			||||||
| 
						 | 
					@ -1126,12 +1236,12 @@ nsHTMLCopyEncoder::GetPromotedPoint(Endpoint aWhere, nsIDOMNode *aNode, PRInt32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // finding the real start for this point.  look up the tree for as long as we are the 
 | 
					    // finding the real start for this point.  look up the tree for as long as we are the 
 | 
				
			||||||
    // first node in the container, and as long as we haven't hit the body node.
 | 
					    // first node in the container, and as long as we haven't hit the body node.
 | 
				
			||||||
    if (!IsTag(node, nsHTMLAtoms::body))
 | 
					    if (!IsRoot(node))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      rv = GetNodeLocation(node, &parent, &offset);
 | 
					      rv = GetNodeLocation(node, &parent, &offset);
 | 
				
			||||||
      NS_ENSURE_SUCCESS(rv, rv);
 | 
					      NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
      if (offset == -1) return NS_OK; // we hit generated content; STOP
 | 
					      if (offset == -1) return NS_OK; // we hit generated content; STOP
 | 
				
			||||||
      while ((IsFirstNode(node)) && (!IsTag(parent, nsHTMLAtoms::body)))
 | 
					      while ((IsFirstNode(node)) && (!IsRoot(parent)))
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        if (bResetPromotion)
 | 
					        if (bResetPromotion)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -1211,12 +1321,12 @@ nsHTMLCopyEncoder::GetPromotedPoint(Endpoint aWhere, nsIDOMNode *aNode, PRInt32
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // finding the real end for this point.  look up the tree for as long as we are the 
 | 
					    // finding the real end for this point.  look up the tree for as long as we are the 
 | 
				
			||||||
    // last node in the container, and as long as we haven't hit the body node.
 | 
					    // last node in the container, and as long as we haven't hit the body node.
 | 
				
			||||||
    if (!IsTag(node, nsHTMLAtoms::body))
 | 
					    if (!IsRoot(node))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      rv = GetNodeLocation(node, &parent, &offset);
 | 
					      rv = GetNodeLocation(node, &parent, &offset);
 | 
				
			||||||
      NS_ENSURE_SUCCESS(rv, rv);
 | 
					      NS_ENSURE_SUCCESS(rv, rv);
 | 
				
			||||||
      if (offset == -1) return NS_OK; // we hit generated content; STOP
 | 
					      if (offset == -1) return NS_OK; // we hit generated content; STOP
 | 
				
			||||||
      while ((IsLastNode(node)) && (!IsTag(parent, nsHTMLAtoms::body)))
 | 
					      while ((IsLastNode(node)) && (!IsRoot(parent)))
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        if (bResetPromotion)
 | 
					        if (bResetPromotion)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -1325,6 +1435,19 @@ nsHTMLCopyEncoder::GetNodeLocation(nsIDOMNode *inChild, nsCOMPtr<nsIDOMNode> *ou
 | 
				
			||||||
  return result;
 | 
					  return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PRBool
 | 
				
			||||||
 | 
					nsHTMLCopyEncoder::IsRoot(nsIDOMNode* aNode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (aNode)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    if (mIsTextWidget) 
 | 
				
			||||||
 | 
					      return (IsTag(aNode, nsHTMLAtoms::div));
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      return (IsTag(aNode, nsHTMLAtoms::body));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return PR_FALSE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PRBool
 | 
					PRBool
 | 
				
			||||||
nsHTMLCopyEncoder::IsFirstNode(nsIDOMNode *aNode)
 | 
					nsHTMLCopyEncoder::IsFirstNode(nsIDOMNode *aNode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,7 @@
 | 
				
			||||||
#include "nsHTMLAtoms.h"
 | 
					#include "nsHTMLAtoms.h"
 | 
				
			||||||
#include "nsIURI.h"
 | 
					#include "nsIURI.h"
 | 
				
			||||||
#include "nsNetUtil.h"
 | 
					#include "nsNetUtil.h"
 | 
				
			||||||
 | 
					#include "nsEscape.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
 | 
					static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
 | 
				
			||||||
static NS_DEFINE_CID(kEntityConverterCID, NS_ENTITYCONVERTER_CID);
 | 
					static NS_DEFINE_CID(kEntityConverterCID, NS_ENTITYCONVERTER_CID);
 | 
				
			||||||
| 
						 | 
					@ -68,21 +69,6 @@ nsHTMLContentSerializer::~nsHTMLContentSerializer()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
nsresult
 | 
					 | 
				
			||||||
nsHTMLContentSerializer::GetEntityConverter(nsIEntityConverter** aConverter)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  if (!mEntityConverter) {
 | 
					 | 
				
			||||||
    nsresult rv;
 | 
					 | 
				
			||||||
    rv = nsComponentManager::CreateInstance(kEntityConverterCID, NULL, 
 | 
					 | 
				
			||||||
                                            NS_GET_IID(nsIEntityConverter),
 | 
					 | 
				
			||||||
                                            getter_AddRefs(mEntityConverter));
 | 
					 | 
				
			||||||
    if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  CallQueryInterface(mEntityConverter.get(), aConverter);
 | 
					 | 
				
			||||||
  return NS_OK;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
nsresult
 | 
					nsresult
 | 
				
			||||||
nsHTMLContentSerializer::GetParserService(nsIParserService** aParserService)
 | 
					nsHTMLContentSerializer::GetParserService(nsIParserService** aParserService)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -149,7 +135,8 @@ nsHTMLContentSerializer::AppendText(nsIDOMText* aText,
 | 
				
			||||||
  PRInt32 lastNewlineOffset = kNotFound;
 | 
					  PRInt32 lastNewlineOffset = kNotFound;
 | 
				
			||||||
  PRBool hasLongLines = HasLongLines(data, lastNewlineOffset);
 | 
					  PRBool hasLongLines = HasLongLines(data, lastNewlineOffset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (mPreLevel || (!mDoFormat && !hasLongLines)) {
 | 
					  if (mPreLevel || (!mDoFormat && !hasLongLines) ||
 | 
				
			||||||
 | 
					      (mFlags & nsIDocumentEncoder::OutputRaw)) {
 | 
				
			||||||
    AppendToString(data, aStr);
 | 
					    AppendToString(data, aStr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (lastNewlineOffset != kNotFound) {
 | 
					    if (lastNewlineOffset != kNotFound) {
 | 
				
			||||||
| 
						 | 
					@ -378,7 +365,6 @@ nsHTMLContentSerializer::AppendToStringWrapped(const nsAReadableString& aStr,
 | 
				
			||||||
  PRBool    done = PR_FALSE;
 | 
					  PRBool    done = PR_FALSE;
 | 
				
			||||||
  PRInt32   indx = 0;
 | 
					  PRInt32   indx = 0;
 | 
				
			||||||
  PRInt32   strOffset = 0;
 | 
					  PRInt32   strOffset = 0;
 | 
				
			||||||
  PRInt32   oldLineOffset = 0;
 | 
					 | 
				
			||||||
  PRInt32   lineLength, oldLineEnd;
 | 
					  PRInt32   lineLength, oldLineEnd;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // Make sure we haven't gone too far already
 | 
					  // Make sure we haven't gone too far already
 | 
				
			||||||
| 
						 | 
					@ -468,28 +454,19 @@ nsHTMLContentSerializer::AppendToString(const nsAReadableString& aStr,
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  nsresult rv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (aIncrColumn) {
 | 
					  if (aIncrColumn) {
 | 
				
			||||||
    mColPos += aStr.Length();
 | 
					    mColPos += aStr.Length();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if (aTranslateEntities) {
 | 
					  if (aTranslateEntities) {
 | 
				
			||||||
    nsCOMPtr<nsIEntityConverter> converter;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    GetEntityConverter(getter_AddRefs(converter));
 | 
					 | 
				
			||||||
    if (converter) {
 | 
					 | 
				
			||||||
    PRUnichar *encodedBuffer;
 | 
					    PRUnichar *encodedBuffer;
 | 
				
			||||||
      rv = mEntityConverter->ConvertToEntities(nsPromiseFlatString(aStr),
 | 
					    encodedBuffer = nsEscapeHTML2(nsPromiseFlatString(aStr), aStr.Length());
 | 
				
			||||||
                                               nsIEntityConverter::html40Latin1,
 | 
					    if (encodedBuffer) {
 | 
				
			||||||
                                               &encodedBuffer);
 | 
					 | 
				
			||||||
      if (NS_SUCCEEDED(rv)) {
 | 
					 | 
				
			||||||
      aOutputStr.Append(encodedBuffer);
 | 
					      aOutputStr.Append(encodedBuffer);
 | 
				
			||||||
      nsCRT::free(encodedBuffer);
 | 
					      nsCRT::free(encodedBuffer);
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  aOutputStr.Append(aStr);
 | 
					  aOutputStr.Append(aStr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -513,7 +490,8 @@ PRBool
 | 
				
			||||||
nsHTMLContentSerializer::LineBreakBeforeOpen(nsIAtom* aName, 
 | 
					nsHTMLContentSerializer::LineBreakBeforeOpen(nsIAtom* aName, 
 | 
				
			||||||
                                             PRBool aHasDirtyAttr)
 | 
					                                             PRBool aHasDirtyAttr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel || !mColPos) {
 | 
					  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel || !mColPos ||
 | 
				
			||||||
 | 
					      (mFlags & nsIDocumentEncoder::OutputRaw)) {
 | 
				
			||||||
    return PR_FALSE;
 | 
					    return PR_FALSE;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
| 
						 | 
					@ -548,7 +526,8 @@ PRBool
 | 
				
			||||||
nsHTMLContentSerializer::LineBreakAfterOpen(nsIAtom* aName, 
 | 
					nsHTMLContentSerializer::LineBreakAfterOpen(nsIAtom* aName, 
 | 
				
			||||||
                                            PRBool aHasDirtyAttr)
 | 
					                                            PRBool aHasDirtyAttr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel) {
 | 
					  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel ||
 | 
				
			||||||
 | 
					      (mFlags & nsIDocumentEncoder::OutputRaw)) {
 | 
				
			||||||
    return PR_FALSE;
 | 
					    return PR_FALSE;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -576,7 +555,8 @@ PRBool
 | 
				
			||||||
nsHTMLContentSerializer::LineBreakBeforeClose(nsIAtom* aName, 
 | 
					nsHTMLContentSerializer::LineBreakBeforeClose(nsIAtom* aName, 
 | 
				
			||||||
                                              PRBool aHasDirtyAttr)
 | 
					                                              PRBool aHasDirtyAttr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel || !mColPos) {
 | 
					  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel || !mColPos ||
 | 
				
			||||||
 | 
					      (mFlags & nsIDocumentEncoder::OutputRaw)) {
 | 
				
			||||||
    return PR_FALSE;
 | 
					    return PR_FALSE;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -598,7 +578,8 @@ PRBool
 | 
				
			||||||
nsHTMLContentSerializer::LineBreakAfterClose(nsIAtom* aName, 
 | 
					nsHTMLContentSerializer::LineBreakAfterClose(nsIAtom* aName, 
 | 
				
			||||||
                                             PRBool aHasDirtyAttr)
 | 
					                                             PRBool aHasDirtyAttr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel) {
 | 
					  if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel ||
 | 
				
			||||||
 | 
					      (mFlags & nsIDocumentEncoder::OutputRaw)) {
 | 
				
			||||||
    return PR_FALSE;
 | 
					    return PR_FALSE;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -281,6 +281,9 @@ nsPlainTextSerializer::AppendElementStart(nsIDOMElement *aElement,
 | 
				
			||||||
  mContent = 0;
 | 
					  mContent = 0;
 | 
				
			||||||
  mOutputString = nsnull;
 | 
					  mOutputString = nsnull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!mInHead && id == eHTMLTag_head)
 | 
				
			||||||
 | 
					    mInHead = PR_TRUE;    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return rv;
 | 
					  return rv;
 | 
				
			||||||
} 
 | 
					} 
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
| 
						 | 
					@ -310,6 +313,9 @@ nsPlainTextSerializer::AppendElementEnd(nsIDOMElement *aElement,
 | 
				
			||||||
  mContent = 0;
 | 
					  mContent = 0;
 | 
				
			||||||
  mOutputString = nsnull;
 | 
					  mOutputString = nsnull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (mInHead && id == eHTMLTag_head)
 | 
				
			||||||
 | 
					    mInHead = PR_FALSE;    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return rv;
 | 
					  return rv;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -326,8 +332,6 @@ NS_IMETHODIMP
 | 
				
			||||||
nsPlainTextSerializer::OpenContainer(const nsIParserNode& aNode)
 | 
					nsPlainTextSerializer::OpenContainer(const nsIParserNode& aNode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PRInt32 type = aNode.GetNodeType();
 | 
					  PRInt32 type = aNode.GetNodeType();
 | 
				
			||||||
  const nsString&   namestr = aNode.GetText();
 | 
					 | 
				
			||||||
  nsCOMPtr<nsIAtom> name = dont_AddRef(NS_NewAtom(namestr));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mParserNode = NS_CONST_CAST(nsIParserNode *, &aNode);
 | 
					  mParserNode = NS_CONST_CAST(nsIParserNode *, &aNode);
 | 
				
			||||||
  return DoOpenContainer(type);
 | 
					  return DoOpenContainer(type);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -150,6 +150,8 @@ public:
 | 
				
			||||||
  static PRBool        InSameDoc(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
 | 
					  static PRBool        InSameDoc(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
 | 
				
			||||||
  static PRInt32       IndexOf(nsIDOMNode* aNode);
 | 
					  static PRInt32       IndexOf(nsIDOMNode* aNode);
 | 
				
			||||||
  static PRInt32       FillArrayWithAncestors(nsVoidArray* aArray,nsIDOMNode* aNode);
 | 
					  static PRInt32       FillArrayWithAncestors(nsVoidArray* aArray,nsIDOMNode* aNode);
 | 
				
			||||||
 | 
					  static PRInt32       GetAncestorsAndOffsets(nsIDOMNode* aNode, PRInt32 aOffset,
 | 
				
			||||||
 | 
					                                              nsVoidArray* aAncestorNodes, nsVoidArray* aAncestorOffsets);
 | 
				
			||||||
  static nsCOMPtr<nsIDOMNode>   CommonParent(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
 | 
					  static nsCOMPtr<nsIDOMNode>   CommonParent(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
 | 
				
			||||||
  static nsresult      GetDOMNodeFromContent(nsIContent* inContentNode, nsCOMPtr<nsIDOMNode>* outDomNode);
 | 
					  static nsresult      GetDOMNodeFromContent(nsIContent* inContentNode, nsCOMPtr<nsIDOMNode>* outDomNode);
 | 
				
			||||||
  static nsresult      GetContentFromDOMNode(nsIDOMNode* inDomNode, nsCOMPtr<nsIContent>* outContentNode);
 | 
					  static nsresult      GetContentFromDOMNode(nsIDOMNode* inDomNode, nsCOMPtr<nsIContent>* outContentNode);
 | 
				
			||||||
| 
						 | 
					@ -173,9 +175,6 @@ public:
 | 
				
			||||||
  nsresult      ComparePointToRange(nsIDOMNode* aParent, PRInt32 aOffset, PRInt32* aResult);
 | 
					  nsresult      ComparePointToRange(nsIDOMNode* aParent, PRInt32 aOffset, PRInt32* aResult);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  PRInt32       GetAncestorsAndOffsets(nsIDOMNode* aNode, PRInt32 aOffset,
 | 
					 | 
				
			||||||
                        nsVoidArray* aAncestorNodes, nsVoidArray* aAncestorOffsets);
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  nsresult      AddToListOf(nsIDOMNode* aNode);
 | 
					  nsresult      AddToListOf(nsIDOMNode* aNode);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  nsresult      RemoveFromListOf(nsIDOMNode* aNode);
 | 
					  nsresult      RemoveFromListOf(nsIDOMNode* aNode);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -224,55 +224,51 @@ nsEscapeHTML(const char * string)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NS_COM PRUnichar *
 | 
					NS_COM PRUnichar *
 | 
				
			||||||
nsEscapeHTML2(const PRUnichar * string)
 | 
					nsEscapeHTML2(const PRUnichar *aSourceBuffer, PRInt32 aSourceBufferLen)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PRUnichar *rv = (PRUnichar *) nsMemory::Alloc(nsCRT::strlen(string)*6*sizeof(PRUnichar) + sizeof(PRUnichar));
 | 
					  // if the caller didn't calculate the length
 | 
				
			||||||
	PRUnichar *ptr = rv;
 | 
					  if (aSourceBufferLen == -1) {
 | 
				
			||||||
 | 
					    aSourceBufferLen = nsCRT::strlen(aSourceBuffer); // ...then I will
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(rv)
 | 
					  PRUnichar *resultBuffer = (PRUnichar *)nsMemory::Alloc(aSourceBufferLen*6*sizeof(PRUnichar) + sizeof(PRUnichar('\0')));
 | 
				
			||||||
	  {
 | 
					  PRUnichar *ptr = resultBuffer;
 | 
				
			||||||
		for(; *string != 0; string++)
 | 
					
 | 
				
			||||||
		  {
 | 
					  if (resultBuffer) {
 | 
				
			||||||
			if(*string == '<')
 | 
					    PRInt32 i;
 | 
				
			||||||
			  {
 | 
					
 | 
				
			||||||
 | 
					    for(i = 0; i < aSourceBufferLen; i++) {
 | 
				
			||||||
 | 
					      if(aSourceBuffer[i] == '<') {
 | 
				
			||||||
        *ptr++ = '&';
 | 
					        *ptr++ = '&';
 | 
				
			||||||
        *ptr++ = 'l';
 | 
					        *ptr++ = 'l';
 | 
				
			||||||
        *ptr++ = 't';
 | 
					        *ptr++ = 't';
 | 
				
			||||||
        *ptr++ = ';';
 | 
					        *ptr++ = ';';
 | 
				
			||||||
			  }
 | 
					      } else if(aSourceBuffer[i] == '>') {
 | 
				
			||||||
			else if(*string == '>')
 | 
					 | 
				
			||||||
			  {
 | 
					 | 
				
			||||||
        *ptr++ = '&';
 | 
					        *ptr++ = '&';
 | 
				
			||||||
        *ptr++ = 'g';
 | 
					        *ptr++ = 'g';
 | 
				
			||||||
        *ptr++ = 't';
 | 
					        *ptr++ = 't';
 | 
				
			||||||
        *ptr++ = ';';
 | 
					        *ptr++ = ';';
 | 
				
			||||||
			  }
 | 
					      } else if(aSourceBuffer[i] == '&') {
 | 
				
			||||||
			else if(*string == '&')
 | 
					 | 
				
			||||||
			  {
 | 
					 | 
				
			||||||
        *ptr++ = '&';
 | 
					        *ptr++ = '&';
 | 
				
			||||||
        *ptr++ = 'a';
 | 
					        *ptr++ = 'a';
 | 
				
			||||||
        *ptr++ = 'm';
 | 
					        *ptr++ = 'm';
 | 
				
			||||||
        *ptr++ = 'p';
 | 
					        *ptr++ = 'p';
 | 
				
			||||||
        *ptr++ = ';';
 | 
					        *ptr++ = ';';
 | 
				
			||||||
			  }
 | 
					      } else if (aSourceBuffer[i] == '"') {
 | 
				
			||||||
			else if (*string == '"')
 | 
					 | 
				
			||||||
			  {
 | 
					 | 
				
			||||||
        *ptr++ = '&';
 | 
					        *ptr++ = '&';
 | 
				
			||||||
        *ptr++ = 'q';
 | 
					        *ptr++ = 'q';
 | 
				
			||||||
        *ptr++ = 'u';
 | 
					        *ptr++ = 'u';
 | 
				
			||||||
        *ptr++ = 'o';
 | 
					        *ptr++ = 'o';
 | 
				
			||||||
        *ptr++ = 't';
 | 
					        *ptr++ = 't';
 | 
				
			||||||
        *ptr++ = ';';
 | 
					        *ptr++ = ';';
 | 
				
			||||||
			  }			
 | 
					      } else {
 | 
				
			||||||
			else
 | 
					        *ptr++ = aSourceBuffer[i];
 | 
				
			||||||
			  {
 | 
					 | 
				
			||||||
				*ptr++ = *string;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    *ptr = 0;
 | 
					    *ptr = 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return(rv);
 | 
					  return resultBuffer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,7 +61,8 @@ NS_COM char *
 | 
				
			||||||
nsEscapeHTML(const char * string);
 | 
					nsEscapeHTML(const char * string);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NS_COM PRUnichar *
 | 
					NS_COM PRUnichar *
 | 
				
			||||||
nsEscapeHTML2(const PRUnichar * string);
 | 
					nsEscapeHTML2(const PRUnichar *aSourceBuffer,
 | 
				
			||||||
 | 
					              PRInt32 aSourceBufferLen = -1);
 | 
				
			||||||
 /*
 | 
					 /*
 | 
				
			||||||
  * Escape problem char's for HTML display 
 | 
					  * Escape problem char's for HTML display 
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue