Code

Corrected initialization order.
[inkscape.git] / src / dom / domimpl.cpp
1 /**
2  * Phoebe DOM Implementation.
3  *
4  * This is a C++ approximation of the W3C DOM model, which follows
5  * fairly closely the specifications in the various .idl files, copies of
6  * which are provided for reference.  Most important is this one:
7  *
8  * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
9  *
10  * Authors:
11  *   Bob Jamison
12  *
13  * Copyright (C) 2005-2008 Bob Jamison
14  *
15  *  This library is free software; you can redistribute it and/or
16  *  modify it under the terms of the GNU Lesser General Public
17  *  License as published by the Free Software Foundation; either
18  *  version 2.1 of the License, or (at your option) any later version.
19  *
20  *  This library is distributed in the hope that it will be useful,
21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23  *  Lesser General Public License for more details.
24  *
25  *  You should have received a copy of the GNU Lesser General Public
26  *  License along with this library; if not, write to the Free Software
27  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
28  */
31 #include "domimpl.h"
33 namespace org
34 {
35 namespace w3c
36 {
37 namespace dom
38 {
41 /**
42  *  Test if the given substring exists for the length of the string
43  *  in a given buffer
44  */
45 /*
46 static bool match(const DOMString &buf, char *str)
47 {
48     int pos = 0;
49     while (*str)
50        {
51        if (buf[pos++] != *str++)
52            return false;
53        }
54    return true;
55 }
56 */
60 /*#########################################################################
61 ## DOMImplementationSourceImpl
62 #########################################################################*/
65 /**
66  *
67  */
68 DOMImplementationSourceImpl::DOMImplementationSourceImpl()
69 {
70     domImpl     = new DOMImplementationImpl();
71 }
73 /**
74  *
75  */
76 DOMImplementationSourceImpl::~DOMImplementationSourceImpl()
77 {
78     delete domImpl;
79 }
81 /**
82  *
83  */
84 DOMImplementation *DOMImplementationSourceImpl::getDOMImplementation(
85                                                                      const DOMString &/*features*/)
86 {
87     return domImpl;
88 }
90 /**
91  *
92  */
93 DOMImplementationList DOMImplementationSourceImpl::getDOMImplementationList(
94                                                                             const DOMString &/*features*/)
95 {
96     return domImplList;
97 }
105 /*#########################################################################
106 ## DOMImplementationImpl
107 #########################################################################*/
110 /**
111  *
112  */
113 DOMImplementationImpl::DOMImplementationImpl()
117 /**
118  *
119  */
120 DOMImplementationImpl::~DOMImplementationImpl()
124 /**
125  *
126  */
127 bool DOMImplementationImpl::hasFeature(const DOMString& /*feature*/,
128                                        const DOMString& /*version*/)
130     return false;
134 /**
135  *
136  */
137 DocumentTypePtr DOMImplementationImpl::createDocumentType(const DOMString& qualifiedName,
138                                  const DOMString& publicId,
139                                  const DOMString& systemId)
140                                  throw(DOMException)
142     DocumentTypePtr typeImpl = new DocumentTypeImpl(qualifiedName,
143                                          publicId, systemId);
144     return typeImpl;
147 /**
148  *
149  */
150 DocumentPtr DOMImplementationImpl::createDocument(
151                          const DOMString& namespaceURI,
152                          const DOMString& qualifiedName,
153                          DocumentTypePtr  doctype)
154                          throw(DOMException)
156     DocumentPtr doc = new DocumentImpl(this,
157                                        namespaceURI,
158                                        qualifiedName,
159                                        doctype);
160     return doc;
163 /**
164  *
165  */
166 DOMObject *DOMImplementationImpl::getFeature(const DOMString& /*feature*/,
167                                              const DOMString& /*version*/)
170     return NULL;
177 /*#########################################################################
178 ## NodeImpl
179 #########################################################################*/
181 /**
182  * Utility for finding the first Element above
183  * a given node.  Used by several methods below
184  */
185 static NodePtr getAncestorElement(NodePtr node)
187     if (!node.get())
188         return NULL;
189     node = node->getParentNode();
190     //Either quit because I am an element, or because I am null
191     while (node.get())
192         {
193         if (node->getNodeType() == Node::ELEMENT_NODE)
194             return node;
195         node = node->getParentNode();
196         }
197     return node;
200 /**
201  *
202  */
203 DOMString NodeImpl::getNodeName()
205     return nodeName;
208 /**
209  *
210  */
211 DOMString NodeImpl::getNodeValue() throw (DOMException)
213     return nodeValue;
216 /**
217  *
218  */
219 void NodeImpl::setNodeValue(const DOMString& val) throw (DOMException)
221     nodeValue = val;
224 /**
225  *
226  */
227 unsigned short NodeImpl::getNodeType()
229     return nodeType;
232 /**
233  *
234  */
235 NodePtr NodeImpl::getParentNode()
237     return parent;
240 /**
241  *
242  */
243 NodeList NodeImpl::getChildNodes()
245     NodeList list;
246     for (NodeImplPtr node = firstChild ; node.get() ; node=node->next)
247         list.add(node);
248     return list;
251 /**
252  *
253  */
254 NodePtr NodeImpl::getFirstChild()
256     return firstChild;
259 /**
260  *
261  */
262 NodePtr NodeImpl::getLastChild()
264     return lastChild;
267 /**
268  *
269  */
270 NodePtr NodeImpl::getPreviousSibling()
272     return prev;
275 /**
276  *
277  */
278 NodePtr NodeImpl::getNextSibling()
280     return next;
283 /**
284  *
285  */
286 NamedNodeMap &NodeImpl::getAttributes()
288     NamedNodeMap &attrs = attributes;
289     return attrs;
293 /**
294  *
295  */
296 DocumentPtr NodeImpl::getOwnerDocument()
298     return ownerDocument;
301 /**
302  *
303  */
304 NodePtr NodeImpl::insertBefore(const NodePtr newChild,
305                                const NodePtr refChild)
306                                throw(DOMException)
308     if (!newChild)
309         return NULL;
310         
311     //if no ref, then just append
312     if (!refChild)
313         return appendChild(newChild);
315     NodeImplPtr newChildImpl = dynamic_cast<NodeImpl *>(newChild.get());
316     for (NodeImplPtr n = firstChild ; n.get() ; n=n->next)
317         {
318         if (n == refChild)
319             {
320             //link to new
321             if (n->prev.get())
322                 n->prev->next = newChildImpl;
323             else
324                 firstChild = newChildImpl;
325             n->prev = newChildImpl;
326             //link from new
327             newChildImpl->next = n;
328             newChildImpl->prev = n->prev;
329             //reflect new location
330             newChildImpl->parent        = this;
331             newChildImpl->ownerDocument = ownerDocument;
332             return n;
333             }
334         }
335     return NULL;
338 /**
339  *
340  */
341 NodePtr NodeImpl::replaceChild(const NodePtr newChild,
342                                const NodePtr oldChild)
343                                throw(DOMException)
345     if (!oldChild)
346         return NULL;
348     NodeImplPtr newChildImpl = dynamic_cast<NodeImpl *>(newChild.get());
349     for (NodeImplPtr n = firstChild ; n.get() ; n=n->next)
350         {
351         if (n == oldChild)
352             {
353             //link to new
354             if (n->prev.get())
355                 n->prev->next = newChildImpl;
356             else
357                 firstChild = newChildImpl;
358             if (n->next.get())
359                 n->next->prev = newChildImpl;
360             else
361                 lastChild = newChildImpl;
362             //link from new
363             newChildImpl->next = n->next;
364             newChildImpl->prev = n->prev;
365             //reflect new location
366             newChildImpl->parent        = this;
367             newChildImpl->ownerDocument = ownerDocument;
368             return n;
369             }
370         }
371     return NULL;
374 /**
375  *
376  */
377 NodePtr NodeImpl::removeChild(const NodePtr oldChild)
378                               throw(DOMException)
380     if (!oldChild)
381         return NULL;
383     for (NodeImplPtr n = firstChild ; n.get() ; n=n->next)
384         {
385         if (n == oldChild)
386             {
387             if (n->prev.get())
388                 n->prev->next = n->next;
389             if (n->next.get())
390                 n->next->prev = n->prev;
391             return n;
392             }
393         }
394     return NULL;
397 /**
398  *
399  */
400 NodePtr NodeImpl::appendChild(const NodePtr newChild)
401                              throw(DOMException)
403     if (!newChild)
404         return NULL;
406     NodeImplPtr newChildImpl =
407              dynamic_cast<NodeImpl *> (newChild.get());
409     newChildImpl->parent        = this;
410     newChildImpl->ownerDocument = ownerDocument;
412     if (!firstChild || !lastChild)
413         {
414         //Set up our first member
415         firstChild = newChildImpl;
416         lastChild  = newChildImpl;
417         }
418     else
419         {
420         //link at the last position
421         lastChild->next    = newChildImpl;
422         newChildImpl->prev = lastChild;
423         lastChild          = newChildImpl;
424         }
426     return newChild;
429 /**
430  *
431  */
432 bool NodeImpl::hasChildNodes()
434     return (firstChild != (NodeImpl *)0);
437 /**
438  *
439  */
440 NodePtr NodeImpl::cloneNode(bool deep)
442     NodeImplPtr node    = new NodeImpl(ownerDocument, nodeName);
443     node->parent        = parent;
444     node->prev          = prev;
445     node->next          = next;
446     node->userData      = userData;
447     node->nodeValue     = nodeValue;
449     if (deep)
450         {
451         node->firstChild = node->lastChild = NULL;
452         for (NodeImplPtr child = firstChild ; child.get() ; child=child->next)
453             {
454             node->appendChild(child->cloneNode(deep));
455             }
456         }
457     else
458         {
459         node->firstChild = firstChild;
460         node->lastChild  = lastChild;
461         }
463     return node;
466 /**
467  *  Concatenate adjoining text subnodes, remove null-length nodes
468  */
469 void NodeImpl::normalize()
471     //First, concatenate adjoining text nodes
472     NodeImplPtr next = (NodeImpl *)0;
473     for (NodeImplPtr child = firstChild ; child.get() ; child=next)
474         {
475         if (child->getNodeType() != Node::TEXT_NODE)
476             continue;
477         next = NULL;
478         DOMString sval = child->getNodeValue();
479         for (NodeImplPtr sibling = child->next ; sibling.get() ; sibling=next)
480             {
481             next = sibling->next;
482             if (sibling->getNodeType() != Node::TEXT_NODE)
483                 break;
484             sval.append(sibling->getNodeValue());
485             //unlink and delete
486             child->next = sibling->next;
487             if (sibling->next.get())
488                 sibling->next->prev = child;
489             //delete sibling;
490             }
491         child->setNodeValue(sval);
492         }
494     //Next, we remove zero-length text subnodes
495     next = NULL;
496     for (NodeImplPtr child = firstChild ; child.get() ; child=next)
497         {
498         next = child->next;
499         if (child->getNodeType() != Node::TEXT_NODE)
500             continue;
501         if (child->getNodeValue().size() == 0)
502             {
503             //unlink and delete
504             if (child->prev.get())
505                 child->prev->next = child->next;
506             if (child->next.get())
507                 child->next->prev = child->prev;
508             //delete child;
509             }
510         }
514 /**
515  *
516  */
517 bool NodeImpl::isSupported(const DOMString& /*feature*/,
518                            const DOMString& /*version*/)
520     //again, no idea
521     return false;
524 /**
525  *
526  */
527 DOMString NodeImpl::getNamespaceURI()
529     return namespaceURI;
532 /**
533  *
534  */
535 DOMString NodeImpl::getPrefix()
537     return prefix;
540 /**
541  *
542  */
543 void NodeImpl::setPrefix(const DOMString& val) throw(DOMException)
545     prefix = val;
546     if (prefix.size()>0)
547         nodeName = prefix + ":" + localName;
548     else
549         nodeName = localName;
552 /**
553  *
554  */
555 DOMString NodeImpl::getLocalName()
557     return localName;
560 /**
561  *
562  */
563 bool NodeImpl::hasAttributes()
565     return (attributes.getLength() > 0);
568 /**
569  *
570  */
571 DOMString NodeImpl::getBaseURI()
573     return baseURI;
576 /**
577  *
578  */
579 unsigned short NodeImpl::compareDocumentPosition(const NodePtr otherArg)
581     if (!otherArg || otherArg == (NodePtr )this)
582         return 0;//no flags
584     NodePtr node;
585     NodePtr other = otherArg;
587     //Look above me
588     for (node=getParentNode() ; node.get() ; node=node->getParentNode())
589         if (node == other)
590             return DOCUMENT_POSITION_CONTAINED_BY;
592     //Look above the other guy. See me?
593     for (node=other->getParentNode() ; node.get() ; node=node->getParentNode())
594         if (node == (NodePtr )this)
595             return DOCUMENT_POSITION_CONTAINS;
598     return DOCUMENT_POSITION_DISCONNECTED |
599            DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
602 /**
603  *
604  */
605 DOMString NodeImpl::getTextContent() throw(DOMException)
607     DOMString buf;
608     if (nodeType == TEXT_NODE          ||
609             nodeType == CDATA_SECTION_NODE ||
610                 nodeType == COMMENT_NODE       ||
611                 nodeType == PROCESSING_INSTRUCTION_NODE)
612                 buf = getNodeValue();
613     else if (nodeType == ELEMENT_NODE      ||
614                  nodeType == ATTRIBUTE_NODE         ||
615                      nodeType == ENTITY_NODE            ||
616                      nodeType == ENTITY_REFERENCE_NODE  ||
617                      nodeType == DOCUMENT_FRAGMENT_NODE)
618                 {
619                 for (NodePtr n = getFirstChild() ; n.get() ;
620                      n=n->getNextSibling() )
621                     {
622             if (n->getNodeType() != COMMENT_NODE &&
623                         n->getNodeType() != COMMENT_NODE)
624                 buf.append(n->getTextContent());
625                     }
626                 }
627     return buf;
631 /**
632  *
633  */
634 void NodeImpl::setTextContent(const DOMString &val) throw(DOMException)
636     //Delete children
637     /** Not necessary.  Just let smart pointers to their work
638         for (NodePtr n = getFirstChild() ; n.get() ;
639                            n=n->getNextSibling() )
640         delete n;
641     */
642     firstChild = lastChild = NULL;
644     //Replace with a single text node
645     NodeImplPtr tnode = new NodeImpl(ownerDocument);
646     tnode->nodeType = Node::TEXT_NODE;
647     tnode->setNodeValue(val);
648     appendChild(tnode);
652 /**
653  * From DOM3 Namespace algorithms
654  */
655 DOMString NodeImpl::lookupPrefix(const DOMString &theNamespaceURI)
658     if (theNamespaceURI.size()==0)
659         {
660         return DOMString("");
661         }
663     switch (nodeType)
664         {
665         case Node::ELEMENT_NODE:
666             {
667             ElementPtr elem = (Element *)this;
668             return lookupNamespacePrefix(theNamespaceURI, elem);
669             }
670         case Node::DOCUMENT_NODE:
671             {
672             DocumentPtr doc = (Document *)this;
673             ElementPtr elem = doc->getDocumentElement();
674             return elem->lookupPrefix(theNamespaceURI);
675             }
676         case Node::ENTITY_NODE :
677         case Node::NOTATION_NODE:
678         case Node::DOCUMENT_FRAGMENT_NODE:
679         case Node::DOCUMENT_TYPE_NODE:
680             return DOMString("");  // type is unknown
681         case Node::ATTRIBUTE_NODE:
682             {
683             AttrPtr attr = (Attr *)this;
684             ElementPtr elem = attr->getOwnerElement();
685             if ( elem.get() )
686                 {
687                 return elem->lookupPrefix(theNamespaceURI);
688                 }
689              return DOMString("");
690             }
691         default:
692             {
693             //Get ancestor element, if any
694             NodePtr ancestor = getAncestorElement(this);
695             if ( ancestor.get() )
696                {
697                return ancestor->lookupPrefix(theNamespaceURI);
698                }
699             return DOMString("");
700             }
701         }//switch
702     return DOMString("");
706 /**
707  *
708  */
709 bool NodeImpl::isDefaultNamespace(const DOMString &theNamespaceURI)
711     switch (nodeType)
712         {
713         case ELEMENT_NODE:
714             {
715             if ( namespaceURI.size()>0 && prefix.size()==0 )
716                 {
717                 return (namespaceURI == theNamespaceURI);
718                 }
719             NodePtr attr = attributes.getNamedItem("xmlns");
720             if ( attr.get() )
721                 {
722                 return (attr->getNodeValue() == theNamespaceURI);
723                 }
725             NodePtr ancestor = getAncestorElement(this);
726             if ( ancestor.get() )
727                 {
728                 return ancestor->isDefaultNamespace(theNamespaceURI);
729                 }
730             else
731                 {
732                 return false;
733                 }
734             }
735         case DOCUMENT_NODE:
736             { //just use braces for local declaration
737             DocumentPtr doc = (Document *)this;
738             ElementPtr elem = doc->getDocumentElement();
739             return elem->isDefaultNamespace(theNamespaceURI);
740             }
741         case ENTITY_NODE:
742         case NOTATION_NODE:
743         case DOCUMENT_TYPE_NODE:
744         case DOCUMENT_FRAGMENT_NODE:
745             return false;
746         case ATTRIBUTE_NODE:
747             {//braces only for scope
748             AttrPtr attr = (Attr *)this;
749             ElementPtr ownerElement = attr->getOwnerElement();
750             if ( ownerElement.get() )
751                 {
752                 return ownerElement->isDefaultNamespace(theNamespaceURI);
753                 }
754             else
755                 {
756                 return false;
757                 }
758             }
759         default:
760             {
761             NodePtr ancestor = getAncestorElement(this);
762             if ( ancestor.get() )
763                 {
764                 return ancestor->isDefaultNamespace(theNamespaceURI);
765                 }
766             else
767                 {
768                 return false;
769                 }
770             }
771         }//switch
773     return false;
777 /**
778  *
779  */
780 DOMString NodeImpl::lookupNamespaceURI(const DOMString &thePrefix)
782     switch (nodeType)
783         {
784         case ELEMENT_NODE:
785             {
786             if ( namespaceURI.size()>0 && prefix == thePrefix )
787                 {
788                 DOMString nsURI = namespaceURI;
789                 return (nsURI);
790                 }
791             if ( hasAttributes() )
792                 {
793                 NamedNodeMap attributes = getAttributes();
794                 int nrAttrs = attributes.getLength();
795                 for (int i=0 ; i<nrAttrs ; i++)
796                     {
797                     NodePtr attr = attributes.item(i);
798                     if (attr->getPrefix() == "xmlns" && attr->getLocalName() == thePrefix )
799                         { // non default namespace
800                         if (attr->getNodeValue().size()>0)
801                             {
802                             return (attr->getNodeValue());
803                             }
804                         return DOMString("");
805                         }
806                     else if (attr->getLocalName() == "xmlns" && thePrefix.size()==0)
807                         { // default namespace
808                         if (attr->getNodeValue().size()>0)
809                             {
810                             return (attr->getNodeValue());
811                             }
812                         return DOMString("");
813                         }
814                     }
815                 }
817             NodePtr ancestor = getAncestorElement(this);
818             if ( ancestor.get() )
819                 {
820                 return ancestor->lookupNamespaceURI(thePrefix);
821                 }
822             return DOMString("");
823             }
824         case DOCUMENT_NODE:
825             {
826             DocumentPtr doc = (Document *)this;
827             ElementPtr elem = doc->getDocumentElement();
828             return elem->lookupNamespaceURI(thePrefix);
829             }
830         case ENTITY_NODE:
831         case NOTATION_NODE:
832         case DOCUMENT_TYPE_NODE:
833         case DOCUMENT_FRAGMENT_NODE:
834             return DOMString("");
836         case ATTRIBUTE_NODE:
837             {
838             ElementPtr ownerElement = ((Attr *)this)->getOwnerElement();
839             if ( ownerElement.get() )
840                 {
841                 return ownerElement->lookupNamespaceURI(thePrefix);
842                 }
843             else
844                 {
845                 return DOMString("");
846                 }
847             }
848         default:
849             {
850             NodePtr ancestor = getAncestorElement(this);
851             if ( ancestor.get() )
852                 {
853                 return ancestor->lookupNamespaceURI(thePrefix);
854                 }
855             else
856                 {
857                 return DOMString("");
858                 }
859             }
860         }//switch
864 /**
865  *
866  */
867 bool NodeImpl::isEqualNode(const NodePtr nodeArg)
869     if (!nodeArg)
870         return false;
872     if (nodeArg == (NodePtr )this)
873         return true;
875     NodePtr node = nodeArg;
877     if (getNodeType()     != node->getNodeType()     ||
878         getNodeName()     != node->getNodeName()     ||
879         getLocalName()    != node->getLocalName()    ||
880         getNamespaceURI() != node->getNamespaceURI() ||
881         getPrefix()       != node->getPrefix()       ||
882         getNodeValue()    != node->getNodeValue()    ||
883         getBaseURI()      != node->getBaseURI()      )
884         return false;
886     return true;
891 /**
892  *
893  */
894 DOMObject *NodeImpl::getFeature(const DOMString &/*feature*/,
895                                 const DOMString &/*version*/)
897     //dont know
898     return NULL;
901 /**
902  *
903  */
904 DOMUserData *NodeImpl::setUserData(const DOMString &key,
905                                    const DOMUserData *data,
906                                    const UserDataHandler *handler)
908     UserDataEntry *entry = userDataEntries;
909     UserDataEntry *prev  = NULL;
910     while (entry)
911         {
912         if (entry->key == key)
913             {
914             DOMUserData *oldData = entry->data;
915             entry->data    = (DOMUserData *)data;
916             entry->handler = (UserDataHandler *)handler;
917             return oldData;
918             }
919         prev  = entry;
920         entry = entry->next;
921         }
923     //Make a new one
924     UserDataEntry *newEntry = new UserDataEntry(key, data, handler);
925     if (!prev)
926         userDataEntries = newEntry;
927     else
928         prev->next = newEntry;
930     return NULL;
933 /**
934  *
935  */
936 DOMUserData *NodeImpl::getUserData(const DOMString &key)
938     UserDataEntry *entry = userDataEntries;
939     while (entry)
940         {
941         if (entry->key == key)
942             return entry->data;
943         entry = entry->next;
944         }
945     return NULL;
950 //##################
951 //# Non-API methods
952 //##################
954 /**
955  *
956  */
957 void NodeImpl::setNodeName(const DOMString &qualifiedName)
959     nodeName  = qualifiedName;
960     prefix    = "";
961     localName = "";
962     for (unsigned int i=0 ; i<qualifiedName.size() ; i++)
963         {
964         int ch = qualifiedName[i];
965         if (ch == ':')
966             {
967             prefix    = localName;
968             localName = "";
969             }
970         else
971             {
972             localName.push_back((XMLCh)ch);
973             }
974         }
977 /**
978  *
979  */
980 void NodeImpl::setNamespaceURI(const DOMString &theNamespaceURI)
982     namespaceURI = theNamespaceURI;
986 /**
987  * From DOM3 Namespace algorithms
988  */
989 DOMString NodeImpl::lookupNamespacePrefix(const DOMString &theNamespaceURI,
990                                           NodePtr originalElement)
992     if (!originalElement)
993         return DOMString("");
995     if ( namespaceURI.size()>0 && namespaceURI==theNamespaceURI &&
996          prefix.size()>0 &&
997          originalElement->lookupNamespaceURI(prefix) == theNamespaceURI)
998         {
999         return (prefix);
1000         }
1002     if ( hasAttributes() )
1003         {
1004         NamedNodeMap attributes = getAttributes();
1005         int nrAttrs = attributes.getLength();
1006         for (int i=0 ; i<nrAttrs ; i++)
1007             {
1008             NodePtr attr = attributes.item(i);
1009             DOMString attrLocalName = attr->getLocalName();
1010             if (attr->getPrefix()    == "xmlns" &&
1011                 attr->getNodeValue() == theNamespaceURI &&
1012                 originalElement->lookupNamespaceURI(attrLocalName)
1013                                      == theNamespaceURI)
1014                 {
1015                 return (attrLocalName);
1016                 }
1017             }
1018         }
1020     //Get ancestor element, if any
1021     NodeImplPtr ancestor = parent;
1022     while (ancestor.get() && ancestor->getNodeType()!= Node::ELEMENT_NODE)
1023         ancestor = ancestor->parent;
1025     if ( ancestor.get() )
1026         {
1027         return ancestor->lookupNamespacePrefix(theNamespaceURI, originalElement);
1028         }
1030     return DOMString("");
1034 /**
1035  *
1036  */
1037 NodeImpl::NodeImpl() : Node()
1039     init();
1043 /**
1044  *
1045  */
1046 NodeImpl::NodeImpl(const NodeImpl &other) : Node()
1048     init();
1049     assign(other);
1052 /**
1053  *
1054  */
1055 NodeImpl &NodeImpl::operator=(const NodeImpl &other)
1057     init();
1058     assign(other);
1059     return *this;
1063 /**
1064  *
1065  */
1066 NodeImpl::NodeImpl(DocumentImplPtr owner) : Node()
1068     init();
1069     ownerDocument = owner;
1072 /**
1073  *
1074  */
1075 NodeImpl::NodeImpl(DocumentImplPtr owner, const DOMString &nodeName)
1076                    : Node()
1078     init();
1079     ownerDocument = owner;
1080     setNodeName(nodeName);
1083 /**
1084  *
1085  */
1086 NodeImpl::NodeImpl(DocumentImplPtr owner, const DOMString &/*theNamespaceURI*/,
1087                    const DOMString &qualifiedName) : Node()
1089     init();
1090     ownerDocument = owner;
1091     //if (owner)
1092     //    namespaceURI  = owner->stringCache(theNamespaceURI);
1093     setNodeName(qualifiedName);
1098 /**
1099  *
1100  */
1101 void NodeImpl::init()
1103     nodeType        = 0; //none yet
1104     nodeValue       = "";
1105     setNodeName("");
1106     namespaceURI    = "";
1107     parent          = NULL;
1108     prev            = NULL;
1109     next            = NULL;
1110     userData        = NULL;
1111     firstChild      = NULL;
1112     lastChild       = NULL;
1113     ownerDocument   = NULL;
1114     userDataEntries = NULL;
1117 /**
1118  *
1119  */
1120 void NodeImpl::assign(const NodeImpl &other)
1122     ownerDocument = other.ownerDocument;
1123     prefix        = other.prefix;
1124     localName     = other.localName;
1125     nodeName      = other.nodeName;
1126     nodeValue     = other.nodeValue;
1127     namespaceURI  = other.namespaceURI;
1128     attributes    = other.attributes;
1132 /**
1133  *
1134  */
1135 NodeImpl::~NodeImpl()
1137     if (userDataEntries)
1138         delete userDataEntries;
1139     //Delete children
1140     /** Use smart pointers.  do not delete explicitly
1141         for (NodePtr n = getFirstChild() ; n.get() ;
1142                      n=n->getNextSibling() )
1143         delete n;
1144     */
1145     firstChild = lastChild = (NodeImpl *)0;
1150 /*#########################################################################
1151 ## CharacterDataImpl
1152 #########################################################################*/
1155 /**
1156  *
1157  */
1158 CharacterDataImpl::CharacterDataImpl() : NodeImpl()
1162 /**
1163  *
1164  */
1165 CharacterDataImpl::CharacterDataImpl(DocumentImplPtr owner,
1166                                      const DOMString &theValue) : NodeImpl()
1168     ownerDocument = owner;
1169     nodeValue     = theValue;
1172 /**
1173  *
1174  */
1175 CharacterDataImpl::~CharacterDataImpl()
1179 /**
1180  *
1181  */
1182 DOMString CharacterDataImpl::getData() throw(DOMException)
1184     return nodeValue;
1187 /**
1188  *
1189  */
1190 void CharacterDataImpl::setData(const DOMString& val) throw(DOMException)
1192     nodeValue = val;
1195 /**
1196  *
1197  */
1198 unsigned long CharacterDataImpl::getLength()
1200     return nodeValue.size();
1203 /**
1204  *
1205  */
1206 DOMString CharacterDataImpl::substringData(unsigned long offset,
1207                         unsigned long count)
1208                         throw(DOMException)
1210     return nodeValue.substr(offset, count);
1213 /**
1214  *
1215  */
1216 void CharacterDataImpl::appendData(const DOMString& arg) throw(DOMException)
1218     nodeValue += arg;
1221 /**
1222  *
1223  */
1224 void CharacterDataImpl::insertData(unsigned long offset,
1225                 const DOMString& arg)
1226                 throw(DOMException)
1228     nodeValue.insert(offset, arg);
1231 /**
1232  *
1233  */
1234 void CharacterDataImpl::deleteData(unsigned long offset,
1235                 unsigned long count)
1236                 throw(DOMException)
1238     nodeValue.erase(offset, count);
1241 /**
1242  *
1243  */
1244 void  CharacterDataImpl::replaceData(unsigned long offset,
1245                   unsigned long count,
1246                   const DOMString& arg)
1247                   throw(DOMException)
1249     nodeValue.replace(offset, count, arg);
1257 /*#########################################################################
1258 ## AttrImpl
1259 #########################################################################*/
1261 /**
1262  *
1263  */
1264 DOMString AttrImpl::getName()
1266     return nodeName;
1269 /**
1270  *
1271  */
1272 bool AttrImpl::getSpecified()
1274     return (nodeValue.size() > 0);
1277 /**
1278  *
1279  */
1280 DOMString AttrImpl::getValue()
1282     return nodeValue;
1285 /**
1286  *
1287  */
1288 void AttrImpl::setValue(const DOMString& val) throw(DOMException)
1290     nodeValue = val;
1293 /**
1294  *
1295  */
1296 ElementPtr AttrImpl::getOwnerElement()
1298     return ownerElement;
1302 /**
1303  *
1304  */
1305 TypeInfo &AttrImpl::getSchemaTypeInfo()
1307     return typeInfo;
1311 /**
1312  *
1313  */
1314 bool AttrImpl::getIsId()
1316     return (nodeName == "id");
1321 //##################
1322 //# Non-API methods
1323 //##################
1326 void AttrImpl::setOwnerElement(const ElementPtr elem)
1328     ownerElement = elem;
1331 /**
1332  *
1333  */
1334 AttrImpl::AttrImpl(DocumentImplPtr owner, const DOMString &theName)
1335                    : NodeImpl()
1337     nodeType     = ATTRIBUTE_NODE;
1338     ownerDocument = owner;
1339     setNodeName(theName);
1342 /**
1343  *
1344  */
1345 AttrImpl::AttrImpl(DocumentImplPtr owner,
1346                    const DOMString &/*theNamespaceURI*/,
1347                    const DOMString &theQualifiedName)
1348                    : NodeImpl()
1350     nodeType     = ATTRIBUTE_NODE;
1351     ownerDocument = owner;
1352     //if (owner)
1353     //    namespaceURI  = owner->stringCache(theNamespaceURI);
1354     setNodeName(theQualifiedName);
1357 /**
1358  *
1359  */
1360 AttrImpl::~AttrImpl()
1368 /*#########################################################################
1369 ## ElementImpl
1370 #########################################################################*/
1373 /**
1374  *
1375  */
1376 DOMString ElementImpl::getTagName()
1378     if (prefix.size() > 0)
1379         return prefix + ":" + nodeName;
1380     else
1381         return nodeName;
1384 /**
1385  *
1386  */
1387 DOMString ElementImpl::getAttribute(const DOMString& name)
1389     NodePtr node = attributes.getNamedItem(name);
1390     if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1391         return DOMString("");
1392     AttrPtr attr = dynamic_cast<Attr *>(node.get());
1393     return attr->getValue();
1396 /**
1397  *
1398  */
1399 void ElementImpl::setAttribute(const DOMString& name,
1400                   const DOMString& value)
1401                   throw(DOMException)
1403     AttrImplPtr attr = new AttrImpl(ownerDocument, name);
1404     attr->setValue(value);
1405     attr->setOwnerElement(this);
1406     attributes.setNamedItem(attr);
1409 /**
1410  *
1411  */
1412 void ElementImpl::removeAttribute(const DOMString& name)
1413                      throw(DOMException)
1415     attributes.removeNamedItem(name);
1418 /**
1419  *
1420  */
1421 AttrPtr ElementImpl::getAttributeNode(const DOMString& name)
1423     NodePtr node = attributes.getNamedItem(name);
1424     if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1425         return NULL;
1426     AttrPtr attr = dynamic_cast<Attr *>(node.get());
1427     return attr;
1430 /**
1431  *
1432  */
1433 AttrPtr ElementImpl::setAttributeNode(AttrPtr attr)
1434                       throw(DOMException)
1436     attributes.setNamedItem(attr);
1437     return attr;
1440 /**
1441  *
1442  */
1443 AttrPtr ElementImpl::removeAttributeNode(AttrPtr attr)
1444                          throw(DOMException)
1446     attributes.removeNamedItem(attr->getName());
1447     return attr;
1451 /**
1452  *
1453  */
1454 void ElementImpl::getElementsByTagNameRecursive(NodeList &list,
1455                         const DOMString& name, ElementPtr elem)
1457     if (!elem)
1458         return;
1460     if (name == elem->getTagName())
1461         list.add(elem);
1462     for (NodePtr node = elem->getFirstChild() ; node.get() ;
1463                        node=node->getNextSibling())
1464         {
1465         if (node->getNodeType() != Node::ELEMENT_NODE)
1466             continue;
1467         ElementPtr childElem = dynamic_cast<Element *>(node.get());
1468         getElementsByTagNameRecursive(list, name, childElem);
1469         }
1473 /**
1474  *
1475  */
1476 NodeList ElementImpl::getElementsByTagName(const DOMString& tagName)
1478     NodeList list;
1479     getElementsByTagNameRecursive(list, tagName, this);
1480     return list;
1483 /**
1484  *
1485  */
1486 DOMString ElementImpl::getAttributeNS(const DOMString& namespaceURI,
1487                          const DOMString& localName)
1489     NodePtr node = attributes.getNamedItemNS(namespaceURI, localName);
1490     if (!node || node->getNodeType()!=ATTRIBUTE_NODE)
1491         return DOMString("");
1492     AttrPtr attr = dynamic_cast<Attr *>(node.get());
1493     return attr->getValue();
1496 /**
1497  *
1498  */
1499 void ElementImpl::setAttributeNS(const DOMString& namespaceURI,
1500                     const DOMString& qualifiedName,
1501                     const DOMString& value)
1502                     throw(DOMException)
1504     AttrImplPtr attr = new AttrImpl(ownerDocument, namespaceURI, qualifiedName);
1505     attr->setValue(value);
1506     attr->setOwnerElement(this);
1507     attributes.setNamedItemNS(attr);
1510 /**
1511  *
1512  */
1513 void ElementImpl::removeAttributeNS(const DOMString& namespaceURI,
1514                        const DOMString& localName)
1515                        throw(DOMException)
1517     attributes.removeNamedItemNS(namespaceURI, localName);
1520 /**
1521  *
1522  */
1523  AttrPtr ElementImpl::getAttributeNodeNS(const DOMString& namespaceURI,
1524                         const DOMString& localName)
1526     NodePtr node = attributes.getNamedItemNS(namespaceURI, localName);
1527     if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1528         return (Attr *)0;
1529     AttrPtr attr = dynamic_cast<Attr *>(node.get());
1530     return attr;
1533 /**
1534  *
1535  */
1536 AttrPtr ElementImpl::setAttributeNodeNS(AttrPtr attr)
1537                         throw(DOMException)
1539     attributes.setNamedItemNS(attr);
1540     return attr;
1544 /**
1545  *
1546  */
1547 void ElementImpl::getElementsByTagNameNSRecursive(NodeList &list,
1548              const DOMString& namespaceURI,
1549                          const DOMString& tagName, ElementPtr elem)
1551     if (!elem)
1552         return;
1554     if (namespaceURI == elem->getNamespaceURI() && tagName == elem->getTagName())
1555         list.add(elem);
1556     for (NodePtr node = elem->getFirstChild() ; node.get() ; node=node->getNextSibling())
1557         {
1558         if (node->getNodeType() != Node::ELEMENT_NODE)
1559             continue;
1560         ElementPtr childElem = dynamic_cast<Element *>(node.get());
1561         getElementsByTagNameNSRecursive(list, namespaceURI, tagName, childElem);
1562         }
1565 /**
1566  *
1567  */
1568 NodeList ElementImpl::getElementsByTagNameNS(const DOMString& namespaceURI,
1569                                 const DOMString& localName)
1571     NodeList list;
1572     getElementsByTagNameNSRecursive(list, namespaceURI, localName, this);
1573     return list;
1576 /**
1577  *
1578  */
1579 bool ElementImpl::hasAttribute(const DOMString& attrName)
1581     NodePtr node = attributes.getNamedItem(attrName);
1582     if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1583         return false;
1584     return true;
1587 /**
1588  *
1589  */
1590 bool ElementImpl::hasAttributeNS(const DOMString& namespaceURI,
1591                     const DOMString& localName)
1593     NodePtr node = attributes.getNamedItemNS(namespaceURI, localName);
1594     if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1595         return false;
1596     return true;
1599 /**
1600  *
1601  */
1602 TypeInfo &ElementImpl::getSchemaTypeInfo()
1604     return typeInfo;
1608 /**
1609  *
1610  */
1611 void ElementImpl::setIdAttribute(const DOMString &/*name*/,
1612                             bool /*isId*/) throw (DOMException)
1614     //fixme
1617 /**
1618  *
1619  */
1620 void ElementImpl::setIdAttributeNS(const DOMString &/*namespaceURI*/,
1621                               const DOMString &/*localName*/,
1622                               bool /*isId*/) throw (DOMException)
1624     //fixme
1627 /**
1628  *
1629  */
1630 void ElementImpl::setIdAttributeNode(const AttrPtr /*idAttr*/,
1631                                 bool /*isId*/) throw (DOMException)
1633     //fixme
1637 //##################
1638 //# Non-API methods
1639 //##################
1642 /**
1643  *
1644  */
1645 ElementImpl::ElementImpl() : NodeImpl()
1647     nodeType = ELEMENT_NODE;
1650 /**
1651  *
1652  */
1653 ElementImpl::ElementImpl(DocumentImplPtr owner, const DOMString &tagName)
1654                                   : NodeImpl()
1656     nodeType = ELEMENT_NODE;
1657     ownerDocument = owner;
1658     setNodeName(tagName);
1661 /**
1662  *
1663  */
1664 ElementImpl::ElementImpl(DocumentImplPtr owner,
1665                          const DOMString &/*theNamespaceURI*/,
1666                          const DOMString &qualifiedName) :
1667                          NodeImpl()
1669     nodeType = ELEMENT_NODE;
1670     ownerDocument = owner;
1671     setNodeName(qualifiedName);
1674 /**
1675  *
1676  */
1677 ElementImpl::~ElementImpl()
1682 /**
1683  *
1684  */
1685 void ElementImpl::normalizeNamespaces()
1687     //printf("### NORMALIZE\n");
1689     NamedNodeMap attrs = getAttributes();
1691     //#######################################
1692     //# Pick up local namespace declarations
1693     //#######################################
1694     bindingsClear();  //Reset bindings on this node
1696     int nrAttrs = attrs.getLength();
1697     for (int i=0; i<nrAttrs ; i++)
1698         {
1699         NodePtr attrNode = attrs.item(i);
1700         if (attrNode->getNodeType() != Node::ATTRIBUTE_NODE)
1701             continue;
1702         AttrImplPtr attr = dynamic_cast<AttrImpl *>(attrNode.get());
1703         DOMString attrNS     = attr->getNamespaceURI();
1704         DOMString attrName   = attr->getLocalName();
1705         DOMString attrPrefix = attr->getPrefix();
1706         DOMString attrValue  = attr->getNodeValue();
1707         if (attrName != "xmlns" && attrPrefix != "xmlns")
1708             continue;
1710         //is the namespace declaration is invalid?
1711         if (attrValue == XMLNSNAME || attrName == attrPrefix)
1712             {
1713             // Note: The prefix xmlns is used only to declare namespace bindings and
1714             // is by definition bound to the namespace name http://www.w3.org/2000/xmlns/.
1715             // It must not be declared. No other prefix may be bound to this namespace name.
1717             //==> Report an error.
1718             printf("normalizeNamespaces() error: Namespace %s cannot be reassigned\n",
1719                         XMLNSNAME);
1721             }
1722         else
1723             {
1724             //==>  Record the namespace declaration
1725             attr->setNamespaceURI(XMLNSNAME);
1726             if (attrPrefix.size() > 0)
1727                 bindingsAdd(attrPrefix, attrValue);
1728             else
1729                 bindingsAdd("*", attrValue);//default
1731             }
1732         }
1735     //#######################################
1736     //# Fixup element's namespace
1737     //#######################################
1738     if ( namespaceURI.size() > 0 )
1739         {
1740         DOMString key = prefix;
1741         if (key.size() == 0)
1742             key = "*";
1743         DOMString binding = bindingsFind(key);
1744         //Element's prefix/namespace pair (or default namespace, if no prefix)
1745         // are within the scope of a binding
1746         if ( binding == namespaceURI )
1747             {
1748             //==> do nothing, declaration in scope is inherited
1750             // See section "B.1.1: Scope of a binding" for an example
1752             }
1753         else
1754             {
1756             /*
1757             ==> Create a local namespace declaration attr for this namespace,
1758             with Element's current prefix (or a default namespace, if
1759             no prefix). If there's a conflicting local declaration
1760             already present, change its value to use this namespace.
1762             See section "B.1.2: Conflicting namespace declaration" for an example
1763             */
1764             DOMString attrName = "xmlns";
1765             if (prefix.size() > 0)
1766                 {
1767                 attrName.append(":");
1768                 attrName.append(prefix);
1769                 }
1770             setAttribute(attrName, namespaceURI);
1771             // NOTE that this may break other nodes within this Element's
1772             // subtree, if they're already using this prefix.
1773             // They will be repaired when we reach them.
1774             }
1775         }
1776     else  // Element has no namespace URI:
1777         {
1778         //###############################################
1779         //# Bob -- alter this from the specs a bit.
1780         //#  Since the XmlReader does not set namespaces,
1781         //#    do it here
1782         //###############################################
1783         DOMString localName = getLocalName();
1784         if ( localName.size()==0 )
1785             {
1786             // DOM Level 1 node
1787             /*
1788             ==> if in process of validation against a namespace aware schema
1789             (i.e XML Schema) report a fatal error: the processor can not recover
1790             in this situation.
1791             Otherwise, report an error: no namespace fixup will be performed on this node.
1792             */
1793             printf("normalizeNamespaces() error: no localName\n");
1794             }
1795         else
1796             {
1797             // Element has no pseudo-prefix
1798             //there's a conflicting local default namespace declaration already present
1799             if ( prefix.size()==0 )
1800                 {
1801                 //==> change its value to use this empty namespace.
1802                 namespaceURI = bindingsFind("*");
1803                 //setAttribute("xmlns", "");
1804                 }
1805             else  //#BOB .   I added this.
1806                 {
1807                 namespaceURI = bindingsFind(prefix);
1808                 }
1809             // NOTE that this may break other nodes within this Element's
1810             // subtree, if they're already using the default namespaces.
1811             // They will be repaired when we reach them.
1812             }
1813         }
1816     //#######################################
1817     //# Examine and polish the attributes
1818     //#######################################
1819     nrAttrs = attrs.getLength();
1820     for (int i=0; i<nrAttrs ; i++)// all non-namespace Attrs of Element
1821         {
1822         NodePtr attrNode = attrs.item(i);
1823         if (attrNode->getNodeType() != Node::ATTRIBUTE_NODE)
1824             continue;
1825         AttrPtr attr = dynamic_cast<Attr *>(attrNode.get());
1826         DOMString attrNS     = attr->getNamespaceURI();
1827         DOMString attrPrefix = attr->getPrefix();
1828         DOMString attrValue  = attr->getNodeValue();
1829         if (attrNS == XMLNSNAME)
1830             continue;
1832         if ( attrNS.size()>0 ) //Attr[i] has a namespace URI
1833             {
1834             DOMString attrBinding = bindingsFind(attrPrefix);
1835             /*
1836              if attribute has no prefix (default namespace decl does not apply to attributes)
1837              OR
1838              attribute prefix is not declared
1839              OR
1840              conflict: attribute has a prefix that conflicts with a binding
1841                        already active in scope
1842             */
1843             if ( attrPrefix.size() == 0 || attrBinding.size() == 0)
1844                 {
1845                 //namespaceURI matches an in scope declaration of one or more prefixes)
1846                 DOMString prefixForNS = lookupNamespacePrefix(attrNS, this);
1847                 if ( prefixForNS.size() > 0 )
1848                     {
1849                     // pick the most local binding available;
1850                     // if there is more than one pick one arbitrarily
1852                     //==> change attribute's prefix.
1853                     attr->setPrefix(prefixForNS);
1854                     }
1855                 else
1856                     {
1857                     // the current prefix is not null and it has no in scope declaration)
1858                     if ( attrPrefix.size() > 0 || attrBinding.size() == 0 )
1859                         {
1860                         //==> declare this prefix
1861                         DOMString newAttrName = "xmlns:";
1862                         newAttrName.append(attrPrefix);
1863                         setAttribute(newAttrName, attrNS);
1864                         bindingsAdd(attrPrefix, attrNS);
1865                         }
1866                     else
1867                         {
1868                         // find a prefix following the pattern "NS" +index (starting at 1)
1869                         // make sure this prefix is not declared in the current scope.
1870                         // create a local namespace declaration attribute
1872                         //==> declare this prefix
1873                         char buf[16];
1874                         sprintf(buf, "%d" , ownerDocument->namespaceIndex++);
1875                         DOMString newPrefix = "NS";
1876                         newPrefix.append(buf);
1877                         DOMString newAttrName = "xmlns:";
1878                         newAttrName.append(newPrefix);
1879                         setAttribute(newAttrName, attrNS);
1880                         bindingsAdd(newPrefix, attrNS);
1881                         //==> change attribute's prefix.
1882                         }
1883                     }
1884                 }
1885             }
1886         else  // Attr has no namespace URI
1887             {
1888             // Attr has no localName
1889             if ( attr->getLocalName().size() == 0 )
1890                 {
1891                 // DOM Level 1 node
1892                 /*
1893                 ==> if in process of validation against a namespace aware schema
1894                 (i.e XML Schema) report a fatal error: the processor can not recover
1895                 in this situation.
1896                 Otherwise, report an error: no namespace fixup will be performed on this node.
1897                 */
1898                 printf("normalizeNamespaces:  no local name for attribute\n");
1899                 }
1900             else
1901                 {
1902                 // attr has no namespace URI and no prefix
1903                 // no action is required, since attrs don't use default
1904                 //==> do nothing
1905                 }
1906             }
1907         } // end for-all-Attrs
1910     //#######################################
1911     //# Recursively normalize children
1912     //#######################################
1913     for (NodePtr child=getFirstChild() ; child.get() ; child=child->getNextSibling())
1914         {
1915         if (child->getNodeType() != Node::ELEMENT_NODE)
1916             continue;
1917         ElementImplPtr childElement = dynamic_cast<ElementImpl *>(child.get());
1918         childElement->normalizeNamespaces();
1919         }
1924 /*#########################################################################
1925 ## TextImpl
1926 #########################################################################*/
1929 /**
1930  *
1931  */
1932 TextImpl::TextImpl() : CharacterDataImpl()
1934     nodeType = TEXT_NODE;
1935     nodeName = "#text";
1939 /**
1940  *
1941  */
1942 TextImpl::TextImpl(DocumentImplPtr owner, const DOMString &value)
1943                                : CharacterDataImpl()
1945     nodeType      = TEXT_NODE;
1946     nodeName      = "#text";
1947     ownerDocument = owner;
1948     nodeValue     = value;
1952 /**
1953  *
1954  */
1955 TextImpl::~TextImpl()
1959 /**
1960  *
1961  */
1962 TextPtr TextImpl::splitText(unsigned long /*offset*/)
1963                 throw(DOMException)
1965     return NULL;
1968 /**
1969  *
1970  */
1971 bool TextImpl::getIsElementContentWhitespace()
1973     return false;
1976 /**
1977  *
1978  */
1979 DOMString TextImpl::getWholeText()
1981     return nodeValue;
1985 /**
1986  *
1987  */
1988 TextPtr TextImpl::replaceWholeText(const DOMString &/*content*/)
1989                              throw(DOMException)
1991     return NULL;
1995 /*#########################################################################
1996 ## CommentImpl
1997 #########################################################################*/
1999 /**
2000  *
2001  */
2002 CommentImpl::CommentImpl() : CharacterDataImpl()
2004     nodeType = COMMENT_NODE;
2005     nodeName = "#comment";
2009 /**
2010  *
2011  */
2012 CommentImpl::CommentImpl(DocumentImplPtr owner, const DOMString &value)
2013                        : CharacterDataImpl()
2015     nodeType      = COMMENT_NODE;
2016     nodeName      = "#comment";
2017     ownerDocument = owner;
2018     nodeValue     = value;
2022 /**
2023  *
2024  */
2025 CommentImpl::~CommentImpl()
2035 /*#########################################################################
2036 ## UserDataHandlerImpl
2037 #########################################################################*/
2041 /**
2042  *
2043  */
2044 UserDataHandlerImpl::UserDataHandlerImpl()
2049 /**
2050  *
2051  */
2052 UserDataHandlerImpl::~UserDataHandlerImpl()
2056 /**
2057  *
2058  */
2059 void UserDataHandlerImpl::handle(unsigned short /*operation*/,
2060                      const DOMString &/*key*/,
2061                      const DOMUserData */*data*/,
2062                      const NodePtr /*src*/,
2063                      const NodePtr /*dst*/)
2065     //do nothing.  do we need anything here?
2070 /*#########################################################################
2071 ## DOMErrorImpl
2072 #########################################################################*/
2076 /**
2077  *
2078  */
2079 DOMErrorImpl::DOMErrorImpl()
2084 /**
2085  *
2086  */
2087 DOMErrorImpl::~DOMErrorImpl()
2091 /**
2092  *
2093  */
2094 unsigned short DOMErrorImpl::getSeverity()
2096     return severity;
2099 /**
2100  *
2101  */
2102 DOMString DOMErrorImpl::getMessage()
2104     return message;
2107 /**
2108  *
2109  */
2110 DOMString DOMErrorImpl::getType()
2112     return type;
2115 /**
2116  *
2117  */
2118 DOMObject *DOMErrorImpl::getRelatedException()
2120     return NULL;
2123 /**
2124  *
2125  */
2126 DOMObject *DOMErrorImpl::getRelatedData()
2128     return NULL;
2131 /**
2132  *
2133  */
2134 DOMLocator *DOMErrorImpl::getLocation()
2136     //really should fill this in
2137     return NULL;
2143 /*#########################################################################
2144 ## DOMErrorHandlerImpl
2145 #########################################################################*/
2149 /**
2150  *
2151  */
2152 DOMErrorHandlerImpl::DOMErrorHandlerImpl()
2157 /**
2158  *
2159  */
2160 DOMErrorHandlerImpl::~DOMErrorHandlerImpl()
2164 /**
2165  *
2166  */
2167 bool DOMErrorHandlerImpl::handleError(const DOMError *error)
2169     if (!error)
2170         return false;
2171     return true;
2177 /*#########################################################################
2178 ## DOMLocatorImpl
2179 #########################################################################*/
2182 /**
2183  *
2184  */
2185 DOMLocatorImpl::DOMLocatorImpl()
2190 /**
2191  *
2192  */
2193 DOMLocatorImpl::~DOMLocatorImpl()
2198 /**
2199  *
2200  */
2201 long DOMLocatorImpl::getLineNumber()
2203     return lineNumber;
2206 /**
2207  *
2208  */
2209 long DOMLocatorImpl::getColumnNumber()
2211     return columnNumber;
2214 /**
2215  *
2216  */
2217 long DOMLocatorImpl::getByteOffset()
2219     return byteOffset;
2222 /**
2223  *
2224  */
2225 long DOMLocatorImpl::getUtf16Offset()
2227     return utf16Offset;
2231 /**
2232  *
2233  */
2234 NodePtr DOMLocatorImpl::getRelatedNode()
2236     return relatedNode;
2240 /**
2241  *
2242  */
2243 DOMString DOMLocatorImpl::getUri()
2245     return uri;
2250 /*#########################################################################
2251 ## DOMConfigurationImpl
2252 #########################################################################*/
2255 /**
2256  *
2257  */
2258 DOMConfigurationImpl::DOMConfigurationImpl()
2263 /**
2264  *
2265  */
2266 DOMConfigurationImpl::~DOMConfigurationImpl()
2270 /**
2271  *
2272  */
2273 void DOMConfigurationImpl::setParameter(const DOMString &/*name*/,
2274                           const DOMUserData */*value*/) throw (DOMException)
2278 /**
2279  *
2280  */
2281 DOMUserData *DOMConfigurationImpl::getParameter(const DOMString &/*name*/)
2282                                   throw (DOMException)
2284     return NULL;
2287 /**
2288  *
2289  */
2290 bool DOMConfigurationImpl::canSetParameter(const DOMString &/*name*/,
2291                              const DOMUserData */*data*/)
2293     return false;
2296 /**
2297  *
2298  */
2299 DOMStringList *DOMConfigurationImpl::getParameterNames()
2301     return NULL;
2306 /*#########################################################################
2307 ## CDATASectionImpl
2308 #########################################################################*/
2310 /**
2311  *
2312  */
2313 CDATASectionImpl::CDATASectionImpl() : TextImpl()
2315     nodeType = CDATA_SECTION_NODE;
2316     nodeName = "#cdata-section";
2319 /**
2320  *
2321  */
2322 CDATASectionImpl::CDATASectionImpl(DocumentImplPtr owner, const DOMString &theValue)
2323                                  : TextImpl()
2325     nodeType      = CDATA_SECTION_NODE;
2326     nodeName      = "#cdata-section";
2327     ownerDocument = owner;
2328     nodeValue     = theValue;
2332 /**
2333  *
2334  */
2335 CDATASectionImpl::~CDATASectionImpl()
2343 /*#########################################################################
2344 ## DocumentTypeImpl
2345 #########################################################################*/
2347 /**
2348  *
2349  */
2350 DocumentTypeImpl::DocumentTypeImpl(const DOMString& theName,
2351                                    const DOMString& thePublicId,
2352                                    const DOMString& theSystemId)
2353                                   : NodeImpl()
2355     nodeType = DOCUMENT_TYPE_NODE;
2356     nodeName = theName;
2357     publicId = thePublicId;
2358     systemId = theSystemId;
2361 /**
2362  *
2363  */
2364 DocumentTypeImpl::~DocumentTypeImpl()
2368 /**
2369  *
2370  */
2371 DOMString DocumentTypeImpl::getName()
2373     return nodeName;
2376 /**
2377  *
2378  */
2379 NamedNodeMap DocumentTypeImpl::getEntities()
2381     return entities;
2384 /**
2385  *
2386  */
2387 NamedNodeMap DocumentTypeImpl::getNotations()
2389     return notations;
2392 /**
2393  *
2394  */
2395 DOMString DocumentTypeImpl::getPublicId()
2397     return publicId;
2400 /**
2401  *
2402  */
2403 DOMString DocumentTypeImpl::getSystemId()
2405     return systemId;
2408 /**
2409  *
2410  */
2411 DOMString DocumentTypeImpl::getInternalSubset()
2413     return DOMString("");
2421 /*#########################################################################
2422 ## NotationImpl
2423 #########################################################################*/
2427 /**
2428  *
2429  */
2430 NotationImpl::NotationImpl(DocumentImplPtr owner) : NodeImpl()
2432     nodeType = NOTATION_NODE;
2433     ownerDocument = owner;
2437 /**
2438  *
2439  */
2440 NotationImpl::~NotationImpl()
2444 /**
2445  *
2446  */
2447 DOMString NotationImpl::getPublicId()
2449     return publicId;
2452 /**
2453  *
2454  */
2455 DOMString NotationImpl::getSystemId()
2457     return systemId;
2467 /*#########################################################################
2468 ## EntityImpl
2469 #########################################################################*/
2472 /**
2473  *
2474  */
2475 EntityImpl::EntityImpl() : NodeImpl()
2477     nodeType = ENTITY_NODE;
2481 /**
2482  *
2483  */
2484 EntityImpl::EntityImpl(DocumentImplPtr owner) : NodeImpl()
2486     nodeType = ENTITY_NODE;
2487     ownerDocument = owner;
2491 /**
2492  *
2493  */
2494 EntityImpl::~EntityImpl()
2498 /**
2499  *
2500  */
2501 DOMString EntityImpl::getPublicId()
2503     return publicId;
2506 /**
2507  *
2508  */
2509 DOMString EntityImpl::getSystemId()
2511     return systemId;
2514 /**
2515  *
2516  */
2517 DOMString EntityImpl::getNotationName()
2519     return notationName;
2522 /**
2523  *
2524  */
2525 DOMString EntityImpl::getInputEncoding()
2527     return inputEncoding;
2530 /**
2531  *
2532  */
2533 DOMString EntityImpl::getXmlEncoding()
2535     return xmlEncoding;
2538 /**
2539  *
2540  */
2541 DOMString EntityImpl::getXmlVersion()
2543     return xmlVersion;
2551 /*#########################################################################
2552 ## EntityReferenceImpl
2553 #########################################################################*/
2557 /**
2558  *
2559  */
2560 EntityReferenceImpl::EntityReferenceImpl() : NodeImpl()
2562     nodeType = ENTITY_REFERENCE_NODE;
2566 /**
2567  *
2568  */
2569 EntityReferenceImpl::EntityReferenceImpl(DocumentImplPtr owner,
2570                                          const DOMString &theName)
2571                                          : NodeImpl()
2573     nodeType = ENTITY_REFERENCE_NODE;
2574     nodeName = theName;
2575     ownerDocument = owner;
2579 /**
2580  *
2581  */
2582 EntityReferenceImpl::~EntityReferenceImpl()
2588 /*#########################################################################
2589 ## ProcessingInstructionImpl
2590 #########################################################################*/
2595 /**
2596  *
2597  */
2598 ProcessingInstructionImpl::ProcessingInstructionImpl(): NodeImpl()
2600     nodeType = PROCESSING_INSTRUCTION_NODE;
2605 /**
2606  *
2607  */
2608 ProcessingInstructionImpl::ProcessingInstructionImpl(DocumentImplPtr owner,
2609                                                      const DOMString &target,
2610                                                      const DOMString &data)
2611                                                      : NodeImpl()
2613     nodeType      = PROCESSING_INSTRUCTION_NODE;
2614     ownerDocument = owner;
2615     nodeName      = target;
2616     nodeValue     = data;
2620 /**
2621  *
2622  */
2623 ProcessingInstructionImpl::~ProcessingInstructionImpl()
2630 /**
2631  *
2632  */
2633 DOMString ProcessingInstructionImpl::getTarget()
2635     return nodeName;
2638 /**
2639  *
2640  */
2641 DOMString ProcessingInstructionImpl::getData()
2643     return nodeValue;
2646 /**
2647  *
2648  */
2649 void ProcessingInstructionImpl::setData(const DOMString& /*val*/) throw(DOMException)
2651      //do something here
2660 /*#########################################################################
2661 ## DocumentFragmentImpl
2662 #########################################################################*/
2664 /**
2665  *
2666  */
2667 DocumentFragmentImpl::DocumentFragmentImpl() : NodeImpl()
2669     nodeType = DOCUMENT_FRAGMENT_NODE;
2670     nodeName = "#document-fragment";
2674 /**
2675  *
2676  */
2677 DocumentFragmentImpl::DocumentFragmentImpl(DocumentImplPtr owner) : NodeImpl()
2679     nodeType = DOCUMENT_FRAGMENT_NODE;
2680     nodeName = "#document-fragment";
2681     ownerDocument = owner;
2685 /**
2686  *
2687  */
2688 DocumentFragmentImpl::~DocumentFragmentImpl()
2697 /*#########################################################################
2698 ## DocumentImpl
2699 #########################################################################*/
2703 /**
2704  *
2705  */
2706 DocumentTypePtr DocumentImpl::getDoctype()
2708     return doctype;
2711 /**
2712  *
2713  */
2714 DOMImplementation *DocumentImpl::getImplementation()
2716     return parent;
2719 /**
2720  *
2721  */
2722 ElementPtr DocumentImpl::getDocumentElement()
2724     return documentElement;
2727 /**
2728  *
2729  */
2730 ElementPtr DocumentImpl::createElement(const DOMString& tagName)
2731                        throw(DOMException)
2733     ElementPtr elem = new ElementImpl(this, tagName);
2734     return elem;
2737 /**
2738  *
2739  */
2740 DocumentFragmentPtr DocumentImpl::createDocumentFragment()
2742     DocumentFragmentPtr frag = new DocumentFragmentImpl(this);
2743     return frag;
2746 /**
2747  *
2748  */
2749 TextPtr DocumentImpl::createTextNode(const DOMString& data)
2751     TextPtr text = new TextImpl(this, data);
2752     return text;
2755 /**
2756  *
2757  */
2758 CommentPtr DocumentImpl::createComment(const DOMString& data)
2760     CommentPtr comment = new CommentImpl(this, data);
2761     return comment;
2764 /**
2765  *
2766  */
2767 CDATASectionPtr DocumentImpl::createCDATASection(const DOMString& data)
2768                                  throw(DOMException)
2770     CDATASectionPtr cdata = new CDATASectionImpl(this, data);
2771     return cdata;
2774 /**
2775  *
2776  */
2777 ProcessingInstructionPtr 
2778 DocumentImpl::createProcessingInstruction(const DOMString& target,
2779                                           const DOMString& data)
2780                                           throw(DOMException)
2782     ProcessingInstructionPtr pi =
2783         new ProcessingInstructionImpl(this, target, data);
2784     return pi;
2787 /**
2788  *
2789  */
2790 AttrPtr DocumentImpl::createAttribute(const DOMString& attrName)
2791                       throw(DOMException)
2793     AttrPtr attr = new AttrImpl(this, attrName);
2794     return attr;
2797 /**
2798  *
2799  */
2800 EntityReferencePtr DocumentImpl::createEntityReference(const DOMString& erName)
2801                                        throw(DOMException)
2803     EntityReferencePtr ref = new EntityReferenceImpl(this, erName);
2804     return ref;
2808 /**
2809  *
2810  */
2811 NodeList DocumentImpl::getElementsByTagName(const DOMString& tagname)
2813     NodeList list;
2814     ElementImpl::getElementsByTagNameRecursive(list,
2815                      tagname, documentElement);
2816     return list;
2820 /**
2821  *
2822  */
2823 NodePtr DocumentImpl::importNode(const NodePtr /*importedNode*/,
2824                  bool /*deep*/)
2825                  throw(DOMException)
2827     return NULL;
2830 /**
2831  *
2832  */
2833 ElementPtr DocumentImpl::createElementNS(const DOMString& namespaceURI,
2834                          const DOMString& qualifiedName)
2835                          throw(DOMException)
2837     ElementPtr elem = new ElementImpl(this, namespaceURI, qualifiedName);
2838     return elem;
2841 /**
2842  *
2843  */
2844 AttrPtr DocumentImpl::createAttributeNS(const DOMString& namespaceURI,
2845                         const DOMString& qualifiedName)
2846                         throw(DOMException)
2848     AttrPtr attr = new AttrImpl(this, namespaceURI, qualifiedName);
2849     return attr;
2853 /**
2854  *
2855  */
2856 NodeList DocumentImpl::getElementsByTagNameNS(const DOMString& namespaceURI,
2857                                  const DOMString& localName)
2859     NodeList list;
2860     ElementImpl::getElementsByTagNameNSRecursive(list, namespaceURI,
2861                           localName, documentElement);
2862     return list;
2865 /**
2866  *
2867  */
2868 ElementPtr DocumentImpl::getElementById(const DOMString& elementId)
2870     for (NamedElementItem *entry = elementsById.next; entry ; entry=entry->next)
2871         if (entry->name == elementId)
2872             return entry->elem;
2873     return NULL;
2877 /**
2878  *
2879  */
2880 DOMString DocumentImpl::getInputEncoding()
2882     return inputEncoding;
2886 /**
2887  *
2888  */
2889 DOMString DocumentImpl::getXmlEncoding()
2891     return xmlEncoding;
2894 /**
2895  *
2896  */
2897 bool DocumentImpl::getXmlStandalone()
2899     return xmlStandalone;
2902 /**
2903  *
2904  */
2905 void DocumentImpl::setXmlStandalone(bool val) throw (DOMException)
2907     xmlStandalone = val;
2910 /**
2911  *
2912  */
2913 DOMString DocumentImpl::getXmlVersion()
2915     return xmlVersion;
2918 /**
2919  *
2920  */
2921 void DocumentImpl::setXmlVersion(const DOMString &version) throw (DOMException)
2923     xmlVersion = version;
2926 /**
2927  *
2928  */
2929 bool DocumentImpl::getStrictErrorChecking()
2931     return strictErrorChecking;
2934 /**
2935  *
2936  */
2937 void DocumentImpl::setStrictErrorChecking(bool val)
2939     strictErrorChecking = val;
2943 /**
2944  *
2945  */
2946 DOMString DocumentImpl::getDocumentURI()
2948     return documentURI;
2951 /**
2952  *
2953  */
2954 void DocumentImpl::setDocumentURI(const DOMString &/*uri*/)
2956     //documentURI = stringCache(uri);
2959 /**
2960  *
2961  */
2962 NodePtr DocumentImpl::adoptNode(const NodePtr source) throw (DOMException)
2964     return (NodePtr )source;
2967 /**
2968  *
2969  */
2970 DOMConfiguration *DocumentImpl::getDomConfig()
2972     return domConfig;
2975 /**
2976  *
2977  */
2978 void DocumentImpl::normalizeDocument()
2980     //i assume that this means adjusting namespaces & prefixes
2981     if (documentElement.get())
2982         documentElement->normalizeNamespaces();
2985 /**
2986  *
2987  */
2988 NodePtr DocumentImpl::renameNode(const NodePtr node,
2989                                const DOMString &/*namespaceURI*/,
2990                                const DOMString &qualifiedName)
2991                                throw (DOMException)
2993     NodeImplPtr nodeImpl = dynamic_cast<NodeImpl *> (node.get());
2994     nodeImpl->setNodeName(qualifiedName);
2995     return node;
3000 //##################
3001 //# Non-API methods
3002 //##################
3004 /**
3005  *
3006  */
3007 DocumentImpl::DocumentImpl(const DOMImplementation *domImpl,
3008                  const DOMString &/*theNamespaceURI*/,
3009                  const DOMString &theQualifiedName,
3010                  const DocumentTypePtr theDoctype) : NodeImpl()
3012     nodeType        = DOCUMENT_NODE;
3013     nodeName        = "#document";
3014     parent          = (DOMImplementation *)domImpl;
3015     //documentURI     = stringCache(theNamespaceURI);
3016     qualifiedName   = theQualifiedName;
3017     if (theDoctype.get()) //only assign if not null.
3018         doctype     = theDoctype;
3019     else
3020         doctype     = new DocumentTypeImpl("", "", "");
3021     documentElement = new ElementImpl(this, "root");
3022     namespaceIndex  = 0;
3026 /**
3027  *
3028  */
3029 DocumentImpl::~DocumentImpl()
3031     documentElement = NULL;
3045 }  //namespace dom
3046 }  //namespace w3c
3047 }  //namespace org
3051 /*#########################################################################
3052 ## E N D    O F    F I L E
3053 #########################################################################*/