Code

Indent support for XSLT extensions output.
[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 <cstdio>
32 #include "domimpl.h"
34 namespace org
35 {
36 namespace w3c
37 {
38 namespace dom
39 {
42 /**
43  *  Test if the given substring exists for the length of the string
44  *  in a given buffer
45  */
46 /*
47 static bool match(const DOMString &buf, char *str)
48 {
49     int pos = 0;
50     while (*str)
51        {
52        if (buf[pos++] != *str++)
53            return false;
54        }
55    return true;
56 }
57 */
61 /*#########################################################################
62 ## DOMImplementationSourceImpl
63 #########################################################################*/
66 /**
67  *
68  */
69 DOMImplementationSourceImpl::DOMImplementationSourceImpl()
70 {
71     domImpl     = new DOMImplementationImpl();
72 }
74 /**
75  *
76  */
77 DOMImplementationSourceImpl::~DOMImplementationSourceImpl()
78 {
79     delete domImpl;
80 }
82 /**
83  *
84  */
85 DOMImplementation *DOMImplementationSourceImpl::getDOMImplementation(
86                                                                      const DOMString &/*features*/)
87 {
88     return domImpl;
89 }
91 /**
92  *
93  */
94 DOMImplementationList DOMImplementationSourceImpl::getDOMImplementationList(
95                                                                             const DOMString &/*features*/)
96 {
97     return domImplList;
98 }
106 /*#########################################################################
107 ## DOMImplementationImpl
108 #########################################################################*/
111 /**
112  *
113  */
114 DOMImplementationImpl::DOMImplementationImpl()
118 /**
119  *
120  */
121 DOMImplementationImpl::~DOMImplementationImpl()
125 /**
126  *
127  */
128 bool DOMImplementationImpl::hasFeature(const DOMString& /*feature*/,
129                                        const DOMString& /*version*/)
131     return false;
135 /**
136  *
137  */
138 DocumentTypePtr DOMImplementationImpl::createDocumentType(const DOMString& qualifiedName,
139                                  const DOMString& publicId,
140                                  const DOMString& systemId)
141                                  throw(DOMException)
143     DocumentTypePtr typeImpl = new DocumentTypeImpl(qualifiedName,
144                                          publicId, systemId);
145     return typeImpl;
148 /**
149  *
150  */
151 DocumentPtr DOMImplementationImpl::createDocument(
152                          const DOMString& namespaceURI,
153                          const DOMString& qualifiedName,
154                          DocumentTypePtr  doctype)
155                          throw(DOMException)
157     DocumentPtr doc = new DocumentImpl(this,
158                                        namespaceURI,
159                                        qualifiedName,
160                                        doctype);
161     return doc;
164 /**
165  *
166  */
167 DOMObject *DOMImplementationImpl::getFeature(const DOMString& /*feature*/,
168                                              const DOMString& /*version*/)
171     return NULL;
178 /*#########################################################################
179 ## NodeImpl
180 #########################################################################*/
182 /**
183  * Utility for finding the first Element above
184  * a given node.  Used by several methods below
185  */
186 static NodePtr getAncestorElement(NodePtr node)
188     if (!node.get())
189         return NULL;
190     node = node->getParentNode();
191     //Either quit because I am an element, or because I am null
192     while (node.get())
193         {
194         if (node->getNodeType() == Node::ELEMENT_NODE)
195             return node;
196         node = node->getParentNode();
197         }
198     return node;
201 /**
202  *
203  */
204 DOMString NodeImpl::getNodeName()
206     return nodeName;
209 /**
210  *
211  */
212 DOMString NodeImpl::getNodeValue() throw (DOMException)
214     return nodeValue;
217 /**
218  *
219  */
220 void NodeImpl::setNodeValue(const DOMString& val) throw (DOMException)
222     nodeValue = val;
225 /**
226  *
227  */
228 unsigned short NodeImpl::getNodeType()
230     return nodeType;
233 /**
234  *
235  */
236 NodePtr NodeImpl::getParentNode()
238     return parent;
241 /**
242  *
243  */
244 NodeList NodeImpl::getChildNodes()
246     NodeList list;
247     for (NodeImplPtr node = firstChild ; node.get() ; node=node->next)
248         list.add(node);
249     return list;
252 /**
253  *
254  */
255 NodePtr NodeImpl::getFirstChild()
257     return firstChild;
260 /**
261  *
262  */
263 NodePtr NodeImpl::getLastChild()
265     return lastChild;
268 /**
269  *
270  */
271 NodePtr NodeImpl::getPreviousSibling()
273     return prev;
276 /**
277  *
278  */
279 NodePtr NodeImpl::getNextSibling()
281     return next;
284 /**
285  *
286  */
287 NamedNodeMap &NodeImpl::getAttributes()
289     NamedNodeMap &attrs = attributes;
290     return attrs;
294 /**
295  *
296  */
297 DocumentPtr NodeImpl::getOwnerDocument()
299     return ownerDocument;
302 /**
303  *
304  */
305 NodePtr NodeImpl::insertBefore(const NodePtr newChild,
306                                const NodePtr refChild)
307                                throw(DOMException)
309     if (!newChild)
310         return NULL;
311         
312     //if no ref, then just append
313     if (!refChild)
314         return appendChild(newChild);
316     NodeImplPtr newChildImpl = dynamic_cast<NodeImpl *>(newChild.get());
317     for (NodeImplPtr n = firstChild ; n.get() ; n=n->next)
318         {
319         if (n == refChild)
320             {
321             //link to new
322             if (n->prev.get())
323                 n->prev->next = newChildImpl;
324             else
325                 firstChild = newChildImpl;
326             n->prev = newChildImpl;
327             //link from new
328             newChildImpl->next = n;
329             newChildImpl->prev = n->prev;
330             //reflect new location
331             newChildImpl->parent        = this;
332             newChildImpl->ownerDocument = ownerDocument;
333             return n;
334             }
335         }
336     return NULL;
339 /**
340  *
341  */
342 NodePtr NodeImpl::replaceChild(const NodePtr newChild,
343                                const NodePtr oldChild)
344                                throw(DOMException)
346     if (!oldChild)
347         return NULL;
349     NodeImplPtr newChildImpl = dynamic_cast<NodeImpl *>(newChild.get());
350     for (NodeImplPtr n = firstChild ; n.get() ; n=n->next)
351         {
352         if (n == oldChild)
353             {
354             //link to new
355             if (n->prev.get())
356                 n->prev->next = newChildImpl;
357             else
358                 firstChild = newChildImpl;
359             if (n->next.get())
360                 n->next->prev = newChildImpl;
361             else
362                 lastChild = newChildImpl;
363             //link from new
364             newChildImpl->next = n->next;
365             newChildImpl->prev = n->prev;
366             //reflect new location
367             newChildImpl->parent        = this;
368             newChildImpl->ownerDocument = ownerDocument;
369             return n;
370             }
371         }
372     return NULL;
375 /**
376  *
377  */
378 NodePtr NodeImpl::removeChild(const NodePtr oldChild)
379                               throw(DOMException)
381     if (!oldChild)
382         return NULL;
384     for (NodeImplPtr n = firstChild ; n.get() ; n=n->next)
385         {
386         if (n == oldChild)
387             {
388             if (n->prev.get())
389                 n->prev->next = n->next;
390             if (n->next.get())
391                 n->next->prev = n->prev;
392             return n;
393             }
394         }
395     return NULL;
398 /**
399  *
400  */
401 NodePtr NodeImpl::appendChild(const NodePtr newChild)
402                              throw(DOMException)
404     if (!newChild)
405         return NULL;
407     NodeImplPtr newChildImpl =
408              dynamic_cast<NodeImpl *> (newChild.get());
410     newChildImpl->parent        = this;
411     newChildImpl->ownerDocument = ownerDocument;
413     if (!firstChild || !lastChild)
414         {
415         //Set up our first member
416         firstChild = newChildImpl;
417         lastChild  = newChildImpl;
418         }
419     else
420         {
421         //link at the last position
422         lastChild->next    = newChildImpl;
423         newChildImpl->prev = lastChild;
424         lastChild          = newChildImpl;
425         }
427     return newChild;
430 /**
431  *
432  */
433 bool NodeImpl::hasChildNodes()
435     return (firstChild != (NodeImpl *)0);
438 /**
439  *
440  */
441 NodePtr NodeImpl::cloneNode(bool deep)
443     NodeImplPtr node    = new NodeImpl(ownerDocument, nodeName);
444     node->parent        = parent;
445     node->prev          = prev;
446     node->next          = next;
447     node->userData      = userData;
448     node->nodeValue     = nodeValue;
450     if (deep)
451         {
452         node->firstChild = node->lastChild = NULL;
453         for (NodeImplPtr child = firstChild ; child.get() ; child=child->next)
454             {
455             node->appendChild(child->cloneNode(deep));
456             }
457         }
458     else
459         {
460         node->firstChild = firstChild;
461         node->lastChild  = lastChild;
462         }
464     return node;
467 /**
468  *  Concatenate adjoining text subnodes, remove null-length nodes
469  */
470 void NodeImpl::normalize()
472     //First, concatenate adjoining text nodes
473     NodeImplPtr next = (NodeImpl *)0;
474     for (NodeImplPtr child = firstChild ; child.get() ; child=next)
475         {
476         if (child->getNodeType() != Node::TEXT_NODE)
477             continue;
478         next = NULL;
479         DOMString sval = child->getNodeValue();
480         for (NodeImplPtr sibling = child->next ; sibling.get() ; sibling=next)
481             {
482             next = sibling->next;
483             if (sibling->getNodeType() != Node::TEXT_NODE)
484                 break;
485             sval.append(sibling->getNodeValue());
486             //unlink and delete
487             child->next = sibling->next;
488             if (sibling->next.get())
489                 sibling->next->prev = child;
490             //delete sibling;
491             }
492         child->setNodeValue(sval);
493         }
495     //Next, we remove zero-length text subnodes
496     next = NULL;
497     for (NodeImplPtr child = firstChild ; child.get() ; child=next)
498         {
499         next = child->next;
500         if (child->getNodeType() != Node::TEXT_NODE)
501             continue;
502         if (child->getNodeValue().size() == 0)
503             {
504             //unlink and delete
505             if (child->prev.get())
506                 child->prev->next = child->next;
507             if (child->next.get())
508                 child->next->prev = child->prev;
509             //delete child;
510             }
511         }
515 /**
516  *
517  */
518 bool NodeImpl::isSupported(const DOMString& /*feature*/,
519                            const DOMString& /*version*/)
521     //again, no idea
522     return false;
525 /**
526  *
527  */
528 DOMString NodeImpl::getNamespaceURI()
530     return namespaceURI;
533 /**
534  *
535  */
536 DOMString NodeImpl::getPrefix()
538     return prefix;
541 /**
542  *
543  */
544 void NodeImpl::setPrefix(const DOMString& val) throw(DOMException)
546     prefix = val;
547     if (prefix.size()>0)
548         nodeName = prefix + ":" + localName;
549     else
550         nodeName = localName;
553 /**
554  *
555  */
556 DOMString NodeImpl::getLocalName()
558     return localName;
561 /**
562  *
563  */
564 bool NodeImpl::hasAttributes()
566     return (attributes.getLength() > 0);
569 /**
570  *
571  */
572 DOMString NodeImpl::getBaseURI()
574     return baseURI;
577 /**
578  *
579  */
580 unsigned short NodeImpl::compareDocumentPosition(const NodePtr otherArg)
582     if (!otherArg || otherArg == (NodePtr )this)
583         return 0;//no flags
585     NodePtr node;
586     NodePtr other = otherArg;
588     //Look above me
589     for (node=getParentNode() ; node.get() ; node=node->getParentNode())
590         if (node == other)
591             return DOCUMENT_POSITION_CONTAINED_BY;
593     //Look above the other guy. See me?
594     for (node=other->getParentNode() ; node.get() ; node=node->getParentNode())
595         if (node == (NodePtr )this)
596             return DOCUMENT_POSITION_CONTAINS;
599     return DOCUMENT_POSITION_DISCONNECTED |
600            DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
603 /**
604  *
605  */
606 DOMString NodeImpl::getTextContent() throw(DOMException)
608     DOMString buf;
609     if (nodeType == TEXT_NODE          ||
610             nodeType == CDATA_SECTION_NODE ||
611                 nodeType == COMMENT_NODE       ||
612                 nodeType == PROCESSING_INSTRUCTION_NODE)
613                 buf = getNodeValue();
614     else if (nodeType == ELEMENT_NODE      ||
615                  nodeType == ATTRIBUTE_NODE         ||
616                      nodeType == ENTITY_NODE            ||
617                      nodeType == ENTITY_REFERENCE_NODE  ||
618                      nodeType == DOCUMENT_FRAGMENT_NODE)
619                 {
620                 for (NodePtr n = getFirstChild() ; n.get() ;
621                      n=n->getNextSibling() )
622                     {
623             if (n->getNodeType() != COMMENT_NODE &&
624                         n->getNodeType() != COMMENT_NODE)
625                 buf.append(n->getTextContent());
626                     }
627                 }
628     return buf;
632 /**
633  *
634  */
635 void NodeImpl::setTextContent(const DOMString &val) throw(DOMException)
637     //Delete children
638     /** Not necessary.  Just let smart pointers to their work
639         for (NodePtr n = getFirstChild() ; n.get() ;
640                            n=n->getNextSibling() )
641         delete n;
642     */
643     firstChild = lastChild = NULL;
645     //Replace with a single text node
646     NodeImplPtr tnode = new NodeImpl(ownerDocument);
647     tnode->nodeType = Node::TEXT_NODE;
648     tnode->setNodeValue(val);
649     appendChild(tnode);
653 /**
654  * From DOM3 Namespace algorithms
655  */
656 DOMString NodeImpl::lookupPrefix(const DOMString &theNamespaceURI)
659     if (theNamespaceURI.size()==0)
660         {
661         return DOMString("");
662         }
664     switch (nodeType)
665         {
666         case Node::ELEMENT_NODE:
667             {
668             ElementPtr elem = (Element *)this;
669             return lookupNamespacePrefix(theNamespaceURI, elem);
670             }
671         case Node::DOCUMENT_NODE:
672             {
673             DocumentPtr doc = (Document *)this;
674             ElementPtr elem = doc->getDocumentElement();
675             return elem->lookupPrefix(theNamespaceURI);
676             }
677         case Node::ENTITY_NODE :
678         case Node::NOTATION_NODE:
679         case Node::DOCUMENT_FRAGMENT_NODE:
680         case Node::DOCUMENT_TYPE_NODE:
681             return DOMString("");  // type is unknown
682         case Node::ATTRIBUTE_NODE:
683             {
684             AttrPtr attr = (Attr *)this;
685             ElementPtr elem = attr->getOwnerElement();
686             if ( elem.get() )
687                 {
688                 return elem->lookupPrefix(theNamespaceURI);
689                 }
690              return DOMString("");
691             }
692         default:
693             {
694             //Get ancestor element, if any
695             NodePtr ancestor = getAncestorElement(this);
696             if ( ancestor.get() )
697                {
698                return ancestor->lookupPrefix(theNamespaceURI);
699                }
700             return DOMString("");
701             }
702         }//switch
703     return DOMString("");
707 /**
708  *
709  */
710 bool NodeImpl::isDefaultNamespace(const DOMString &theNamespaceURI)
712     switch (nodeType)
713         {
714         case ELEMENT_NODE:
715             {
716             if ( namespaceURI.size()>0 && prefix.size()==0 )
717                 {
718                 return (namespaceURI == theNamespaceURI);
719                 }
720             NodePtr attr = attributes.getNamedItem("xmlns");
721             if ( attr.get() )
722                 {
723                 return (attr->getNodeValue() == theNamespaceURI);
724                 }
726             NodePtr ancestor = getAncestorElement(this);
727             if ( ancestor.get() )
728                 {
729                 return ancestor->isDefaultNamespace(theNamespaceURI);
730                 }
731             else
732                 {
733                 return false;
734                 }
735             }
736         case DOCUMENT_NODE:
737             { //just use braces for local declaration
738             DocumentPtr doc = (Document *)this;
739             ElementPtr elem = doc->getDocumentElement();
740             return elem->isDefaultNamespace(theNamespaceURI);
741             }
742         case ENTITY_NODE:
743         case NOTATION_NODE:
744         case DOCUMENT_TYPE_NODE:
745         case DOCUMENT_FRAGMENT_NODE:
746             return false;
747         case ATTRIBUTE_NODE:
748             {//braces only for scope
749             AttrPtr attr = (Attr *)this;
750             ElementPtr ownerElement = attr->getOwnerElement();
751             if ( ownerElement.get() )
752                 {
753                 return ownerElement->isDefaultNamespace(theNamespaceURI);
754                 }
755             else
756                 {
757                 return false;
758                 }
759             }
760         default:
761             {
762             NodePtr ancestor = getAncestorElement(this);
763             if ( ancestor.get() )
764                 {
765                 return ancestor->isDefaultNamespace(theNamespaceURI);
766                 }
767             else
768                 {
769                 return false;
770                 }
771             }
772         }//switch
774     return false;
778 /**
779  *
780  */
781 DOMString NodeImpl::lookupNamespaceURI(const DOMString &thePrefix)
783     switch (nodeType)
784         {
785         case ELEMENT_NODE:
786             {
787             if ( namespaceURI.size()>0 && prefix == thePrefix )
788                 {
789                 DOMString nsURI = namespaceURI;
790                 return (nsURI);
791                 }
792             if ( hasAttributes() )
793                 {
794                 NamedNodeMap attributes = getAttributes();
795                 int nrAttrs = attributes.getLength();
796                 for (int i=0 ; i<nrAttrs ; i++)
797                     {
798                     NodePtr attr = attributes.item(i);
799                     if (attr->getPrefix() == "xmlns" && attr->getLocalName() == thePrefix )
800                         { // non default namespace
801                         if (attr->getNodeValue().size()>0)
802                             {
803                             return (attr->getNodeValue());
804                             }
805                         return DOMString("");
806                         }
807                     else if (attr->getLocalName() == "xmlns" && thePrefix.size()==0)
808                         { // default namespace
809                         if (attr->getNodeValue().size()>0)
810                             {
811                             return (attr->getNodeValue());
812                             }
813                         return DOMString("");
814                         }
815                     }
816                 }
818             NodePtr ancestor = getAncestorElement(this);
819             if ( ancestor.get() )
820                 {
821                 return ancestor->lookupNamespaceURI(thePrefix);
822                 }
823             return DOMString("");
824             }
825         case DOCUMENT_NODE:
826             {
827             DocumentPtr doc = (Document *)this;
828             ElementPtr elem = doc->getDocumentElement();
829             return elem->lookupNamespaceURI(thePrefix);
830             }
831         case ENTITY_NODE:
832         case NOTATION_NODE:
833         case DOCUMENT_TYPE_NODE:
834         case DOCUMENT_FRAGMENT_NODE:
835             return DOMString("");
837         case ATTRIBUTE_NODE:
838             {
839             ElementPtr ownerElement = ((Attr *)this)->getOwnerElement();
840             if ( ownerElement.get() )
841                 {
842                 return ownerElement->lookupNamespaceURI(thePrefix);
843                 }
844             else
845                 {
846                 return DOMString("");
847                 }
848             }
849         default:
850             {
851             NodePtr ancestor = getAncestorElement(this);
852             if ( ancestor.get() )
853                 {
854                 return ancestor->lookupNamespaceURI(thePrefix);
855                 }
856             else
857                 {
858                 return DOMString("");
859                 }
860             }
861         }//switch
865 /**
866  *
867  */
868 bool NodeImpl::isEqualNode(const NodePtr nodeArg)
870     if (!nodeArg)
871         return false;
873     if (nodeArg == (NodePtr )this)
874         return true;
876     NodePtr node = nodeArg;
878     if (getNodeType()     != node->getNodeType()     ||
879         getNodeName()     != node->getNodeName()     ||
880         getLocalName()    != node->getLocalName()    ||
881         getNamespaceURI() != node->getNamespaceURI() ||
882         getPrefix()       != node->getPrefix()       ||
883         getNodeValue()    != node->getNodeValue()    ||
884         getBaseURI()      != node->getBaseURI()      )
885         return false;
887     return true;
892 /**
893  *
894  */
895 DOMObject *NodeImpl::getFeature(const DOMString &/*feature*/,
896                                 const DOMString &/*version*/)
898     //dont know
899     return NULL;
902 /**
903  *
904  */
905 DOMUserData *NodeImpl::setUserData(const DOMString &key,
906                                    const DOMUserData *data,
907                                    const UserDataHandler *handler)
909     UserDataEntry *entry = userDataEntries;
910     UserDataEntry *prev  = NULL;
911     while (entry)
912         {
913         if (entry->key == key)
914             {
915             DOMUserData *oldData = entry->data;
916             entry->data    = (DOMUserData *)data;
917             entry->handler = (UserDataHandler *)handler;
918             return oldData;
919             }
920         prev  = entry;
921         entry = entry->next;
922         }
924     //Make a new one
925     UserDataEntry *newEntry = new UserDataEntry(key, data, handler);
926     if (!prev)
927         userDataEntries = newEntry;
928     else
929         prev->next = newEntry;
931     return NULL;
934 /**
935  *
936  */
937 DOMUserData *NodeImpl::getUserData(const DOMString &key)
939     UserDataEntry *entry = userDataEntries;
940     while (entry)
941         {
942         if (entry->key == key)
943             return entry->data;
944         entry = entry->next;
945         }
946     return NULL;
951 //##################
952 //# Non-API methods
953 //##################
955 /**
956  *
957  */
958 void NodeImpl::setNodeName(const DOMString &qualifiedName)
960     nodeName  = qualifiedName;
961     prefix    = "";
962     localName = "";
963     for (unsigned int i=0 ; i<qualifiedName.size() ; i++)
964         {
965         int ch = qualifiedName[i];
966         if (ch == ':')
967             {
968             prefix    = localName;
969             localName = "";
970             }
971         else
972             {
973             localName.push_back((XMLCh)ch);
974             }
975         }
978 /**
979  *
980  */
981 void NodeImpl::setNamespaceURI(const DOMString &theNamespaceURI)
983     namespaceURI = theNamespaceURI;
987 /**
988  * From DOM3 Namespace algorithms
989  */
990 DOMString NodeImpl::lookupNamespacePrefix(const DOMString &theNamespaceURI,
991                                           NodePtr originalElement)
993     if (!originalElement)
994         return DOMString("");
996     if ( namespaceURI.size()>0 && namespaceURI==theNamespaceURI &&
997          prefix.size()>0 &&
998          originalElement->lookupNamespaceURI(prefix) == theNamespaceURI)
999         {
1000         return (prefix);
1001         }
1003     if ( hasAttributes() )
1004         {
1005         NamedNodeMap attributes = getAttributes();
1006         int nrAttrs = attributes.getLength();
1007         for (int i=0 ; i<nrAttrs ; i++)
1008             {
1009             NodePtr attr = attributes.item(i);
1010             DOMString attrLocalName = attr->getLocalName();
1011             if (attr->getPrefix()    == "xmlns" &&
1012                 attr->getNodeValue() == theNamespaceURI &&
1013                 originalElement->lookupNamespaceURI(attrLocalName)
1014                                      == theNamespaceURI)
1015                 {
1016                 return (attrLocalName);
1017                 }
1018             }
1019         }
1021     //Get ancestor element, if any
1022     NodeImplPtr ancestor = parent;
1023     while (ancestor.get() && ancestor->getNodeType()!= Node::ELEMENT_NODE)
1024         ancestor = ancestor->parent;
1026     if ( ancestor.get() )
1027         {
1028         return ancestor->lookupNamespacePrefix(theNamespaceURI, originalElement);
1029         }
1031     return DOMString("");
1035 /**
1036  *
1037  */
1038 NodeImpl::NodeImpl() : Node()
1040     init();
1044 /**
1045  *
1046  */
1047 NodeImpl::NodeImpl(const NodeImpl &other) : Node()
1049     init();
1050     assign(other);
1053 /**
1054  *
1055  */
1056 NodeImpl &NodeImpl::operator=(const NodeImpl &other)
1058     init();
1059     assign(other);
1060     return *this;
1064 /**
1065  *
1066  */
1067 NodeImpl::NodeImpl(DocumentImplPtr owner) : Node()
1069     init();
1070     ownerDocument = owner;
1073 /**
1074  *
1075  */
1076 NodeImpl::NodeImpl(DocumentImplPtr owner, const DOMString &nodeName)
1077                    : Node()
1079     init();
1080     ownerDocument = owner;
1081     setNodeName(nodeName);
1084 /**
1085  *
1086  */
1087 NodeImpl::NodeImpl(DocumentImplPtr owner, const DOMString &/*theNamespaceURI*/,
1088                    const DOMString &qualifiedName) : Node()
1090     init();
1091     ownerDocument = owner;
1092     //if (owner)
1093     //    namespaceURI  = owner->stringCache(theNamespaceURI);
1094     setNodeName(qualifiedName);
1099 /**
1100  *
1101  */
1102 void NodeImpl::init()
1104     nodeType        = 0; //none yet
1105     nodeValue       = "";
1106     setNodeName("");
1107     namespaceURI    = "";
1108     parent          = NULL;
1109     prev            = NULL;
1110     next            = NULL;
1111     userData        = NULL;
1112     firstChild      = NULL;
1113     lastChild       = NULL;
1114     ownerDocument   = NULL;
1115     userDataEntries = NULL;
1118 /**
1119  *
1120  */
1121 void NodeImpl::assign(const NodeImpl &other)
1123     ownerDocument = other.ownerDocument;
1124     prefix        = other.prefix;
1125     localName     = other.localName;
1126     nodeName      = other.nodeName;
1127     nodeValue     = other.nodeValue;
1128     namespaceURI  = other.namespaceURI;
1129     attributes    = other.attributes;
1133 /**
1134  *
1135  */
1136 NodeImpl::~NodeImpl()
1138     if (userDataEntries)
1139         delete userDataEntries;
1140     //Delete children
1141     /** Use smart pointers.  do not delete explicitly
1142         for (NodePtr n = getFirstChild() ; n.get() ;
1143                      n=n->getNextSibling() )
1144         delete n;
1145     */
1146     firstChild = lastChild = (NodeImpl *)0;
1151 /*#########################################################################
1152 ## CharacterDataImpl
1153 #########################################################################*/
1156 /**
1157  *
1158  */
1159 CharacterDataImpl::CharacterDataImpl() : NodeImpl()
1163 /**
1164  *
1165  */
1166 CharacterDataImpl::CharacterDataImpl(DocumentImplPtr owner,
1167                                      const DOMString &theValue) : NodeImpl()
1169     ownerDocument = owner;
1170     nodeValue     = theValue;
1173 /**
1174  *
1175  */
1176 CharacterDataImpl::~CharacterDataImpl()
1180 /**
1181  *
1182  */
1183 DOMString CharacterDataImpl::getData() throw(DOMException)
1185     return nodeValue;
1188 /**
1189  *
1190  */
1191 void CharacterDataImpl::setData(const DOMString& val) throw(DOMException)
1193     nodeValue = val;
1196 /**
1197  *
1198  */
1199 unsigned long CharacterDataImpl::getLength()
1201     return nodeValue.size();
1204 /**
1205  *
1206  */
1207 DOMString CharacterDataImpl::substringData(unsigned long offset,
1208                         unsigned long count)
1209                         throw(DOMException)
1211     return nodeValue.substr(offset, count);
1214 /**
1215  *
1216  */
1217 void CharacterDataImpl::appendData(const DOMString& arg) throw(DOMException)
1219     nodeValue += arg;
1222 /**
1223  *
1224  */
1225 void CharacterDataImpl::insertData(unsigned long offset,
1226                 const DOMString& arg)
1227                 throw(DOMException)
1229     nodeValue.insert(offset, arg);
1232 /**
1233  *
1234  */
1235 void CharacterDataImpl::deleteData(unsigned long offset,
1236                 unsigned long count)
1237                 throw(DOMException)
1239     nodeValue.erase(offset, count);
1242 /**
1243  *
1244  */
1245 void  CharacterDataImpl::replaceData(unsigned long offset,
1246                   unsigned long count,
1247                   const DOMString& arg)
1248                   throw(DOMException)
1250     nodeValue.replace(offset, count, arg);
1258 /*#########################################################################
1259 ## AttrImpl
1260 #########################################################################*/
1262 /**
1263  *
1264  */
1265 DOMString AttrImpl::getName()
1267     return nodeName;
1270 /**
1271  *
1272  */
1273 bool AttrImpl::getSpecified()
1275     return (nodeValue.size() > 0);
1278 /**
1279  *
1280  */
1281 DOMString AttrImpl::getValue()
1283     return nodeValue;
1286 /**
1287  *
1288  */
1289 void AttrImpl::setValue(const DOMString& val) throw(DOMException)
1291     nodeValue = val;
1294 /**
1295  *
1296  */
1297 ElementPtr AttrImpl::getOwnerElement()
1299     return ownerElement;
1303 /**
1304  *
1305  */
1306 TypeInfo &AttrImpl::getSchemaTypeInfo()
1308     return typeInfo;
1312 /**
1313  *
1314  */
1315 bool AttrImpl::getIsId()
1317     return (nodeName == "id");
1322 //##################
1323 //# Non-API methods
1324 //##################
1327 void AttrImpl::setOwnerElement(const ElementPtr elem)
1329     ownerElement = elem;
1332 /**
1333  *
1334  */
1335 AttrImpl::AttrImpl(DocumentImplPtr owner, const DOMString &theName)
1336                    : NodeImpl()
1338     nodeType     = ATTRIBUTE_NODE;
1339     ownerDocument = owner;
1340     setNodeName(theName);
1343 /**
1344  *
1345  */
1346 AttrImpl::AttrImpl(DocumentImplPtr owner,
1347                    const DOMString &/*theNamespaceURI*/,
1348                    const DOMString &theQualifiedName)
1349                    : NodeImpl()
1351     nodeType     = ATTRIBUTE_NODE;
1352     ownerDocument = owner;
1353     //if (owner)
1354     //    namespaceURI  = owner->stringCache(theNamespaceURI);
1355     setNodeName(theQualifiedName);
1358 /**
1359  *
1360  */
1361 AttrImpl::~AttrImpl()
1369 /*#########################################################################
1370 ## ElementImpl
1371 #########################################################################*/
1374 /**
1375  *
1376  */
1377 DOMString ElementImpl::getTagName()
1379     if (prefix.size() > 0)
1380         return prefix + ":" + nodeName;
1381     else
1382         return nodeName;
1385 /**
1386  *
1387  */
1388 DOMString ElementImpl::getAttribute(const DOMString& name)
1390     NodePtr node = attributes.getNamedItem(name);
1391     if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1392         return DOMString("");
1393     AttrPtr attr = dynamic_cast<Attr *>(node.get());
1394     return attr->getValue();
1397 /**
1398  *
1399  */
1400 void ElementImpl::setAttribute(const DOMString& name,
1401                   const DOMString& value)
1402                   throw(DOMException)
1404     AttrImplPtr attr = new AttrImpl(ownerDocument, name);
1405     attr->setValue(value);
1406     attr->setOwnerElement(this);
1407     attributes.setNamedItem(attr);
1410 /**
1411  *
1412  */
1413 void ElementImpl::removeAttribute(const DOMString& name)
1414                      throw(DOMException)
1416     attributes.removeNamedItem(name);
1419 /**
1420  *
1421  */
1422 AttrPtr ElementImpl::getAttributeNode(const DOMString& name)
1424     NodePtr node = attributes.getNamedItem(name);
1425     if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1426         return NULL;
1427     AttrPtr attr = dynamic_cast<Attr *>(node.get());
1428     return attr;
1431 /**
1432  *
1433  */
1434 AttrPtr ElementImpl::setAttributeNode(AttrPtr attr)
1435                       throw(DOMException)
1437     attributes.setNamedItem(attr);
1438     return attr;
1441 /**
1442  *
1443  */
1444 AttrPtr ElementImpl::removeAttributeNode(AttrPtr attr)
1445                          throw(DOMException)
1447     attributes.removeNamedItem(attr->getName());
1448     return attr;
1452 /**
1453  *
1454  */
1455 void ElementImpl::getElementsByTagNameRecursive(NodeList &list,
1456                         const DOMString& name, ElementPtr elem)
1458     if (!elem)
1459         return;
1461     if (name == elem->getTagName())
1462         list.add(elem);
1463     for (NodePtr node = elem->getFirstChild() ; node.get() ;
1464                        node=node->getNextSibling())
1465         {
1466         if (node->getNodeType() != Node::ELEMENT_NODE)
1467             continue;
1468         ElementPtr childElem = dynamic_cast<Element *>(node.get());
1469         getElementsByTagNameRecursive(list, name, childElem);
1470         }
1474 /**
1475  *
1476  */
1477 NodeList ElementImpl::getElementsByTagName(const DOMString& tagName)
1479     NodeList list;
1480     getElementsByTagNameRecursive(list, tagName, this);
1481     return list;
1484 /**
1485  *
1486  */
1487 DOMString ElementImpl::getAttributeNS(const DOMString& namespaceURI,
1488                          const DOMString& localName)
1490     NodePtr node = attributes.getNamedItemNS(namespaceURI, localName);
1491     if (!node || node->getNodeType()!=ATTRIBUTE_NODE)
1492         return DOMString("");
1493     AttrPtr attr = dynamic_cast<Attr *>(node.get());
1494     return attr->getValue();
1497 /**
1498  *
1499  */
1500 void ElementImpl::setAttributeNS(const DOMString& namespaceURI,
1501                     const DOMString& qualifiedName,
1502                     const DOMString& value)
1503                     throw(DOMException)
1505     AttrImplPtr attr = new AttrImpl(ownerDocument, namespaceURI, qualifiedName);
1506     attr->setValue(value);
1507     attr->setOwnerElement(this);
1508     attributes.setNamedItemNS(attr);
1511 /**
1512  *
1513  */
1514 void ElementImpl::removeAttributeNS(const DOMString& namespaceURI,
1515                        const DOMString& localName)
1516                        throw(DOMException)
1518     attributes.removeNamedItemNS(namespaceURI, localName);
1521 /**
1522  *
1523  */
1524  AttrPtr ElementImpl::getAttributeNodeNS(const DOMString& namespaceURI,
1525                         const DOMString& localName)
1527     NodePtr node = attributes.getNamedItemNS(namespaceURI, localName);
1528     if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1529         return (Attr *)0;
1530     AttrPtr attr = dynamic_cast<Attr *>(node.get());
1531     return attr;
1534 /**
1535  *
1536  */
1537 AttrPtr ElementImpl::setAttributeNodeNS(AttrPtr attr)
1538                         throw(DOMException)
1540     attributes.setNamedItemNS(attr);
1541     return attr;
1545 /**
1546  *
1547  */
1548 void ElementImpl::getElementsByTagNameNSRecursive(NodeList &list,
1549              const DOMString& namespaceURI,
1550                          const DOMString& tagName, ElementPtr elem)
1552     if (!elem)
1553         return;
1555     if (namespaceURI == elem->getNamespaceURI() && tagName == elem->getTagName())
1556         list.add(elem);
1557     for (NodePtr node = elem->getFirstChild() ; node.get() ; node=node->getNextSibling())
1558         {
1559         if (node->getNodeType() != Node::ELEMENT_NODE)
1560             continue;
1561         ElementPtr childElem = dynamic_cast<Element *>(node.get());
1562         getElementsByTagNameNSRecursive(list, namespaceURI, tagName, childElem);
1563         }
1566 /**
1567  *
1568  */
1569 NodeList ElementImpl::getElementsByTagNameNS(const DOMString& namespaceURI,
1570                                 const DOMString& localName)
1572     NodeList list;
1573     getElementsByTagNameNSRecursive(list, namespaceURI, localName, this);
1574     return list;
1577 /**
1578  *
1579  */
1580 bool ElementImpl::hasAttribute(const DOMString& attrName)
1582     NodePtr node = attributes.getNamedItem(attrName);
1583     if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1584         return false;
1585     return true;
1588 /**
1589  *
1590  */
1591 bool ElementImpl::hasAttributeNS(const DOMString& namespaceURI,
1592                     const DOMString& localName)
1594     NodePtr node = attributes.getNamedItemNS(namespaceURI, localName);
1595     if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1596         return false;
1597     return true;
1600 /**
1601  *
1602  */
1603 TypeInfo &ElementImpl::getSchemaTypeInfo()
1605     return typeInfo;
1609 /**
1610  *
1611  */
1612 void ElementImpl::setIdAttribute(const DOMString &/*name*/,
1613                             bool /*isId*/) throw (DOMException)
1615     //fixme
1618 /**
1619  *
1620  */
1621 void ElementImpl::setIdAttributeNS(const DOMString &/*namespaceURI*/,
1622                               const DOMString &/*localName*/,
1623                               bool /*isId*/) throw (DOMException)
1625     //fixme
1628 /**
1629  *
1630  */
1631 void ElementImpl::setIdAttributeNode(const AttrPtr /*idAttr*/,
1632                                 bool /*isId*/) throw (DOMException)
1634     //fixme
1638 //##################
1639 //# Non-API methods
1640 //##################
1643 /**
1644  *
1645  */
1646 ElementImpl::ElementImpl() : NodeImpl()
1648     nodeType = ELEMENT_NODE;
1651 /**
1652  *
1653  */
1654 ElementImpl::ElementImpl(DocumentImplPtr owner, const DOMString &tagName)
1655                                   : NodeImpl()
1657     nodeType = ELEMENT_NODE;
1658     ownerDocument = owner;
1659     setNodeName(tagName);
1662 /**
1663  *
1664  */
1665 ElementImpl::ElementImpl(DocumentImplPtr owner,
1666                          const DOMString &/*theNamespaceURI*/,
1667                          const DOMString &qualifiedName) :
1668                          NodeImpl()
1670     nodeType = ELEMENT_NODE;
1671     ownerDocument = owner;
1672     setNodeName(qualifiedName);
1675 /**
1676  *
1677  */
1678 ElementImpl::~ElementImpl()
1683 /**
1684  *
1685  */
1686 void ElementImpl::normalizeNamespaces()
1688     //printf("### NORMALIZE\n");
1690     NamedNodeMap attrs = getAttributes();
1692     //#######################################
1693     //# Pick up local namespace declarations
1694     //#######################################
1695     bindingsClear();  //Reset bindings on this node
1697     int nrAttrs = attrs.getLength();
1698     for (int i=0; i<nrAttrs ; i++)
1699         {
1700         NodePtr attrNode = attrs.item(i);
1701         if (attrNode->getNodeType() != Node::ATTRIBUTE_NODE)
1702             continue;
1703         AttrImplPtr attr = dynamic_cast<AttrImpl *>(attrNode.get());
1704         DOMString attrNS     = attr->getNamespaceURI();
1705         DOMString attrName   = attr->getLocalName();
1706         DOMString attrPrefix = attr->getPrefix();
1707         DOMString attrValue  = attr->getNodeValue();
1708         if (attrName != "xmlns" && attrPrefix != "xmlns")
1709             continue;
1711         //is the namespace declaration is invalid?
1712         if (attrValue == XMLNSNAME || attrName == attrPrefix)
1713             {
1714             // Note: The prefix xmlns is used only to declare namespace bindings and
1715             // is by definition bound to the namespace name http://www.w3.org/2000/xmlns/.
1716             // It must not be declared. No other prefix may be bound to this namespace name.
1718             //==> Report an error.
1719             printf("normalizeNamespaces() error: Namespace %s cannot be reassigned\n",
1720                         XMLNSNAME);
1722             }
1723         else
1724             {
1725             //==>  Record the namespace declaration
1726             attr->setNamespaceURI(XMLNSNAME);
1727             if (attrPrefix.size() > 0)
1728                 bindingsAdd(attrPrefix, attrValue);
1729             else
1730                 bindingsAdd("*", attrValue);//default
1732             }
1733         }
1736     //#######################################
1737     //# Fixup element's namespace
1738     //#######################################
1739     if ( namespaceURI.size() > 0 )
1740         {
1741         DOMString key = prefix;
1742         if (key.size() == 0)
1743             key = "*";
1744         DOMString binding = bindingsFind(key);
1745         //Element's prefix/namespace pair (or default namespace, if no prefix)
1746         // are within the scope of a binding
1747         if ( binding == namespaceURI )
1748             {
1749             //==> do nothing, declaration in scope is inherited
1751             // See section "B.1.1: Scope of a binding" for an example
1753             }
1754         else
1755             {
1757             /*
1758             ==> Create a local namespace declaration attr for this namespace,
1759             with Element's current prefix (or a default namespace, if
1760             no prefix). If there's a conflicting local declaration
1761             already present, change its value to use this namespace.
1763             See section "B.1.2: Conflicting namespace declaration" for an example
1764             */
1765             DOMString attrName = "xmlns";
1766             if (prefix.size() > 0)
1767                 {
1768                 attrName.append(":");
1769                 attrName.append(prefix);
1770                 }
1771             setAttribute(attrName, namespaceURI);
1772             // NOTE that this may break other nodes within this Element's
1773             // subtree, if they're already using this prefix.
1774             // They will be repaired when we reach them.
1775             }
1776         }
1777     else  // Element has no namespace URI:
1778         {
1779         //###############################################
1780         //# Bob -- alter this from the specs a bit.
1781         //#  Since the XmlReader does not set namespaces,
1782         //#    do it here
1783         //###############################################
1784         DOMString localName = getLocalName();
1785         if ( localName.size()==0 )
1786             {
1787             // DOM Level 1 node
1788             /*
1789             ==> if in process of validation against a namespace aware schema
1790             (i.e XML Schema) report a fatal error: the processor can not recover
1791             in this situation.
1792             Otherwise, report an error: no namespace fixup will be performed on this node.
1793             */
1794             printf("normalizeNamespaces() error: no localName\n");
1795             }
1796         else
1797             {
1798             // Element has no pseudo-prefix
1799             //there's a conflicting local default namespace declaration already present
1800             if ( prefix.size()==0 )
1801                 {
1802                 //==> change its value to use this empty namespace.
1803                 namespaceURI = bindingsFind("*");
1804                 //setAttribute("xmlns", "");
1805                 }
1806             else  //#BOB .   I added this.
1807                 {
1808                 namespaceURI = bindingsFind(prefix);
1809                 }
1810             // NOTE that this may break other nodes within this Element's
1811             // subtree, if they're already using the default namespaces.
1812             // They will be repaired when we reach them.
1813             }
1814         }
1817     //#######################################
1818     //# Examine and polish the attributes
1819     //#######################################
1820     nrAttrs = attrs.getLength();
1821     for (int i=0; i<nrAttrs ; i++)// all non-namespace Attrs of Element
1822         {
1823         NodePtr attrNode = attrs.item(i);
1824         if (attrNode->getNodeType() != Node::ATTRIBUTE_NODE)
1825             continue;
1826         AttrPtr attr = dynamic_cast<Attr *>(attrNode.get());
1827         DOMString attrNS     = attr->getNamespaceURI();
1828         DOMString attrPrefix = attr->getPrefix();
1829         DOMString attrValue  = attr->getNodeValue();
1830         if (attrNS == XMLNSNAME)
1831             continue;
1833         if ( attrNS.size()>0 ) //Attr[i] has a namespace URI
1834             {
1835             DOMString attrBinding = bindingsFind(attrPrefix);
1836             /*
1837              if attribute has no prefix (default namespace decl does not apply to attributes)
1838              OR
1839              attribute prefix is not declared
1840              OR
1841              conflict: attribute has a prefix that conflicts with a binding
1842                        already active in scope
1843             */
1844             if ( attrPrefix.size() == 0 || attrBinding.size() == 0)
1845                 {
1846                 //namespaceURI matches an in scope declaration of one or more prefixes)
1847                 DOMString prefixForNS = lookupNamespacePrefix(attrNS, this);
1848                 if ( prefixForNS.size() > 0 )
1849                     {
1850                     // pick the most local binding available;
1851                     // if there is more than one pick one arbitrarily
1853                     //==> change attribute's prefix.
1854                     attr->setPrefix(prefixForNS);
1855                     }
1856                 else
1857                     {
1858                     // the current prefix is not null and it has no in scope declaration)
1859                     if ( attrPrefix.size() > 0 || attrBinding.size() == 0 )
1860                         {
1861                         //==> declare this prefix
1862                         DOMString newAttrName = "xmlns:";
1863                         newAttrName.append(attrPrefix);
1864                         setAttribute(newAttrName, attrNS);
1865                         bindingsAdd(attrPrefix, attrNS);
1866                         }
1867                     else
1868                         {
1869                         // find a prefix following the pattern "NS" +index (starting at 1)
1870                         // make sure this prefix is not declared in the current scope.
1871                         // create a local namespace declaration attribute
1873                         //==> declare this prefix
1874                         char buf[16];
1875                         sprintf(buf, "%d" , ownerDocument->namespaceIndex++);
1876                         DOMString newPrefix = "NS";
1877                         newPrefix.append(buf);
1878                         DOMString newAttrName = "xmlns:";
1879                         newAttrName.append(newPrefix);
1880                         setAttribute(newAttrName, attrNS);
1881                         bindingsAdd(newPrefix, attrNS);
1882                         //==> change attribute's prefix.
1883                         }
1884                     }
1885                 }
1886             }
1887         else  // Attr has no namespace URI
1888             {
1889             // Attr has no localName
1890             if ( attr->getLocalName().size() == 0 )
1891                 {
1892                 // DOM Level 1 node
1893                 /*
1894                 ==> if in process of validation against a namespace aware schema
1895                 (i.e XML Schema) report a fatal error: the processor can not recover
1896                 in this situation.
1897                 Otherwise, report an error: no namespace fixup will be performed on this node.
1898                 */
1899                 printf("normalizeNamespaces:  no local name for attribute\n");
1900                 }
1901             else
1902                 {
1903                 // attr has no namespace URI and no prefix
1904                 // no action is required, since attrs don't use default
1905                 //==> do nothing
1906                 }
1907             }
1908         } // end for-all-Attrs
1911     //#######################################
1912     //# Recursively normalize children
1913     //#######################################
1914     for (NodePtr child=getFirstChild() ; child.get() ; child=child->getNextSibling())
1915         {
1916         if (child->getNodeType() != Node::ELEMENT_NODE)
1917             continue;
1918         ElementImplPtr childElement = dynamic_cast<ElementImpl *>(child.get());
1919         childElement->normalizeNamespaces();
1920         }
1925 /*#########################################################################
1926 ## TextImpl
1927 #########################################################################*/
1930 /**
1931  *
1932  */
1933 TextImpl::TextImpl() : CharacterDataImpl()
1935     nodeType = TEXT_NODE;
1936     nodeName = "#text";
1940 /**
1941  *
1942  */
1943 TextImpl::TextImpl(DocumentImplPtr owner, const DOMString &value)
1944                                : CharacterDataImpl()
1946     nodeType      = TEXT_NODE;
1947     nodeName      = "#text";
1948     ownerDocument = owner;
1949     nodeValue     = value;
1953 /**
1954  *
1955  */
1956 TextImpl::~TextImpl()
1960 /**
1961  *
1962  */
1963 TextPtr TextImpl::splitText(unsigned long /*offset*/)
1964                 throw(DOMException)
1966     return NULL;
1969 /**
1970  *
1971  */
1972 bool TextImpl::getIsElementContentWhitespace()
1974     return false;
1977 /**
1978  *
1979  */
1980 DOMString TextImpl::getWholeText()
1982     return nodeValue;
1986 /**
1987  *
1988  */
1989 TextPtr TextImpl::replaceWholeText(const DOMString &/*content*/)
1990                              throw(DOMException)
1992     return NULL;
1996 /*#########################################################################
1997 ## CommentImpl
1998 #########################################################################*/
2000 /**
2001  *
2002  */
2003 CommentImpl::CommentImpl() : CharacterDataImpl()
2005     nodeType = COMMENT_NODE;
2006     nodeName = "#comment";
2010 /**
2011  *
2012  */
2013 CommentImpl::CommentImpl(DocumentImplPtr owner, const DOMString &value)
2014                        : CharacterDataImpl()
2016     nodeType      = COMMENT_NODE;
2017     nodeName      = "#comment";
2018     ownerDocument = owner;
2019     nodeValue     = value;
2023 /**
2024  *
2025  */
2026 CommentImpl::~CommentImpl()
2036 /*#########################################################################
2037 ## UserDataHandlerImpl
2038 #########################################################################*/
2042 /**
2043  *
2044  */
2045 UserDataHandlerImpl::UserDataHandlerImpl()
2050 /**
2051  *
2052  */
2053 UserDataHandlerImpl::~UserDataHandlerImpl()
2057 /**
2058  *
2059  */
2060 void UserDataHandlerImpl::handle(unsigned short /*operation*/,
2061                      const DOMString &/*key*/,
2062                      const DOMUserData */*data*/,
2063                      const NodePtr /*src*/,
2064                      const NodePtr /*dst*/)
2066     //do nothing.  do we need anything here?
2071 /*#########################################################################
2072 ## DOMErrorImpl
2073 #########################################################################*/
2077 /**
2078  *
2079  */
2080 DOMErrorImpl::DOMErrorImpl()
2085 /**
2086  *
2087  */
2088 DOMErrorImpl::~DOMErrorImpl()
2092 /**
2093  *
2094  */
2095 unsigned short DOMErrorImpl::getSeverity()
2097     return severity;
2100 /**
2101  *
2102  */
2103 DOMString DOMErrorImpl::getMessage()
2105     return message;
2108 /**
2109  *
2110  */
2111 DOMString DOMErrorImpl::getType()
2113     return type;
2116 /**
2117  *
2118  */
2119 DOMObject *DOMErrorImpl::getRelatedException()
2121     return NULL;
2124 /**
2125  *
2126  */
2127 DOMObject *DOMErrorImpl::getRelatedData()
2129     return NULL;
2132 /**
2133  *
2134  */
2135 DOMLocator *DOMErrorImpl::getLocation()
2137     //really should fill this in
2138     return NULL;
2144 /*#########################################################################
2145 ## DOMErrorHandlerImpl
2146 #########################################################################*/
2150 /**
2151  *
2152  */
2153 DOMErrorHandlerImpl::DOMErrorHandlerImpl()
2158 /**
2159  *
2160  */
2161 DOMErrorHandlerImpl::~DOMErrorHandlerImpl()
2165 /**
2166  *
2167  */
2168 bool DOMErrorHandlerImpl::handleError(const DOMError *error)
2170     if (!error)
2171         return false;
2172     return true;
2178 /*#########################################################################
2179 ## DOMLocatorImpl
2180 #########################################################################*/
2183 /**
2184  *
2185  */
2186 DOMLocatorImpl::DOMLocatorImpl()
2191 /**
2192  *
2193  */
2194 DOMLocatorImpl::~DOMLocatorImpl()
2199 /**
2200  *
2201  */
2202 long DOMLocatorImpl::getLineNumber()
2204     return lineNumber;
2207 /**
2208  *
2209  */
2210 long DOMLocatorImpl::getColumnNumber()
2212     return columnNumber;
2215 /**
2216  *
2217  */
2218 long DOMLocatorImpl::getByteOffset()
2220     return byteOffset;
2223 /**
2224  *
2225  */
2226 long DOMLocatorImpl::getUtf16Offset()
2228     return utf16Offset;
2232 /**
2233  *
2234  */
2235 NodePtr DOMLocatorImpl::getRelatedNode()
2237     return relatedNode;
2241 /**
2242  *
2243  */
2244 DOMString DOMLocatorImpl::getUri()
2246     return uri;
2251 /*#########################################################################
2252 ## DOMConfigurationImpl
2253 #########################################################################*/
2256 /**
2257  *
2258  */
2259 DOMConfigurationImpl::DOMConfigurationImpl()
2264 /**
2265  *
2266  */
2267 DOMConfigurationImpl::~DOMConfigurationImpl()
2271 /**
2272  *
2273  */
2274 void DOMConfigurationImpl::setParameter(const DOMString &/*name*/,
2275                           const DOMUserData */*value*/) throw (DOMException)
2279 /**
2280  *
2281  */
2282 DOMUserData *DOMConfigurationImpl::getParameter(const DOMString &/*name*/)
2283                                   throw (DOMException)
2285     return NULL;
2288 /**
2289  *
2290  */
2291 bool DOMConfigurationImpl::canSetParameter(const DOMString &/*name*/,
2292                              const DOMUserData */*data*/)
2294     return false;
2297 /**
2298  *
2299  */
2300 DOMStringList *DOMConfigurationImpl::getParameterNames()
2302     return NULL;
2307 /*#########################################################################
2308 ## CDATASectionImpl
2309 #########################################################################*/
2311 /**
2312  *
2313  */
2314 CDATASectionImpl::CDATASectionImpl() : TextImpl()
2316     nodeType = CDATA_SECTION_NODE;
2317     nodeName = "#cdata-section";
2320 /**
2321  *
2322  */
2323 CDATASectionImpl::CDATASectionImpl(DocumentImplPtr owner, const DOMString &theValue)
2324                                  : TextImpl()
2326     nodeType      = CDATA_SECTION_NODE;
2327     nodeName      = "#cdata-section";
2328     ownerDocument = owner;
2329     nodeValue     = theValue;
2333 /**
2334  *
2335  */
2336 CDATASectionImpl::~CDATASectionImpl()
2344 /*#########################################################################
2345 ## DocumentTypeImpl
2346 #########################################################################*/
2348 /**
2349  *
2350  */
2351 DocumentTypeImpl::DocumentTypeImpl(const DOMString& theName,
2352                                    const DOMString& thePublicId,
2353                                    const DOMString& theSystemId)
2354                                   : NodeImpl()
2356     nodeType = DOCUMENT_TYPE_NODE;
2357     nodeName = theName;
2358     publicId = thePublicId;
2359     systemId = theSystemId;
2362 /**
2363  *
2364  */
2365 DocumentTypeImpl::~DocumentTypeImpl()
2369 /**
2370  *
2371  */
2372 DOMString DocumentTypeImpl::getName()
2374     return nodeName;
2377 /**
2378  *
2379  */
2380 NamedNodeMap DocumentTypeImpl::getEntities()
2382     return entities;
2385 /**
2386  *
2387  */
2388 NamedNodeMap DocumentTypeImpl::getNotations()
2390     return notations;
2393 /**
2394  *
2395  */
2396 DOMString DocumentTypeImpl::getPublicId()
2398     return publicId;
2401 /**
2402  *
2403  */
2404 DOMString DocumentTypeImpl::getSystemId()
2406     return systemId;
2409 /**
2410  *
2411  */
2412 DOMString DocumentTypeImpl::getInternalSubset()
2414     return DOMString("");
2422 /*#########################################################################
2423 ## NotationImpl
2424 #########################################################################*/
2428 /**
2429  *
2430  */
2431 NotationImpl::NotationImpl(DocumentImplPtr owner) : NodeImpl()
2433     nodeType = NOTATION_NODE;
2434     ownerDocument = owner;
2438 /**
2439  *
2440  */
2441 NotationImpl::~NotationImpl()
2445 /**
2446  *
2447  */
2448 DOMString NotationImpl::getPublicId()
2450     return publicId;
2453 /**
2454  *
2455  */
2456 DOMString NotationImpl::getSystemId()
2458     return systemId;
2468 /*#########################################################################
2469 ## EntityImpl
2470 #########################################################################*/
2473 /**
2474  *
2475  */
2476 EntityImpl::EntityImpl() : NodeImpl()
2478     nodeType = ENTITY_NODE;
2482 /**
2483  *
2484  */
2485 EntityImpl::EntityImpl(DocumentImplPtr owner) : NodeImpl()
2487     nodeType = ENTITY_NODE;
2488     ownerDocument = owner;
2492 /**
2493  *
2494  */
2495 EntityImpl::~EntityImpl()
2499 /**
2500  *
2501  */
2502 DOMString EntityImpl::getPublicId()
2504     return publicId;
2507 /**
2508  *
2509  */
2510 DOMString EntityImpl::getSystemId()
2512     return systemId;
2515 /**
2516  *
2517  */
2518 DOMString EntityImpl::getNotationName()
2520     return notationName;
2523 /**
2524  *
2525  */
2526 DOMString EntityImpl::getInputEncoding()
2528     return inputEncoding;
2531 /**
2532  *
2533  */
2534 DOMString EntityImpl::getXmlEncoding()
2536     return xmlEncoding;
2539 /**
2540  *
2541  */
2542 DOMString EntityImpl::getXmlVersion()
2544     return xmlVersion;
2552 /*#########################################################################
2553 ## EntityReferenceImpl
2554 #########################################################################*/
2558 /**
2559  *
2560  */
2561 EntityReferenceImpl::EntityReferenceImpl() : NodeImpl()
2563     nodeType = ENTITY_REFERENCE_NODE;
2567 /**
2568  *
2569  */
2570 EntityReferenceImpl::EntityReferenceImpl(DocumentImplPtr owner,
2571                                          const DOMString &theName)
2572                                          : NodeImpl()
2574     nodeType = ENTITY_REFERENCE_NODE;
2575     nodeName = theName;
2576     ownerDocument = owner;
2580 /**
2581  *
2582  */
2583 EntityReferenceImpl::~EntityReferenceImpl()
2589 /*#########################################################################
2590 ## ProcessingInstructionImpl
2591 #########################################################################*/
2596 /**
2597  *
2598  */
2599 ProcessingInstructionImpl::ProcessingInstructionImpl(): NodeImpl()
2601     nodeType = PROCESSING_INSTRUCTION_NODE;
2606 /**
2607  *
2608  */
2609 ProcessingInstructionImpl::ProcessingInstructionImpl(DocumentImplPtr owner,
2610                                                      const DOMString &target,
2611                                                      const DOMString &data)
2612                                                      : NodeImpl()
2614     nodeType      = PROCESSING_INSTRUCTION_NODE;
2615     ownerDocument = owner;
2616     nodeName      = target;
2617     nodeValue     = data;
2621 /**
2622  *
2623  */
2624 ProcessingInstructionImpl::~ProcessingInstructionImpl()
2631 /**
2632  *
2633  */
2634 DOMString ProcessingInstructionImpl::getTarget()
2636     return nodeName;
2639 /**
2640  *
2641  */
2642 DOMString ProcessingInstructionImpl::getData()
2644     return nodeValue;
2647 /**
2648  *
2649  */
2650 void ProcessingInstructionImpl::setData(const DOMString& /*val*/) throw(DOMException)
2652      //do something here
2661 /*#########################################################################
2662 ## DocumentFragmentImpl
2663 #########################################################################*/
2665 /**
2666  *
2667  */
2668 DocumentFragmentImpl::DocumentFragmentImpl() : NodeImpl()
2670     nodeType = DOCUMENT_FRAGMENT_NODE;
2671     nodeName = "#document-fragment";
2675 /**
2676  *
2677  */
2678 DocumentFragmentImpl::DocumentFragmentImpl(DocumentImplPtr owner) : NodeImpl()
2680     nodeType = DOCUMENT_FRAGMENT_NODE;
2681     nodeName = "#document-fragment";
2682     ownerDocument = owner;
2686 /**
2687  *
2688  */
2689 DocumentFragmentImpl::~DocumentFragmentImpl()
2698 /*#########################################################################
2699 ## DocumentImpl
2700 #########################################################################*/
2704 /**
2705  *
2706  */
2707 DocumentTypePtr DocumentImpl::getDoctype()
2709     return doctype;
2712 /**
2713  *
2714  */
2715 DOMImplementation *DocumentImpl::getImplementation()
2717     return parent;
2720 /**
2721  *
2722  */
2723 ElementPtr DocumentImpl::getDocumentElement()
2725     return documentElement;
2728 /**
2729  *
2730  */
2731 ElementPtr DocumentImpl::createElement(const DOMString& tagName)
2732                        throw(DOMException)
2734     ElementPtr elem = new ElementImpl(this, tagName);
2735     return elem;
2738 /**
2739  *
2740  */
2741 DocumentFragmentPtr DocumentImpl::createDocumentFragment()
2743     DocumentFragmentPtr frag = new DocumentFragmentImpl(this);
2744     return frag;
2747 /**
2748  *
2749  */
2750 TextPtr DocumentImpl::createTextNode(const DOMString& data)
2752     TextPtr text = new TextImpl(this, data);
2753     return text;
2756 /**
2757  *
2758  */
2759 CommentPtr DocumentImpl::createComment(const DOMString& data)
2761     CommentPtr comment = new CommentImpl(this, data);
2762     return comment;
2765 /**
2766  *
2767  */
2768 CDATASectionPtr DocumentImpl::createCDATASection(const DOMString& data)
2769                                  throw(DOMException)
2771     CDATASectionPtr cdata = new CDATASectionImpl(this, data);
2772     return cdata;
2775 /**
2776  *
2777  */
2778 ProcessingInstructionPtr 
2779 DocumentImpl::createProcessingInstruction(const DOMString& target,
2780                                           const DOMString& data)
2781                                           throw(DOMException)
2783     ProcessingInstructionPtr pi =
2784         new ProcessingInstructionImpl(this, target, data);
2785     return pi;
2788 /**
2789  *
2790  */
2791 AttrPtr DocumentImpl::createAttribute(const DOMString& attrName)
2792                       throw(DOMException)
2794     AttrPtr attr = new AttrImpl(this, attrName);
2795     return attr;
2798 /**
2799  *
2800  */
2801 EntityReferencePtr DocumentImpl::createEntityReference(const DOMString& erName)
2802                                        throw(DOMException)
2804     EntityReferencePtr ref = new EntityReferenceImpl(this, erName);
2805     return ref;
2809 /**
2810  *
2811  */
2812 NodeList DocumentImpl::getElementsByTagName(const DOMString& tagname)
2814     NodeList list;
2815     ElementImpl::getElementsByTagNameRecursive(list,
2816                      tagname, documentElement);
2817     return list;
2821 /**
2822  *
2823  */
2824 NodePtr DocumentImpl::importNode(const NodePtr /*importedNode*/,
2825                  bool /*deep*/)
2826                  throw(DOMException)
2828     return NULL;
2831 /**
2832  *
2833  */
2834 ElementPtr DocumentImpl::createElementNS(const DOMString& namespaceURI,
2835                          const DOMString& qualifiedName)
2836                          throw(DOMException)
2838     ElementPtr elem = new ElementImpl(this, namespaceURI, qualifiedName);
2839     return elem;
2842 /**
2843  *
2844  */
2845 AttrPtr DocumentImpl::createAttributeNS(const DOMString& namespaceURI,
2846                         const DOMString& qualifiedName)
2847                         throw(DOMException)
2849     AttrPtr attr = new AttrImpl(this, namespaceURI, qualifiedName);
2850     return attr;
2854 /**
2855  *
2856  */
2857 NodeList DocumentImpl::getElementsByTagNameNS(const DOMString& namespaceURI,
2858                                  const DOMString& localName)
2860     NodeList list;
2861     ElementImpl::getElementsByTagNameNSRecursive(list, namespaceURI,
2862                           localName, documentElement);
2863     return list;
2866 /**
2867  *
2868  */
2869 ElementPtr DocumentImpl::getElementById(const DOMString& elementId)
2871     for (NamedElementItem *entry = elementsById.next; entry ; entry=entry->next)
2872         if (entry->name == elementId)
2873             return entry->elem;
2874     return NULL;
2878 /**
2879  *
2880  */
2881 DOMString DocumentImpl::getInputEncoding()
2883     return inputEncoding;
2887 /**
2888  *
2889  */
2890 DOMString DocumentImpl::getXmlEncoding()
2892     return xmlEncoding;
2895 /**
2896  *
2897  */
2898 bool DocumentImpl::getXmlStandalone()
2900     return xmlStandalone;
2903 /**
2904  *
2905  */
2906 void DocumentImpl::setXmlStandalone(bool val) throw (DOMException)
2908     xmlStandalone = val;
2911 /**
2912  *
2913  */
2914 DOMString DocumentImpl::getXmlVersion()
2916     return xmlVersion;
2919 /**
2920  *
2921  */
2922 void DocumentImpl::setXmlVersion(const DOMString &version) throw (DOMException)
2924     xmlVersion = version;
2927 /**
2928  *
2929  */
2930 bool DocumentImpl::getStrictErrorChecking()
2932     return strictErrorChecking;
2935 /**
2936  *
2937  */
2938 void DocumentImpl::setStrictErrorChecking(bool val)
2940     strictErrorChecking = val;
2944 /**
2945  *
2946  */
2947 DOMString DocumentImpl::getDocumentURI()
2949     return documentURI;
2952 /**
2953  *
2954  */
2955 void DocumentImpl::setDocumentURI(const DOMString &/*uri*/)
2957     //documentURI = stringCache(uri);
2960 /**
2961  *
2962  */
2963 NodePtr DocumentImpl::adoptNode(const NodePtr source) throw (DOMException)
2965     return (NodePtr )source;
2968 /**
2969  *
2970  */
2971 DOMConfiguration *DocumentImpl::getDomConfig()
2973     return domConfig;
2976 /**
2977  *
2978  */
2979 void DocumentImpl::normalizeDocument()
2981     //i assume that this means adjusting namespaces & prefixes
2982     if (documentElement.get())
2983         documentElement->normalizeNamespaces();
2986 /**
2987  *
2988  */
2989 NodePtr DocumentImpl::renameNode(const NodePtr node,
2990                                const DOMString &/*namespaceURI*/,
2991                                const DOMString &qualifiedName)
2992                                throw (DOMException)
2994     NodeImplPtr nodeImpl = dynamic_cast<NodeImpl *> (node.get());
2995     nodeImpl->setNodeName(qualifiedName);
2996     return node;
3001 //##################
3002 //# Non-API methods
3003 //##################
3005 /**
3006  *
3007  */
3008 DocumentImpl::DocumentImpl(const DOMImplementation *domImpl,
3009                  const DOMString &/*theNamespaceURI*/,
3010                  const DOMString &theQualifiedName,
3011                  const DocumentTypePtr theDoctype) : NodeImpl()
3013     nodeType        = DOCUMENT_NODE;
3014     nodeName        = "#document";
3015     parent          = (DOMImplementation *)domImpl;
3016     //documentURI     = stringCache(theNamespaceURI);
3017     qualifiedName   = theQualifiedName;
3018     if (theDoctype.get()) //only assign if not null.
3019         doctype     = theDoctype;
3020     else
3021         doctype     = new DocumentTypeImpl("", "", "");
3022     documentElement = new ElementImpl(this, "root");
3023     namespaceIndex  = 0;
3027 /**
3028  *
3029  */
3030 DocumentImpl::~DocumentImpl()
3032     documentElement = NULL;
3046 }  //namespace dom
3047 }  //namespace w3c
3048 }  //namespace org
3052 /*#########################################################################
3053 ## E N D    O F    F I L E
3054 #########################################################################*/