Commit 109a49d6 authored by vidur%netscape.com's avatar vidur%netscape.com
Browse files

Fix for bug 38349. Implemented nsIDOMNode::CloneNode() and ImportNode() for...

Fix for bug 38349. Implemented nsIDOMNode::CloneNode() and ImportNode() for XML and HTML documents as part of finishing out our DOM1 and DOM2 implementations. Cleanup of DOMImplementation::createDocument. r=jst
parent 67e47d27
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -25,7 +25,7 @@


#include "nsISupports.h"
#include "nsISupports.h"


class nsIDocument;
class nsIURI;


/*
/*
 * Event listener manager interface.
 * Event listener manager interface.
@@ -40,7 +40,7 @@ class nsIPrivateDOMImplementation : public nsISupports {
public:
public:
  static const nsIID& GetIID() { static nsIID iid = NS_IPRIVATEDOMIMPLEMENTATION_IID; return iid; }
  static const nsIID& GetIID() { static nsIID iid = NS_IPRIVATEDOMIMPLEMENTATION_IID; return iid; }


  NS_IMETHOD Init(nsIDocument* aDoc) = 0;
  NS_IMETHOD Init(nsIURI* aBaseURI) = 0;
};
};


NS_LAYOUT nsresult
NS_LAYOUT nsresult
+34 −19
Original line number Original line Diff line number Diff line
@@ -361,7 +361,7 @@ class nsDOMImplementation : public nsIDOMDOMImplementation,
                            public nsIPrivateDOMImplementation
                            public nsIPrivateDOMImplementation
{
{
public:
public:
  nsDOMImplementation(nsIDocument* aDocument = nsnull);
  nsDOMImplementation(nsIURI* aBaseURI = nsnull);
  virtual ~nsDOMImplementation();
  virtual ~nsDOMImplementation();


  NS_DECL_ISUPPORTS
  NS_DECL_ISUPPORTS
@@ -385,11 +385,11 @@ public:
  NS_IMETHOD SetScriptObject(void *aScriptObject);
  NS_IMETHOD SetScriptObject(void *aScriptObject);


  //nsIPrivateDOMImplementation
  //nsIPrivateDOMImplementation
  NS_IMETHOD Init(nsIDocument* aDoc);
  NS_IMETHOD Init(nsIURI* aBaseURI);


protected:
protected:
  void *mScriptObject;
  void *mScriptObject;
  nsCOMPtr<nsIDocument> mDocument;
  nsCOMPtr<nsIURI> mBaseURI;
};
};




@@ -402,11 +402,11 @@ NS_NewDOMImplementation(nsIDOMDOMImplementation** aInstancePtrResult)
  return domImpl->QueryInterface(NS_GET_IID(nsIDOMDOMImplementation), (void**) aInstancePtrResult);
  return domImpl->QueryInterface(NS_GET_IID(nsIDOMDOMImplementation), (void**) aInstancePtrResult);
}
}


nsDOMImplementation::nsDOMImplementation(nsIDocument* aDocument)
nsDOMImplementation::nsDOMImplementation(nsIURI* aBaseURI)
{
{
  NS_INIT_REFCNT();
  NS_INIT_REFCNT();
  mScriptObject = nsnull;
  mScriptObject = nsnull;
  mDocument = aDocument;
  mBaseURI = aBaseURI;
}
}


nsDOMImplementation::~nsDOMImplementation()
nsDOMImplementation::~nsDOMImplementation()
@@ -447,15 +447,8 @@ nsDOMImplementation::CreateDocument(const nsString& aNamespaceURI,
  nsresult rv = NS_OK;
  nsresult rv = NS_OK;
  *aReturn = nsnull;
  *aReturn = nsnull;


  nsIURI* baseURI = nsnull;
  NS_NewDOMDocument(aReturn, aNamespaceURI, aQualifiedName, aDoctype, mBaseURI);
  if (mDocument) {
    rv = mDocument->GetBaseURL(baseURI);
    if (NS_FAILED(rv)) return rv;
  }


  NS_NewDOMDocument(aReturn, aNamespaceURI, aQualifiedName, aDoctype, baseURI);

  NS_IF_RELEASE(baseURI);
  return rv;
  return rv;
}
}


@@ -490,9 +483,9 @@ nsDOMImplementation::SetScriptObject(void *aScriptObject)
}
}


NS_IMETHODIMP
NS_IMETHODIMP
nsDOMImplementation::Init(nsIDocument* aDoc)
nsDOMImplementation::Init(nsIURI* aBaseURI)
{
{
  mDocument = aDoc;
  mBaseURI = aBaseURI;
  return NS_OK;
  return NS_OK;
}
}


@@ -2062,7 +2055,7 @@ nsDocument::GetImplementation(nsIDOMDOMImplementation** aImplementation)
{
{
  // For now, create a new implementation every time. This shouldn't
  // For now, create a new implementation every time. This shouldn't
  // be a high bandwidth operation
  // be a high bandwidth operation
  nsDOMImplementation* impl = new nsDOMImplementation(this);
  nsDOMImplementation* impl = new nsDOMImplementation(mDocumentURL);
  if (nsnull == impl) {
  if (nsnull == impl) {
    return NS_ERROR_OUT_OF_MEMORY;
    return NS_ERROR_OUT_OF_MEMORY;
  }
  }
@@ -2247,6 +2240,17 @@ nsDocument::CreateElementWithNameSpace(const nsString& aTagName,
  return NS_ERROR_NOT_IMPLEMENTED;
  return NS_ERROR_NOT_IMPLEMENTED;
}
}


NS_IMETHODIMP
nsDocument::ImportNode(nsIDOMNode* aImportedNode,
                       PRBool aDeep,
                       nsIDOMNode** aReturn)
{
  NS_ENSURE_ARG(aImportedNode);
  NS_ENSURE_ARG_POINTER(aReturn);

  return aImportedNode->CloneNode(aDeep, aReturn);
}

NS_IMETHODIMP
NS_IMETHODIMP
nsDocument::AddBinding(nsIDOMElement* aContent, const nsString& aURL)
nsDocument::AddBinding(nsIDOMElement* aContent, const nsString& aURL)
{
{
@@ -2466,6 +2470,7 @@ nsDocument::GetHeight(PRInt32* aHeight)
NS_IMETHODIMP
NS_IMETHODIMP
nsDocument::Load (const nsString& aUrl)
nsDocument::Load (const nsString& aUrl)
{
{
  // Should be implemented by subclass
  return NS_ERROR_NOT_IMPLEMENTED;
  return NS_ERROR_NOT_IMPLEMENTED;
}
}


@@ -2677,6 +2682,7 @@ nsDocument::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNod


  aNewChild->GetNodeType(&nodeType);
  aNewChild->GetNodeType(&nodeType);
  if ((COMMENT_NODE != nodeType) &&
  if ((COMMENT_NODE != nodeType) &&
      (TEXT_NODE != nodeType) &&
      (PROCESSING_INSTRUCTION_NODE != nodeType) &&
      (PROCESSING_INSTRUCTION_NODE != nodeType) &&
      (DOCUMENT_TYPE_NODE != nodeType) &&
      (DOCUMENT_TYPE_NODE != nodeType) &&
      (ELEMENT_NODE != nodeType)) {
      (ELEMENT_NODE != nodeType)) {
@@ -2764,6 +2770,7 @@ nsDocument::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNod
  aNewChild->GetNodeType(&nodeType);
  aNewChild->GetNodeType(&nodeType);


  if ((COMMENT_NODE != nodeType) &&
  if ((COMMENT_NODE != nodeType) &&
      (TEXT_NODE != nodeType) &&
      (PROCESSING_INSTRUCTION_NODE != nodeType) &&
      (PROCESSING_INSTRUCTION_NODE != nodeType) &&
      (DOCUMENT_TYPE_NODE != nodeType) &&
      (DOCUMENT_TYPE_NODE != nodeType) &&
      (ELEMENT_NODE != nodeType)) {
      (ELEMENT_NODE != nodeType)) {
@@ -2894,7 +2901,7 @@ nsDocument::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
NS_IMETHODIMP    
NS_IMETHODIMP    
nsDocument::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
nsDocument::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
{
{
  // We don't allow cloning of a document
  // XXX should be implemented by subclass
  *aReturn = nsnull;
  *aReturn = nsnull;
  return NS_OK;
  return NS_OK;
}
}
@@ -2902,8 +2909,16 @@ nsDocument::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
NS_IMETHODIMP
NS_IMETHODIMP
nsDocument::Normalize()
nsDocument::Normalize()
{
{
  NS_NOTYETIMPLEMENTED("write me!");
  // XXX Not completely correct, since you can still have unnormalized
  return NS_ERROR_NOT_IMPLEMENTED;
  // text nodes as immediate children of the document.
  if (mRootContent) {
    nsCOMPtr<nsIDOMNode> node = do_QueryInterface(mRootContent);

    if (node) {
      return node->Normalize();
    }
  }
  return NS_OK;
}
}


NS_IMETHODIMP
NS_IMETHODIMP
+3 −0
Original line number Original line Diff line number Diff line
@@ -390,6 +390,9 @@ public:
  NS_IMETHOD    GetElementsByTagNameNS(const nsString& aNamespaceURI, const nsString& aLocalName, nsIDOMNodeList** aReturn);
  NS_IMETHOD    GetElementsByTagNameNS(const nsString& aNamespaceURI, const nsString& aLocalName, nsIDOMNodeList** aReturn);
  NS_IMETHOD    GetStyleSheets(nsIDOMStyleSheetList** aStyleSheets);
  NS_IMETHOD    GetStyleSheets(nsIDOMStyleSheetList** aStyleSheets);
  NS_IMETHOD    GetCharacterSet(nsString& aCharacterSet);
  NS_IMETHOD    GetCharacterSet(nsString& aCharacterSet);
  NS_IMETHOD    ImportNode(nsIDOMNode* aImportedNode,
                           PRBool aDeep,
                           nsIDOMNode** aReturn);
  NS_IMETHOD    CreateElementWithNameSpace(const nsString& aTagName, 
  NS_IMETHOD    CreateElementWithNameSpace(const nsString& aTagName, 
                                           const nsString& aNameSpace, 
                                           const nsString& aNameSpace, 
                                           nsIDOMElement** aReturn);
                                           nsIDOMElement** aReturn);
+1 −2
Original line number Original line Diff line number Diff line
@@ -2233,8 +2233,7 @@ nsHTMLDocument::ImportNode(nsIDOMNode* aImportedNode,
                           PRBool aDeep,
                           PRBool aDeep,
                           nsIDOMNode** aReturn)
                           nsIDOMNode** aReturn)
{
{
  NS_NOTYETIMPLEMENTED("write me");
  return nsDocument::ImportNode(aImportedNode, aDeep, aReturn);
  return NS_ERROR_NOT_IMPLEMENTED;
}
}


NS_IMETHODIMP
NS_IMETHODIMP
+70 −2
Original line number Original line Diff line number Diff line
@@ -786,13 +786,81 @@ nsXMLDocument::CreateElementWithNameSpace(const nsString& aTagName,
  return rv;
  return rv;
}
}


NS_IMETHODIMP    
nsXMLDocument::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
{
  NS_ENSURE_ARG_POINTER(aReturn);
  *aReturn = nsnull;

  nsresult rv;
  nsCOMPtr<nsIDOMDocumentType> docType, newDocType;
  nsCOMPtr<nsIDOMDocument> newDoc;

  // Get the doctype prior to new document construction. There's no big 
  // advantage now to dealing with the doctype separately, but maybe one 
  // day we'll do something significant with the doctype on document creation.
  GetDoctype(getter_AddRefs(docType));
  if (docType) {
    nsCOMPtr<nsIDOMNode> newDocTypeNode;
    rv = docType->CloneNode(PR_TRUE, getter_AddRefs(newDocTypeNode));
    if (NS_FAILED(rv)) return rv;
    newDocType = do_QueryInterface(newDocTypeNode);
  }

  // Create an empty document
  nsAutoString emptyStr;
  emptyStr.Truncate();
  rv = NS_NewDOMDocument(getter_AddRefs(newDoc), emptyStr, emptyStr,
                         newDocType, mDocumentURL);
  if (NS_FAILED(rv)) return rv;

  if (aDeep) {
    // If there was a doctype, a new one has already been inserted into the
    // new document. We might have to add nodes before it.
    PRBool beforeDocType = (docType.get() != nsnull);
    nsCOMPtr<nsIDOMNodeList> childNodes;
    
    GetChildNodes(getter_AddRefs(childNodes));
    if (childNodes) {
      PRUint32 index, count;
      childNodes->GetLength(&count);
      for (index=0; index < count; index++) {
        nsCOMPtr<nsIDOMNode> child;
        childNodes->Item(index, getter_AddRefs(child));
        if (child && (child != docType)) {
          nsCOMPtr<nsIDOMNode> newChild;
          rv = child->CloneNode(aDeep, getter_AddRefs(newChild));
          if (NS_FAILED(rv)) return rv;
          
          nsCOMPtr<nsIDOMNode> dummyNode;
          if (beforeDocType) {
            rv = newDoc->InsertBefore(newChild, 
                                      docType, 
                                      getter_AddRefs(dummyNode));
            if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
          }
          else {
            rv = newDoc->AppendChild(newChild, 
                                     getter_AddRefs(dummyNode));
            if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
          }
        }
        else {
          beforeDocType = PR_FALSE;
        }
      }
    }
  }

  return newDoc->QueryInterface(NS_GET_IID(nsIDOMNode), (void**)aReturn);
}
 
NS_IMETHODIMP
NS_IMETHODIMP
nsXMLDocument::ImportNode(nsIDOMNode* aImportedNode,
nsXMLDocument::ImportNode(nsIDOMNode* aImportedNode,
                          PRBool aDeep,
                          PRBool aDeep,
                          nsIDOMNode** aReturn)
                          nsIDOMNode** aReturn)
{
{
  NS_NOTYETIMPLEMENTED("write me");
  return nsDocument::ImportNode(aImportedNode, aDeep, aReturn);
  return NS_ERROR_NOT_IMPLEMENTED;
}
}


NS_IMETHODIMP
NS_IMETHODIMP
Loading