Peter.VanderBeken%pandora.be fd291f1545 Remove use of nsXMLDocument so we only use interfaces.
Not part of build yet. a=leaf


git-svn-id: svn://10.0.0.236/trunk@66209 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-17 22:00:30 +00:00

849 lines
22 KiB
C++

/*
* (C) Copyright The MITRE Corporation 1999 All rights reserved.
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* The program provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* The Copyright owner will not be liable for any damages suffered by
* you as a result of using the Program. In no event will the Copyright
* owner be liable for any special, indirect or consequential damages or
* lost profits even if the Copyright owner has been advised of the
* possibility of their occurrence.
*
* Please see release.txt distributed with this file for more information.
*
*/
// Tom Kneeland (01/18/2000)
//
// Implementation of the Mozilla Wrapper class for the Document Object.
//
// Modification History:
// Who When What
// TK 02/11/2000 Added default constructor. If no NS object is provided
// simply create an nsXMLDocument to use.
// TK 02/15/2000 Fixed bug in Create Wrapper. We must check to see if the
// the nsIDOM* object is NULL. If it is, then we don't need
// a wrapper.
// Also fixed the same problem with the other factory methods
// that create wrappers for Mozilla objects.
//
#include "mozilladom.h"
#include "iostream.h"
#include "nsCOMPtr.h"
//
//Construct a Document Wrapper object without specificy a nsIDOMDocument
//object. We will create an ns
//
Document::Document()
{
nsCOMPtr<nsIDocument> document;
nsresult res = NS_NewXMLDocument(getter_AddRefs(document));
if (NS_SUCCEEDED(res) && document) {
document->QueryInterface(NS_GET_IID(nsIDOMDocument), (void**) &nsDocument);
}
Node::setNSObj(nsDocument, this);
}
//
//Construct a Document Wrapper object with a nsIDOMDocument object
//
Document::Document(nsIDOMDocument* document) : Node(document, this)
{
nsDocument = document;
}
//
//Clean up the private data members
//
Document::~Document()
{
}
//
//Provide an nsIDOMDocument object for wrapping
//
void Document::setNSObj(nsIDOMDocument* document)
{
Node::setNSObj(document);
nsDocument = document;
}
//
//Call nsIDOMDocument::GetDocumentElement to retreive the element for this
//document. Then call the createElement factory method to retreive an element
//wrapper for this object.
//
Element* Document::getDocumentElement()
{
nsIDOMElement* theElement = NULL;
Element* elemWrapper = NULL;
nsresult retval = 5;
if (nsDocument == NULL)
return NULL;
//retval = nsDocument->GetDocumentElement(&theElement);
//if (retval == NS_OK)
if ((retval = nsDocument->GetDocumentElement(&theElement)) == NS_OK)
{
cout << "Document::getDocumentElement - Mozilla Call ok" << endl;
return createElement(theElement);
}
else
{
cout << "Document::getDocumentElement - Mozilla Call not ok(" << hex <<retval << ")" << endl;
return NULL;
}
}
//
//Retrieve the DocumentType from nsIDOMDocument::GetDocType. Return it wrapped
//in the docType data member.
//
DocumentType* Document::getDoctype()
{
nsIDOMDocumentType* theDocType = NULL;
if (nsDocument == NULL)
return NULL;
if (nsDocument->GetDoctype(&theDocType) == NS_OK)
return createDocumentType(theDocType);
else
return NULL;
}
//
//Return a constant reference to the DOM's Implementation
//
DOMImplementation* Document::getImplementation()
{
nsIDOMDOMImplementation* theImpl = NULL;
if (nsDocument == NULL)
return NULL;
if (nsDocument->GetImplementation(&theImpl) == NS_OK)
return createDOMImplementation(theImpl);
else
return NULL;
}
//
// DEFFER this functionality to the NODE parent class
//Ensure that no Element node is inserted if the document already has an
//associated Element child.
//
/*
Node* Document::insertBefore(Node* newChild, Node* refChild)
{
Node* returnVal = NULL;
NodeDefinition* pCurrentNode = NULL;
NodeDefinition* pNextNode = NULL;
//Convert to a NodeDefinition Pointer
NodeDefinition* pNewChild = (NodeDefinition*)newChild;
NodeDefinition* pRefChild = (NodeDefinition*)refChild;
//Check to see if the reference node is a child of this node
if ((refChild != NULL) && (pRefChild->getParentNode() != this))
return NULL;
switch (pNewChild->getNodeType())
{
case Node::DOCUMENT_FRAGMENT_NODE :
pCurrentNode = (NodeDefinition*)pNewChild->getFirstChild();
while (pCurrentNode)
{
pNextNode = (NodeDefinition*)pCurrentNode->getNextSibling();
//Make sure that if the current node is an Element, the document
//doesn't already have one.
if ((pCurrentNode->getNodeType() != Node::ELEMENT_NODE) ||
((pCurrentNode->getNodeType() == Node::ELEMENT_NODE) &&
(documentElement == NULL)))
{
pCurrentNode = (NodeDefinition*)pNewChild->removeChild(pCurrentNode);
implInsertBefore(pCurrentNode, pRefChild);
if (pCurrentNode->getNodeType() == Node::ELEMENT_NODE)
documentElement = (Element*)pCurrentNode;
}
pCurrentNode = pNextNode;
}
returnVal = newChild;
break;
case Node::PROCESSING_INSTRUCTION_NODE :
case Node::COMMENT_NODE :
case Node::DOCUMENT_TYPE_NODE :
returnVal = implInsertBefore(pNewChild, pRefChild);
break;
case Node::ELEMENT_NODE :
if (!documentElement)
{
documentElement = (Element*)pNewChild;
returnVal = implInsertBefore(pNewChild, pRefChild);
}
else
returnVal = NULL;
break;
default:
returnVal = NULL;
}
return returnVal;
}
*/
//
// DEFFER this functionality to the NODE implementation
//Ensure that if the newChild is an Element and the Document already has an
//element, then oldChild should be specifying the existing element. If not
//then the replacement can not take place.
//
/*
Node* Document::replaceChild(Node* newChild, Node* oldChild)
{
Node* replacedChild = NULL;
if (newChild->getNodeType() != Node::ELEMENT_NODE)
{
//The new child is not an Element, so perform replacement
replacedChild = NodeDefinition::replaceChild(newChild, oldChild);
//If old node was an Element, then the document's element has been
//replaced with a non-element node. Therefore clear the documentElement
//pointer
if (replacedChild && (oldChild->getNodeType() == Node::ELEMENT_NODE))
documentElement = NULL;
return replacedChild;
}
else
{
//A node is being replaced with an Element. If the document does not
//have an elemet yet, then just allow the replacemetn to take place.
if (!documentElement)
replacedChild = NodeDefinition::replaceChild(newChild, oldChild);
else if (oldChild->getNodeType() == Node::ELEMENT_NODE)
replacedChild = NodeDefinition::replaceChild(newChild, oldChild);
if (replacedChild)
documentElement = (Element*)newChild;
return replacedChild;
}
}
*/
//
// DEFFER this functionality to the NODE Implementation
//Update the documentElement pointer if the associated Element node is being
//removed.
//
/*
Node* Document::removeChild(Node* oldChild)
{
Node* removedChild = NULL;
removedChild = NodeDefinition::removeChild(oldChild);
if (removedChild && (removedChild->getNodeType() == Node::ELEMENT_NODE))
documentElement = NULL;
return removedChild;
}
*/
//
//Call the nsIDOMDocument::CreateDocumentFragment function, then create or
//retrieve a wrapper class for it.
//
DocumentFragment* Document::createDocumentFragment()
{
nsIDOMDocumentFragment* fragment = NULL;
if (nsDocument == NULL)
return NULL;
if (nsDocument->CreateDocumentFragment(&fragment) == NS_OK)
return createDocumentFragment(fragment);
else
return NULL;
}
//
//Check the wrapperHashTable for a preexisting wrapper object. If it does not
// exists, create one and store it in the hash table. If it does exist, simply
// return it to the caller.
//
DocumentFragment*
Document::createDocumentFragment(nsIDOMDocumentFragment* fragment)
{
DocumentFragment* docFragWrapper = NULL;
if (fragment)
{
docFragWrapper =
(DocumentFragment*)wrapperHashTable.retrieve((Int32)fragment);
if (!docFragWrapper)
{
docFragWrapper = new DocumentFragment(fragment, this);
wrapperHashTable.add(docFragWrapper, (Int32)fragment);
}
}
return docFragWrapper;
}
//
//Call the nsIDOMDocument::CreateElement function, and retrieve or create
//a wrapper object for it.
//
Element* Document::createElement(const DOMString& tagName)
{
nsIDOMElement* element = NULL;
if (nsDocument->CreateElement(tagName.getConstNSString(), &element) == NS_OK)
return createElement(element);
else
return NULL;
}
//
//Check the wrapperHashTable for a precreated wrapper object. If one exists,
//return it to the caller. If it doens't exist, create one, store it in the
//hash, and return it to the caller.
//
Element* Document::createElement(nsIDOMElement* element)
{
Element* elemWrapper = NULL;
if (element)
{
elemWrapper = (Element*)wrapperHashTable.retrieve((Int32)element);
if (!elemWrapper)
{
elemWrapper = new Element(element, this);
wrapperHashTable.add(elemWrapper, (Int32)element);
}
}
return elemWrapper;
}
//
//Call the nsIDOMDocument::CreateAttribute function, then create or retrieve a
//wrapper object for it.
//
Attr* Document::createAttribute(const DOMString& name)
{
nsIDOMAttr* attr = NULL;
if (nsDocument == NULL)
return NULL;
if (nsDocument->CreateAttribute(name.getConstNSString(), &attr) == NS_OK)
return createAttribute(attr);
else
return NULL;
}
//
//Check the wrapperHashTable for a precreated object. If one exists, return it,
//else, create one, store it in the table, and return it.
//
Attr* Document::createAttribute(nsIDOMAttr* attr)
{
Attr* attrWrapper = NULL;
if (attr)
{
attrWrapper = (Attr*)wrapperHashTable.retrieve((Int32)attr);
if (!attrWrapper)
{
attrWrapper = new Attr(attr, this);
wrapperHashTable.add(attrWrapper, (Int32)attr);
}
}
return attrWrapper;
}
//
//Call the nsIDOMDocument::CreateTextNode function, then create, or retrieve a
//wrapper object for it.
//
Text* Document::createTextNode(const DOMString& theData)
{
nsIDOMText* text = NULL;
if (nsDocument == NULL)
return NULL;
if (nsDocument->CreateTextNode(theData.getConstNSString(), &text) == NS_OK)
return createTextNode(text);
else
return NULL;
}
//
//Check the wrapperHashTable to see if a precreated object exists. If it does
//then return it. Else, create a new one, insert it into the hash table, and
//then return it.
//
Text* Document::createTextNode(nsIDOMText* text)
{
Text* textWrapper = NULL;
if (text)
{
textWrapper = (Text*)wrapperHashTable.retrieve((Int32)text);
if (!textWrapper)
{
textWrapper = new Text(text, this);
wrapperHashTable.add(textWrapper, (Int32)text);
}
}
return textWrapper;
}
//
//Call the nsIDOMDocument::CreateComment function, then create or retrieve a
//wrapper object to return to the caller.
//
Comment* Document::createComment(const DOMString& theData)
{
nsIDOMComment* comment = NULL;
if (nsDocument == NULL)
return NULL;
if (nsDocument->CreateComment(theData.getConstNSString(), &comment) == NS_OK)
return createComment(comment);
else
return NULL;
}
//
//Check the wrapperHashTable for a precreated object to return to the caller.
//If one does not exist, create it, store it in the hash, and return it to the
//caller.
Comment* Document::createComment(nsIDOMComment* comment)
{
Comment* commentWrapper = NULL;
if (comment)
{
commentWrapper = (Comment*)wrapperHashTable.retrieve((Int32)comment);
if (!commentWrapper)
{
commentWrapper = new Comment(comment, this);
wrapperHashTable.add(commentWrapper, (Int32)comment);
}
}
return commentWrapper;
}
//
//Call the nsIDOMDocument::CreateCDATASection function, then create or retrieve
//a wrapper object to return to the caller.
//
CDATASection* Document::createCDATASection(const DOMString& theData)
{
nsIDOMCDATASection* cdata = NULL;
if (nsDocument == NULL)
return NULL;
if (nsDocument->CreateCDATASection(theData.getConstNSString(), &cdata) ==
NS_OK)
return createCDATASection(cdata);
else
return NULL;
}
//
//Check to see if a precreated object exists in the wrapperHashTable. If so
//simply return it to the caller. If not, creat one, store it in the hash, and
//return it to the caller.
//
CDATASection* Document::createCDATASection(nsIDOMCDATASection* cdata)
{
CDATASection* cdataWrapper = NULL;
if (cdata)
{
cdataWrapper = (CDATASection*)wrapperHashTable.retrieve((Int32)cdata);
if (!cdataWrapper)
{
cdataWrapper = new CDATASection(cdata, this);
wrapperHashTable.add(cdataWrapper, (Int32)cdata);
}
}
return cdataWrapper;
}
//
//Call the nsIDOMDocument::CreateProcessingInstruction function, then find or
//create a wrapper class to return to the caller.
//
ProcessingInstruction*
Document::createProcessingInstruction(const DOMString& target,
const DOMString& data)
{
nsIDOMProcessingInstruction* pi = NULL;
if (nsDocument == NULL)
return NULL;
if (nsDocument->CreateProcessingInstruction(target.getConstNSString(),
data.getConstNSString(), &pi) == NS_OK)
return createProcessingInstruction(pi);
else
return NULL;
}
//
//Check the wrapperHashTable for a precreated object. If one exists, return
//it to the caller. If not, create one, store it in the hash table, and then
//return it to the caller.
//
ProcessingInstruction*
Document::createProcessingInstruction(nsIDOMProcessingInstruction* pi)
{
ProcessingInstruction* piWrapper = NULL;
if (pi)
{
piWrapper = (ProcessingInstruction*)wrapperHashTable.retrieve((Int32)pi);
if (!piWrapper)
{
piWrapper = new ProcessingInstruction(pi, this);
wrapperHashTable.add(piWrapper, (Int32)pi);
}
}
return piWrapper;
}
//
//Call the nsIDOMDocument::CreateEntityReference function, then obtain a wrapper
//class to return to the user.
//
EntityReference* Document::createEntityReference(const DOMString& name)
{
nsIDOMEntityReference* entityRef = NULL;
if (nsDocument == NULL)
return NULL;
if (nsDocument->CreateEntityReference(name.getConstNSString(),
&entityRef) == NS_OK)
return createEntityReference(entityRef);
else
return NULL;
}
//
//Check the wrapperHashTable for a wrapper class. If one exists, simply return
//it to the caller. Else, create one, place it in the hash, and return it to
//the caller.
//
EntityReference*
Document::createEntityReference(nsIDOMEntityReference* entityRef)
{
EntityReference* entityWrapper = NULL;
if (entityRef)
{
entityWrapper =
(EntityReference*) wrapperHashTable.retrieve((Int32)entityRef);
if (!entityWrapper)
{
entityWrapper = new EntityReference(entityRef, this);
wrapperHashTable.add(entityWrapper, (Int32)entityRef);
}
}
return entityWrapper;
}
//
//Check the wrapperHashTable for a wrapper class. If one exists, simply return
//it to the caller. Else create one, place it in the hash table, and then return
//it to the caller.
Entity* Document::createEntity(nsIDOMEntity* entity)
{
Entity* entityWrapper = NULL;
if (entity)
{
entityWrapper = (Entity*)wrapperHashTable.retrieve((Int32) entity);
if (!entity)
{
entityWrapper = new Entity(entity, this);
wrapperHashTable.add(entityWrapper, (Int32)entity);
}
}
return entityWrapper;
}
//
//Factory function for creating and hashing generic Node wrapper classes.
//Check the wrapperHashTable to see if a wrapper object already exists. If it
//does then return it. If one does not exist, then creat one, hash it, and
//return it to the caller.
//
Node* Document::createNode(nsIDOMNode* node)
{
Node* nodeWrapper = NULL;
if (node)
{
nodeWrapper = (Node*)wrapperHashTable.retrieve((Int32)node);
if (!nodeWrapper)
{
nodeWrapper = new Node(node, this);
wrapperHashTable.add(nodeWrapper, (Int32)node);
}
}
return nodeWrapper;
}
//
//Factory function for creating and hashing a DOMString object. Note that it
//is specifically for wrapping nsString objects with MozillaString objects.
//Once the object is created it is stored in the hash table.
//
DOMString* Document::createDOMString(nsString* str)
{
DOMString* strWrapper = NULL;
if (str)
{
strWrapper = (DOMString*)wrapperHashTable.retrieve((Int32)str);
if (!strWrapper)
{
strWrapper = new DOMString(str);
wrapperHashTable.add(strWrapper, (Int32)str);
}
}
return strWrapper;
}
//
//Factory function for creating and hashing a Notation object.
//
Notation* Document::createNotation(nsIDOMNotation* notation)
{
Notation* notationWrapper = NULL;
if (notation)
{
notationWrapper = (Notation*)wrapperHashTable.retrieve((Int32) notation);
if (!notationWrapper)
{
notationWrapper = new Notation(notation, this);
wrapperHashTable.add(notationWrapper, (Int32)notation);
}
}
return notationWrapper;
}
//
//Factory function for creating and hashing DOM Implementation objects
//
DOMImplementation*
Document::createDOMImplementation(nsIDOMDOMImplementation* impl)
{
DOMImplementation* implWrapper = NULL;
if (impl)
{
implWrapper = (DOMImplementation*)wrapperHashTable.retrieve((Int32)impl);
if (!implWrapper)
{
implWrapper = new DOMImplementation(impl, this);
wrapperHashTable.add(implWrapper, (Int32)impl);
}
}
return implWrapper;
}
//
//Factory function for creating and hashing DOM DocumentType objects.
//
DocumentType* Document::createDocumentType(nsIDOMDocumentType* doctype)
{
DocumentType* doctypeWrapper = NULL;
if (doctype)
{
doctypeWrapper = (DocumentType*)wrapperHashTable.retrieve((Int32)doctype);
if (!doctypeWrapper)
{
doctypeWrapper = new DocumentType(doctype, this);
wrapperHashTable.add(doctypeWrapper, (Int32)doctype);
}
}
return doctypeWrapper;
}
//
//Factory function for creating and hashing NodeList objects
//
NodeList* Document::createNodeList(nsIDOMNodeList* list)
{
NodeList* listWrapper = NULL;
if (list)
{
listWrapper = (NodeList*)wrapperHashTable.retrieve((Int32)list);
if (!listWrapper)
{
listWrapper = new NodeList(list, this);
wrapperHashTable.add(listWrapper, (Int32)list);
}
}
return listWrapper;
}
//
//Factory function for creating and hashing NamedNodeMap objects
//
NamedNodeMap* Document::createNamedNodeMap(nsIDOMNamedNodeMap* map)
{
NamedNodeMap* mapWrapper = NULL;
if (map)
{
mapWrapper = (NamedNodeMap*)wrapperHashTable.retrieve((Int32)map);
if (!mapWrapper)
{
mapWrapper = new NamedNodeMap(map, this);
wrapperHashTable.add(mapWrapper, (Int32)map);
}
}
return mapWrapper;
}
//
//Remove the specified hashed object from wrapperHashTable and return it to the
//caller.
//
MITREObject* Document::removeWrapper(Int32 hashValue)
{
return wrapperHashTable.remove(hashValue);
}
//
//Add the specified wrapper to the hash table using the specified hash value
//
void Document::addWrapper(MITREObject* obj, Int32 hashValue)
{
wrapperHashTable.add(obj, hashValue);
}
//
//Determine what kind of node this is, and create the appropriate wrapper for it
//
Node* Document::createWrapper(nsIDOMNode* node)
{
unsigned short nodeType = 0;
//
//TK 02/15/2000 - Must make sure node is not null.
if (!node)
return NULL;
node->GetNodeType(&nodeType);
switch (nodeType)
{
case nsIDOMNode::ELEMENT_NODE:
return createElement((nsIDOMElement*)node);
break;
case nsIDOMNode::ATTRIBUTE_NODE:
return createAttribute((nsIDOMAttr*)node);
break;
case nsIDOMNode::TEXT_NODE:
return createTextNode((nsIDOMText*)node);
break;
case nsIDOMNode::CDATA_SECTION_NODE:
return createCDATASection((nsIDOMCDATASection*)node);
break;
case nsIDOMNode::COMMENT_NODE:
return createComment((nsIDOMComment*)node);
break;
case nsIDOMNode::ENTITY_REFERENCE_NODE:
return createEntityReference((nsIDOMEntityReference*)node);
break;
case nsIDOMNode::ENTITY_NODE:
return createEntity((nsIDOMEntity*)node);
break;
case nsIDOMNode::PROCESSING_INSTRUCTION_NODE:
return createProcessingInstruction((nsIDOMProcessingInstruction*)node);
break;
case nsIDOMNode::DOCUMENT_TYPE_NODE:
return createDocumentType((nsIDOMDocumentType*)node);
break;
case nsIDOMNode::DOCUMENT_FRAGMENT_NODE:
return createDocumentFragment((nsIDOMDocumentFragment*)node);
break;
case nsIDOMNode::NOTATION_NODE:
return createNotation((nsIDOMNotation*)node);
break;
default:
return createNode(node);
}
}