Code

More binding progress. Fix Node::textContent and child manipulation.
[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 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 DocumentType *DOMImplementationImpl::createDocumentType(const DOMString& qualifiedName,
138                                  const DOMString& publicId,
139                                  const DOMString& systemId)
140                                  throw(DOMException)
142     DocumentTypeImpl *typeImpl = new DocumentTypeImpl(qualifiedName,
143                                          publicId, systemId);
144     return typeImpl;
147 /**
148  *
149  */
150 Document *DOMImplementationImpl::createDocument(
151                          const DOMString& namespaceURI,
152                          const DOMString& qualifiedName,
153                          DocumentType *doctype)
154                          throw(DOMException)
156     DocumentImpl *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 Node *getAncestorElement(Node *node)
187     if (!node)
188         return NULL;
189     node = node->getParentNode();
190     //Either quit because I am an element, or because I am null
191     while (node)
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 Node *NodeImpl::getParentNode()
237     return parent;
240 /**
241  *
242  */
243 NodeList NodeImpl::getChildNodes()
245     NodeList list;
246     for (NodeImpl *node = firstChild ; node ; node=node->next)
247         list.add(node);
248     return list;
251 /**
252  *
253  */
254 Node *NodeImpl::getFirstChild()
256     return firstChild;
259 /**
260  *
261  */
262 Node *NodeImpl::getLastChild()
264     return lastChild;
267 /**
268  *
269  */
270 Node *NodeImpl::getPreviousSibling()
272     return prev;
275 /**
276  *
277  */
278 Node *NodeImpl::getNextSibling()
280     return next;
283 /**
284  *
285  */
286 NamedNodeMap &NodeImpl::getAttributes()
288     NamedNodeMap &attrs = attributes;
289     return attrs;
293 /**
294  *
295  */
296 Document *NodeImpl::getOwnerDocument()
298     return ownerDocument;
301 /**
302  *
303  */
304 Node *NodeImpl::insertBefore(const Node *newChild,
305                    const Node *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     NodeImpl *newChildImpl = dynamic_cast<NodeImpl *>((Node *)newChild);
316     for (NodeImpl *n = firstChild ; n ; n=n->next)
317         {
318         if (n == refChild)
319             {
320             //link to new
321             if (n->prev)
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 Node *NodeImpl::replaceChild(const Node *newChild,
342                    const Node *oldChild)
343                    throw(DOMException)
345     if (!oldChild)
346         return NULL;
348     NodeImpl *newChildImpl = dynamic_cast<NodeImpl *>((Node *)newChild);
349     for (NodeImpl *n = firstChild ; n ; n=n->next)
350         {
351         if (n == oldChild)
352             {
353             //link to new
354             if (n->prev)
355                 n->prev->next = newChildImpl;
356             else
357                 firstChild = newChildImpl;
358             if (n->next)
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 Node *NodeImpl::removeChild(const Node *oldChild)
378                   throw(DOMException)
380     if (!oldChild)
381         return NULL;
383     for (NodeImpl *n = firstChild ; n ; n=n->next)
384         {
385         if (n == oldChild)
386             {
387             if (n->prev)
388                 n->prev->next = n->next;
389             if (n->next)
390                 n->next->prev = n->prev;
391             return n;
392             }
393         }
394     return NULL;
397 /**
398  *
399  */
400 Node *NodeImpl::appendChild(const Node *newChild)
401                   throw(DOMException)
403     if (!newChild)
404         return NULL;
406     NodeImpl *newChildImpl =
407              dynamic_cast<NodeImpl *> ((Node *)newChild);
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 (Node *)newChild;
429 /**
430  *
431  */
432 bool NodeImpl::hasChildNodes()
434     return (firstChild != NULL);
437 /**
438  *
439  */
440 Node *NodeImpl::cloneNode(bool deep)
442     NodeImpl *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 (NodeImpl *child = firstChild ; child ; 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     NodeImpl *next = NULL;
473     for (NodeImpl *child = firstChild ; child ; child=next)
474         {
475         if (child->getNodeType() != Node::TEXT_NODE)
476             continue;
477         next = NULL;
478         DOMString sval = child->getNodeValue();
479         for (NodeImpl *sibling = child->next ; sibling ; 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)
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 (NodeImpl *child = firstChild ; child ; 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)
505                 child->prev->next = child->next;
506             if (child->next)
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 Node *otherArg)
581     if (!otherArg || this == otherArg)
582         return 0;//no flags
584     Node *node;
585     Node *other = (Node *)otherArg;
587     //Look above me
588     for (node=getParentNode() ; node ; 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 ; node=node->getParentNode())
594         if (node == 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 (Node *n = getFirstChild() ; n ;
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         for (Node *n = getFirstChild() ; n ;
638                      n=n->getNextSibling() )
639         delete n;
640     firstChild = lastChild = NULL;
642     //Replace with a single text node
643     NodeImpl *tnode = new NodeImpl(ownerDocument);
644     tnode->nodeType = Node::TEXT_NODE;
645     tnode->setNodeValue(val);
646     appendChild(tnode);
650 /**
651  * From DOM3 Namespace algorithms
652  */
653 DOMString NodeImpl::lookupPrefix(const DOMString &theNamespaceURI)
656     if (theNamespaceURI.size()==0)
657         {
658         return DOMString("");
659         }
661     switch (nodeType)
662         {
663         case Node::ELEMENT_NODE:
664             {
665             ElementImpl *elem = (ElementImpl *)this;
666             return lookupNamespacePrefix(theNamespaceURI, elem);
667             }
668         case Node::DOCUMENT_NODE:
669             {
670             Document *doc = (Document *)this;
671             Element *elem = doc->getDocumentElement();
672             return elem->lookupPrefix(theNamespaceURI);
673             }
674         case Node::ENTITY_NODE :
675         case Node::NOTATION_NODE:
676         case Node::DOCUMENT_FRAGMENT_NODE:
677         case Node::DOCUMENT_TYPE_NODE:
678             return DOMString("");  // type is unknown
679         case Node::ATTRIBUTE_NODE:
680             {
681             Attr *attr = (Attr *)this;
682             Element *elem = (Element *)attr->getOwnerElement();
683             if ( elem )
684                 {
685                 return elem->lookupPrefix(theNamespaceURI);
686                 }
687              return DOMString("");
688             }
689         default:
690             {
691             //Get ancestor element, if any
692             if ( Node *ancestor = getAncestorElement(this) )
693                {
694                return ancestor->lookupPrefix(theNamespaceURI);
695                }
696             return DOMString("");
697             }
698         }//switch
699     return DOMString("");
703 /**
704  *
705  */
706 bool NodeImpl::isDefaultNamespace(const DOMString &theNamespaceURI)
708     switch (nodeType)
709         {
710         case ELEMENT_NODE:
711             if ( namespaceURI.size()>0 && prefix.size()==0 )
712                 {
713                 return (namespaceURI == theNamespaceURI);
714                 }
715             if ( Node *attr = attributes.getNamedItem("xmlns"))
716                 {
717                 return (attr->getNodeValue() == theNamespaceURI);
718                 }
721             if ( Node *ancestor = getAncestorElement(this) )
722                 {
723                 return ancestor->isDefaultNamespace(theNamespaceURI);
724                 }
725             else
726                 {
727                 return false;
728                 }
729         case DOCUMENT_NODE:
730             { //just use braces for local declaration
731             Document *doc = (Document *)this;
732             Element *elem = doc->getDocumentElement();
733             return elem->isDefaultNamespace(theNamespaceURI);
734             }
735         case ENTITY_NODE:
736         case NOTATION_NODE:
737         case DOCUMENT_TYPE_NODE:
738         case DOCUMENT_FRAGMENT_NODE:
739             return false;
740         case ATTRIBUTE_NODE:
741            {//braces only for scope
742            Attr *attr = (Attr *)this;
743            Element *ownerElement = attr->getOwnerElement();
744            if ( ownerElement )
745                 {
746                 return ownerElement->isDefaultNamespace(theNamespaceURI);
747                 }
748            else
749                 {
750                 return false;
751                 }
752            }
753         default:
754             if ( Node *ancestor = getAncestorElement(this) )
755                 {
756                 return ancestor->isDefaultNamespace(theNamespaceURI);
757                 }
758             else
759                 {
760                 return false;
761                 }
762         }//switch
764     return false;
768 /**
769  *
770  */
771 DOMString NodeImpl::lookupNamespaceURI(const DOMString &thePrefix)
773     switch (nodeType)
774         {
775         case ELEMENT_NODE:
776             {
777             if ( namespaceURI.size()>0 && prefix == thePrefix )
778                 {
779                 DOMString nsURI = namespaceURI;
780                 return (nsURI);
781                 }
782             if ( hasAttributes() )
783                 {
784                 NamedNodeMap attributes = getAttributes();
785                 int nrAttrs = attributes.getLength();
786                 for (int i=0 ; i<nrAttrs ; i++)
787                     {
788                     Node *attr = attributes.item(i);
789                     if (attr->getPrefix() == "xmlns" && attr->getLocalName() == thePrefix )
790                         { // non default namespace
791                         if (attr->getNodeValue().size()>0)
792                             {
793                             return (attr->getNodeValue());
794                             }
795                         return DOMString("");
796                         }
797                     else if (attr->getLocalName() == "xmlns" && thePrefix.size()==0)
798                         { // default namespace
799                         if (attr->getNodeValue().size()>0)
800                             {
801                             return (attr->getNodeValue());
802                             }
803                         return DOMString("");
804                         }
805                     }
806                 }
808             if ( Node *ancestor = getAncestorElement(this) )
809                 {
810                 return ancestor->lookupNamespaceURI(thePrefix);
811                 }
812             return DOMString("");
813             }
814         case DOCUMENT_NODE:
815             {
816             Document *doc = (Document *)this;
817             Element *elem = doc->getDocumentElement();
818             return elem->lookupNamespaceURI(thePrefix);
819             }
820         case ENTITY_NODE:
821         case NOTATION_NODE:
822         case DOCUMENT_TYPE_NODE:
823         case DOCUMENT_FRAGMENT_NODE:
824             return DOMString("");
826         case ATTRIBUTE_NODE:
827             {
828             if (Element *ownerElement = ((Attr *)this)->getOwnerElement())
829                 {
830                 return ownerElement->lookupNamespaceURI(thePrefix);
831                 }
832             else
833                 {
834                 return DOMString("");
835                 }
836             }
837         default:
838             if ( Node *ancestor = getAncestorElement(this) )
839                 {
840                 return ancestor->lookupNamespaceURI(thePrefix);
841                 }
842             else
843                 {
844                 return DOMString("");
845                 }
846         }//switch
850 /**
851  *
852  */
853 bool NodeImpl::isEqualNode(const Node *nodeArg)
855     if (!nodeArg)
856         return false;
858     if (this == nodeArg)
859         return true;
861     Node *node = (Node *)nodeArg;
863     if (getNodeType()     != node->getNodeType()     ||
864         getNodeName()     != node->getNodeName()     ||
865         getLocalName()    != node->getLocalName()    ||
866         getNamespaceURI() != node->getNamespaceURI() ||
867         getPrefix()       != node->getPrefix()       ||
868         getNodeValue()    != node->getNodeValue()    ||
869         getBaseURI()      != node->getBaseURI()      )
870         return false;
872     return true;
877 /**
878  *
879  */
880 DOMObject *NodeImpl::getFeature(const DOMString &feature,
881                              const DOMString &version)
883     //dont know
884     return NULL;
887 /**
888  *
889  */
890 DOMUserData *NodeImpl::setUserData(const DOMString &key,
891                                    const DOMUserData *data,
892                                    const UserDataHandler *handler)
894     UserDataEntry *entry = userDataEntries;
895     UserDataEntry *prev  = NULL;
896     while (entry)
897         {
898         if (entry->key == key)
899             {
900             DOMUserData *oldData = entry->data;
901             entry->data    = (DOMUserData *)data;
902             entry->handler = (UserDataHandler *)handler;
903             return oldData;
904             }
905         prev  = entry;
906         entry = entry->next;
907         }
909     //Make a new one
910     UserDataEntry *newEntry = new UserDataEntry(key, data, handler);
911     if (!prev)
912         userDataEntries = newEntry;
913     else
914         prev->next = newEntry;
916     return NULL;
919 /**
920  *
921  */
922 DOMUserData *NodeImpl::getUserData(const DOMString &key)
924     UserDataEntry *entry = userDataEntries;
925     while (entry)
926         {
927         if (entry->key == key)
928             return entry->data;
929         entry = entry->next;
930         }
931     return NULL;
936 //##################
937 //# Non-API methods
938 //##################
940 /**
941  *
942  */
943 void NodeImpl::setNodeName(const DOMString &qualifiedName)
945     nodeName  = qualifiedName;
946     prefix    = "";
947     localName = "";
948     for (unsigned int i=0 ; i<qualifiedName.size() ; i++)
949         {
950         int ch = qualifiedName[i];
951         if (ch == ':')
952             {
953             prefix    = localName;
954             localName = "";
955             }
956         else
957             {
958             localName.push_back((XMLCh)ch);
959             }
960         }
963 /**
964  *
965  */
966 void NodeImpl::setNamespaceURI(const DOMString &theNamespaceURI)
968     namespaceURI = theNamespaceURI;
972 /**
973  * From DOM3 Namespace algorithms
974  */
975 DOMString NodeImpl::lookupNamespacePrefix(const DOMString &theNamespaceURI,
976                                 Node *originalElement)
978     if (!originalElement)
979         return DOMString("");
981     if ( namespaceURI.size()>0 && namespaceURI==theNamespaceURI &&
982          prefix.size()>0 &&
983          originalElement->lookupNamespaceURI(prefix) == theNamespaceURI)
984         {
985         return (prefix);
986         }
988     if ( hasAttributes() )
989         {
990         NamedNodeMap attributes = getAttributes();
991         int nrAttrs = attributes.getLength();
992         for (int i=0 ; i<nrAttrs ; i++)
993             {
994             Node *attr = attributes.item(i);
995             DOMString attrLocalName = attr->getLocalName();
996             if (attr->getPrefix()    == "xmlns" &&
997                 attr->getNodeValue() == theNamespaceURI &&
998                 originalElement->lookupNamespaceURI(attrLocalName)
999                                      == theNamespaceURI)
1000                 {
1001                 return (attrLocalName);
1002                 }
1003             }
1004         }
1006     //Get ancestor element, if any
1007     NodeImpl *ancestor = parent;
1008     while (ancestor && ancestor->getNodeType()!= Node::ELEMENT_NODE)
1009         ancestor = ancestor->parent;
1011     if ( ancestor )
1012         {
1013         return ancestor->lookupNamespacePrefix(theNamespaceURI, originalElement);
1014         }
1016     return DOMString("");
1020 /**
1021  *
1022  */
1023 NodeImpl::NodeImpl() : Node()
1025     init();
1029 /**
1030  *
1031  */
1032 NodeImpl::NodeImpl(const NodeImpl &other) : Node()
1034     init();
1035     assign(other);
1038 /**
1039  *
1040  */
1041 NodeImpl &NodeImpl::operator=(const NodeImpl &other)
1043     init();
1044     assign(other);
1045     return *this;
1049 /**
1050  *
1051  */
1052 NodeImpl::NodeImpl(DocumentImpl *owner)
1054     init();
1055     ownerDocument = owner;
1058 /**
1059  *
1060  */
1061 NodeImpl::NodeImpl(DocumentImpl *owner, const DOMString &nodeName)
1063     init();
1064     ownerDocument = owner;
1065     setNodeName(nodeName);
1068 /**
1069  *
1070  */
1071 NodeImpl::NodeImpl(DocumentImpl *owner, const DOMString &theNamespaceURI,
1072                       const DOMString &qualifiedName)
1074     init();
1075     ownerDocument = owner;
1076     //if (owner)
1077     //    namespaceURI  = owner->stringCache(theNamespaceURI);
1078     setNodeName(qualifiedName);
1083 /**
1084  *
1085  */
1086 void NodeImpl::init()
1088     nodeType        = 0; //none yet
1089     nodeValue       = "";
1090     setNodeName("");
1091     namespaceURI    = "";
1092     parent          = NULL;
1093     prev            = NULL;
1094     next            = NULL;
1095     userData        = NULL;
1096     firstChild      = NULL;
1097     lastChild       = NULL;
1098     ownerDocument   = NULL;
1099     userDataEntries = NULL;
1102 /**
1103  *
1104  */
1105 void NodeImpl::assign(const NodeImpl &other)
1107     ownerDocument = other.ownerDocument;
1108     prefix        = other.prefix;
1109     localName     = other.localName;
1110     nodeName      = other.nodeName;
1111     nodeValue     = other.nodeValue;
1112     namespaceURI  = other.namespaceURI;
1113     attributes    = other.attributes;
1117 /**
1118  *
1119  */
1120 NodeImpl::~NodeImpl()
1122     if (userDataEntries)
1123         delete userDataEntries;
1124     //Delete children
1125         for (Node *n = getFirstChild() ; n ;
1126                      n=n->getNextSibling() )
1127         delete n;
1132 /*#########################################################################
1133 ## CharacterDataImpl
1134 #########################################################################*/
1137 /**
1138  *
1139  */
1140 CharacterDataImpl::CharacterDataImpl() : NodeImpl()
1144 /**
1145  *
1146  */
1147 CharacterDataImpl::CharacterDataImpl(DocumentImpl *owner,
1148                                      const DOMString &theValue) : NodeImpl()
1150     ownerDocument = owner;
1151     nodeValue     = theValue;
1154 /**
1155  *
1156  */
1157 CharacterDataImpl::~CharacterDataImpl()
1161 /**
1162  *
1163  */
1164 DOMString CharacterDataImpl::getData() throw(DOMException)
1166     return nodeValue;
1169 /**
1170  *
1171  */
1172 void CharacterDataImpl::setData(const DOMString& val) throw(DOMException)
1174     nodeValue = val;
1177 /**
1178  *
1179  */
1180 unsigned long CharacterDataImpl::getLength()
1182     return nodeValue.size();
1185 /**
1186  *
1187  */
1188 DOMString CharacterDataImpl::substringData(unsigned long offset,
1189                         unsigned long count)
1190                         throw(DOMException)
1192     return nodeValue.substr(offset, count);
1195 /**
1196  *
1197  */
1198 void CharacterDataImpl::appendData(const DOMString& arg) throw(DOMException)
1200     nodeValue += arg;
1203 /**
1204  *
1205  */
1206 void CharacterDataImpl::insertData(unsigned long offset,
1207                 const DOMString& arg)
1208                 throw(DOMException)
1210     nodeValue.insert(offset, arg);
1213 /**
1214  *
1215  */
1216 void CharacterDataImpl::deleteData(unsigned long offset,
1217                 unsigned long count)
1218                 throw(DOMException)
1220     nodeValue.erase(offset, count);
1223 /**
1224  *
1225  */
1226 void  CharacterDataImpl::replaceData(unsigned long offset,
1227                   unsigned long count,
1228                   const DOMString& arg)
1229                   throw(DOMException)
1231     nodeValue.replace(offset, count, arg);
1239 /*#########################################################################
1240 ## AttrImpl
1241 #########################################################################*/
1243 /**
1244  *
1245  */
1246 DOMString AttrImpl::getName()
1248     return nodeName;
1251 /**
1252  *
1253  */
1254 bool AttrImpl::getSpecified()
1256     return (nodeValue.size() > 0);
1259 /**
1260  *
1261  */
1262 DOMString AttrImpl::getValue()
1264     return nodeValue;
1267 /**
1268  *
1269  */
1270 void AttrImpl::setValue(const DOMString& val) throw(DOMException)
1272     nodeValue = val;
1275 /**
1276  *
1277  */
1278 Element *AttrImpl::getOwnerElement()
1280     return ownerElement;
1284 /**
1285  *
1286  */
1287 TypeInfo *AttrImpl::getSchemaTypeInfo()
1289     return NULL;
1293 /**
1294  *
1295  */
1296 bool AttrImpl::getIsId()
1298     return (nodeName == "id");
1303 //##################
1304 //# Non-API methods
1305 //##################
1308 void AttrImpl::setOwnerElement(const Element *elem)
1310     ownerElement = (Element *)elem;
1313 /**
1314  *
1315  */
1316 AttrImpl::AttrImpl(DocumentImpl *owner, const DOMString &theName)
1317                    : NodeImpl()
1319     nodeType     = ATTRIBUTE_NODE;
1320     ownerDocument = owner;
1321     setNodeName(theName);
1324 /**
1325  *
1326  */
1327 AttrImpl::AttrImpl(DocumentImpl *owner,
1328                    const DOMString &theNamespaceURI,
1329                    const DOMString &theQualifiedName)
1330                    : NodeImpl()
1332     nodeType     = ATTRIBUTE_NODE;
1333     ownerDocument = owner;
1334     //if (owner)
1335     //    namespaceURI  = owner->stringCache(theNamespaceURI);
1336     setNodeName(theQualifiedName);
1339 /**
1340  *
1341  */
1342 AttrImpl::~AttrImpl()
1350 /*#########################################################################
1351 ## ElementImpl
1352 #########################################################################*/
1355 /**
1356  *
1357  */
1358 DOMString ElementImpl::getTagName()
1360     if (prefix.size() > 0)
1361         return prefix + ":" + nodeName;
1362     else
1363         return nodeName;
1366 /**
1367  *
1368  */
1369 DOMString ElementImpl::getAttribute(const DOMString& name)
1371     Node *node = attributes.getNamedItem(name);
1372     if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1373         return DOMString("");
1374     Attr *attr = dynamic_cast<Attr *>(node);
1375     return attr->getValue();
1378 /**
1379  *
1380  */
1381 void ElementImpl::setAttribute(const DOMString& name,
1382                   const DOMString& value)
1383                   throw(DOMException)
1385     AttrImpl *attr = new AttrImpl(ownerDocument, name);
1386     attr->setValue(value);
1387     attr->setOwnerElement(this);
1388     attributes.setNamedItem(attr);
1391 /**
1392  *
1393  */
1394 void ElementImpl::removeAttribute(const DOMString& name)
1395                      throw(DOMException)
1397     attributes.removeNamedItem(name);
1400 /**
1401  *
1402  */
1403 Attr *ElementImpl::getAttributeNode(const DOMString& name)
1405     Node *node = attributes.getNamedItem(name);
1406     if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1407         return NULL;
1408     Attr *attr = dynamic_cast<Attr *>(node);
1409     return attr;
1412 /**
1413  *
1414  */
1415 Attr *ElementImpl::setAttributeNode(Attr *attr)
1416                       throw(DOMException)
1418     attributes.setNamedItem(attr);
1419     return attr;
1422 /**
1423  *
1424  */
1425 Attr *ElementImpl::removeAttributeNode(Attr *attr)
1426                          throw(DOMException)
1428     if (!attr)
1429         return NULL;
1430     attributes.removeNamedItem(attr->getName());
1431     return attr;
1435 /**
1436  *
1437  */
1438 void ElementImpl::getElementsByTagNameRecursive(NodeList &list,
1439                         const DOMString& name, Element *elem)
1441     if (!elem)
1442         return;
1444     if (name == elem->getTagName())
1445         list.add(elem);
1446     for (Node *node = elem->getFirstChild() ; node ; node=node->getNextSibling())
1447         {
1448         if (node->getNodeType() != Node::ELEMENT_NODE)
1449             continue;
1450         Element *childElem = dynamic_cast<Element *>(node);
1451         getElementsByTagNameRecursive(list, name, childElem);
1452         }
1456 /**
1457  *
1458  */
1459 NodeList ElementImpl::getElementsByTagName(const DOMString& tagName)
1461     NodeList list;
1462     getElementsByTagNameRecursive(list, tagName, this);
1463     return list;
1466 /**
1467  *
1468  */
1469 DOMString ElementImpl::getAttributeNS(const DOMString& namespaceURI,
1470                          const DOMString& localName)
1472     Node *node = attributes.getNamedItemNS(namespaceURI, localName);
1473     if (!node || node->getNodeType()!=ATTRIBUTE_NODE)
1474         return DOMString("");
1475     Attr *attr = dynamic_cast<Attr *>(node);
1476     return attr->getValue();
1479 /**
1480  *
1481  */
1482 void ElementImpl::setAttributeNS(const DOMString& namespaceURI,
1483                     const DOMString& qualifiedName,
1484                     const DOMString& value)
1485                     throw(DOMException)
1487     AttrImpl *attr = new AttrImpl(ownerDocument, namespaceURI, qualifiedName);
1488     attr->setValue(value);
1489     attr->setOwnerElement(this);
1490     attributes.setNamedItemNS(attr);
1493 /**
1494  *
1495  */
1496 void ElementImpl::removeAttributeNS(const DOMString& namespaceURI,
1497                        const DOMString& localName)
1498                        throw(DOMException)
1500     attributes.removeNamedItemNS(namespaceURI, localName);
1503 /**
1504  *
1505  */
1506  Attr *ElementImpl::getAttributeNodeNS(const DOMString& namespaceURI,
1507                         const DOMString& localName)
1509     Node *node = attributes.getNamedItemNS(namespaceURI, localName);
1510     if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1511         return NULL;
1512     Attr *attr = dynamic_cast<Attr *>(node);
1513     return attr;
1516 /**
1517  *
1518  */
1519 Attr *ElementImpl::setAttributeNodeNS(Attr *attr)
1520                         throw(DOMException)
1522     attributes.setNamedItemNS(attr);
1523     return attr;
1527 /**
1528  *
1529  */
1530 void ElementImpl::getElementsByTagNameNSRecursive(NodeList &list,
1531              const DOMString& namespaceURI, const DOMString& tagName, Element *elem)
1533     if (!elem)
1534         return;
1536     if (namespaceURI == elem->getNamespaceURI() && tagName == elem->getTagName())
1537         list.add(elem);
1538     for (Node *node = elem->getFirstChild() ; node ; node=node->getNextSibling())
1539         {
1540         if (node->getNodeType() != Node::ELEMENT_NODE)
1541             continue;
1542         Element *childElem = dynamic_cast<Element *>(node);
1543         getElementsByTagNameNSRecursive(list, namespaceURI, tagName, childElem);
1544         }
1547 /**
1548  *
1549  */
1550 NodeList ElementImpl::getElementsByTagNameNS(const DOMString& namespaceURI,
1551                                 const DOMString& localName)
1553     NodeList list;
1554     getElementsByTagNameNSRecursive(list, namespaceURI, localName, this);
1555     return list;
1558 /**
1559  *
1560  */
1561 bool ElementImpl::hasAttribute(const DOMString& attrName)
1563     Node *node = attributes.getNamedItem(attrName);
1564     if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1565         return false;
1566     return true;
1569 /**
1570  *
1571  */
1572 bool ElementImpl::hasAttributeNS(const DOMString& namespaceURI,
1573                     const DOMString& localName)
1575     Node *node = attributes.getNamedItemNS(namespaceURI, localName);
1576     if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1577         return false;
1578     return true;
1581 /**
1582  *
1583  */
1584 TypeInfo *ElementImpl::getSchemaTypeInto()
1586     //fixme
1587     return NULL;
1591 /**
1592  *
1593  */
1594 void ElementImpl::setIdAttribute(const DOMString &name,
1595                             bool isId) throw (DOMException)
1597     //fixme
1600 /**
1601  *
1602  */
1603 void ElementImpl::setIdAttributeNS(const DOMString &namespaceURI,
1604                               const DOMString &localName,
1605                               bool isId) throw (DOMException)
1607     //fixme
1610 /**
1611  *
1612  */
1613 void ElementImpl::setIdAttributeNode(const Attr *idAttr,
1614                                 bool isId) throw (DOMException)
1616     //fixme
1620 //##################
1621 //# Non-API methods
1622 //##################
1625 /**
1626  *
1627  */
1628 ElementImpl::ElementImpl() : NodeImpl()
1630     nodeType = ELEMENT_NODE;
1633 /**
1634  *
1635  */
1636 ElementImpl::ElementImpl(DocumentImpl *owner, const DOMString &tagName)
1637                                   : NodeImpl()
1639     nodeType = ELEMENT_NODE;
1640     ownerDocument = owner;
1641     setNodeName(tagName);
1644 /**
1645  *
1646  */
1647 ElementImpl::ElementImpl(DocumentImpl *owner,
1648                          const DOMString &theNamespaceURI,
1649                          const DOMString &qualifiedName) :
1650                          NodeImpl()
1652     nodeType = ELEMENT_NODE;
1653     ownerDocument = owner;
1654     setNodeName(qualifiedName);
1657 /**
1658  *
1659  */
1660 ElementImpl::~ElementImpl()
1665 /**
1666  *
1667  */
1668 void ElementImpl::normalizeNamespaces()
1670     //printf("### NORMALIZE\n");
1672     NamedNodeMap attrs = getAttributes();
1674     //#######################################
1675     //# Pick up local namespace declarations
1676     //#######################################
1677     bindingsClear();  //Reset bindings on this node
1679     int nrAttrs = attrs.getLength();
1680     for (int i=0; i<nrAttrs ; i++)
1681         {
1682         Node *attrNode = attrs.item(i);
1683         if (attrNode->getNodeType() != Node::ATTRIBUTE_NODE)
1684             continue;
1685         AttrImpl *attr = dynamic_cast<AttrImpl *>(attrNode);
1686         DOMString attrNS     = attr->getNamespaceURI();
1687         DOMString attrName   = attr->getLocalName();
1688         DOMString attrPrefix = attr->getPrefix();
1689         DOMString attrValue  = attr->getNodeValue();
1690         if (attrName != "xmlns" && attrPrefix != "xmlns")
1691             continue;
1693         //is the namespace declaration is invalid?
1694         if (attrValue == XMLNSNAME || attrName == attrPrefix)
1695             {
1696             // Note: The prefix xmlns is used only to declare namespace bindings and
1697             // is by definition bound to the namespace name http://www.w3.org/2000/xmlns/.
1698             // It must not be declared. No other prefix may be bound to this namespace name.
1700             //==> Report an error.
1701             printf("normalizeNamespaces() error: Namespace %s cannot be reassigned\n",
1702                         XMLNSNAME);
1704             }
1705         else
1706             {
1707             //==>  Record the namespace declaration
1708             attr->setNamespaceURI(XMLNSNAME);
1709             if (attrPrefix.size() > 0)
1710                 bindingsAdd(attrPrefix, attrValue);
1711             else
1712                 bindingsAdd("*", attrValue);//default
1714             }
1715         }
1718     //#######################################
1719     //# Fixup element's namespace
1720     //#######################################
1721     if ( namespaceURI.size() > 0 )
1722         {
1723         DOMString key = prefix;
1724         if (key.size() == 0)
1725             key = "*";
1726         DOMString binding = bindingsFind(key);
1727         //Element's prefix/namespace pair (or default namespace, if no prefix)
1728         // are within the scope of a binding
1729         if ( binding == namespaceURI )
1730             {
1731             //==> do nothing, declaration in scope is inherited
1733             // See section "B.1.1: Scope of a binding" for an example
1735             }
1736         else
1737             {
1739             /*
1740             ==> Create a local namespace declaration attr for this namespace,
1741             with Element's current prefix (or a default namespace, if
1742             no prefix). If there's a conflicting local declaration
1743             already present, change its value to use this namespace.
1745             See section "B.1.2: Conflicting namespace declaration" for an example
1746             */
1747             DOMString attrName = "xmlns";
1748             if (prefix.size() > 0)
1749                 {
1750                 attrName.append(":");
1751                 attrName.append(prefix);
1752                 }
1753             setAttribute(attrName, namespaceURI);
1754             // NOTE that this may break other nodes within this Element's
1755             // subtree, if they're already using this prefix.
1756             // They will be repaired when we reach them.
1757             }
1758         }
1759     else  // Element has no namespace URI:
1760         {
1761         //###############################################
1762         //# Bob -- alter this from the specs a bit.
1763         //#  Since the XmlReader does not set namespaces,
1764         //#    do it here
1765         //###############################################
1766         DOMString localName = getLocalName();
1767         if ( localName.size()==0 )
1768             {
1769             // DOM Level 1 node
1770             /*
1771             ==> if in process of validation against a namespace aware schema
1772             (i.e XML Schema) report a fatal error: the processor can not recover
1773             in this situation.
1774             Otherwise, report an error: no namespace fixup will be performed on this node.
1775             */
1776             printf("normalizeNamespaces() error: no localName\n");
1777             }
1778         else
1779             {
1780             // Element has no pseudo-prefix
1781             //there's a conflicting local default namespace declaration already present
1782             if ( prefix.size()==0 )
1783                 {
1784                 //==> change its value to use this empty namespace.
1785                 namespaceURI = bindingsFind("*");
1786                 //setAttribute("xmlns", "");
1787                 }
1788             else  //#BOB .   I added this.
1789                 {
1790                 namespaceURI = bindingsFind(prefix);
1791                 }
1792             // NOTE that this may break other nodes within this Element's
1793             // subtree, if they're already using the default namespaces.
1794             // They will be repaired when we reach them.
1795             }
1796         }
1799     //#######################################
1800     //# Examine and polish the attributes
1801     //#######################################
1802     nrAttrs = attrs.getLength();
1803     for (int i=0; i<nrAttrs ; i++)// all non-namespace Attrs of Element
1804         {
1805         Node *attrNode = attrs.item(i);
1806         if (attrNode->getNodeType() != Node::ATTRIBUTE_NODE)
1807             continue;
1808         Attr *attr = dynamic_cast<Attr *>(attrNode);
1809         DOMString attrNS     = attr->getNamespaceURI();
1810         DOMString attrPrefix = attr->getPrefix();
1811         DOMString attrValue  = attr->getNodeValue();
1812         if (attrNS == XMLNSNAME)
1813             continue;
1815         if ( attrNS.size()>0 ) //Attr[i] has a namespace URI
1816             {
1817             DOMString attrBinding = bindingsFind(attrPrefix);
1818             /*
1819              if attribute has no prefix (default namespace decl does not apply to attributes)
1820              OR
1821              attribute prefix is not declared
1822              OR
1823              conflict: attribute has a prefix that conflicts with a binding
1824                        already active in scope
1825             */
1826             if ( attrPrefix.size() == 0 || attrBinding.size() == 0)
1827                 {
1828                 //namespaceURI matches an in scope declaration of one or more prefixes)
1829                 DOMString prefixForNS = lookupNamespacePrefix(attrNS, this);
1830                 if ( prefixForNS.size() > 0 )
1831                     {
1832                     // pick the most local binding available;
1833                     // if there is more than one pick one arbitrarily
1835                     //==> change attribute's prefix.
1836                     attr->setPrefix(prefixForNS);
1837                     }
1838                 else
1839                     {
1840                     // the current prefix is not null and it has no in scope declaration)
1841                     if ( attrPrefix.size() > 0 || attrBinding.size() == 0 )
1842                         {
1843                         //==> declare this prefix
1844                         DOMString newAttrName = "xmlns:";
1845                         newAttrName.append(attrPrefix);
1846                         setAttribute(newAttrName, attrNS);
1847                         bindingsAdd(attrPrefix, attrNS);
1848                         }
1849                     else
1850                         {
1851                         // find a prefix following the pattern "NS" +index (starting at 1)
1852                         // make sure this prefix is not declared in the current scope.
1853                         // create a local namespace declaration attribute
1855                         //==> declare this prefix
1856                         char buf[16];
1857                         sprintf(buf, "%d" , ownerDocument->namespaceIndex++);
1858                         DOMString newPrefix = "NS";
1859                         newPrefix.append(buf);
1860                         DOMString newAttrName = "xmlns:";
1861                         newAttrName.append(newPrefix);
1862                         setAttribute(newAttrName, attrNS);
1863                         bindingsAdd(newPrefix, attrNS);
1864                         //==> change attribute's prefix.
1865                         }
1866                     }
1867                 }
1868             }
1869         else  // Attr has no namespace URI
1870             {
1871             // Attr has no localName
1872             if ( attr->getLocalName().size() == 0 )
1873                 {
1874                 // DOM Level 1 node
1875                 /*
1876                 ==> if in process of validation against a namespace aware schema
1877                 (i.e XML Schema) report a fatal error: the processor can not recover
1878                 in this situation.
1879                 Otherwise, report an error: no namespace fixup will be performed on this node.
1880                 */
1881                 printf("normalizeNamespaces:  no local name for attribute\n");
1882                 }
1883             else
1884                 {
1885                 // attr has no namespace URI and no prefix
1886                 // no action is required, since attrs don't use default
1887                 //==> do nothing
1888                 }
1889             }
1890         } // end for-all-Attrs
1893     //#######################################
1894     //# Recursively normalize children
1895     //#######################################
1896     for (Node *child=getFirstChild() ; child ; child=child->getNextSibling())
1897         {
1898         if (child->getNodeType() != Node::ELEMENT_NODE)
1899             continue;
1900         ElementImpl *childElement = dynamic_cast<ElementImpl *>(child);
1901         childElement->normalizeNamespaces();
1902         }
1907 /*#########################################################################
1908 ## TextImpl
1909 #########################################################################*/
1912 /**
1913  *
1914  */
1915 TextImpl::TextImpl() : CharacterDataImpl()
1917     nodeType = TEXT_NODE;
1918     nodeName = "#text";
1922 /**
1923  *
1924  */
1925 TextImpl::TextImpl(DocumentImpl *owner, const DOMString &value)
1926                                : CharacterDataImpl()
1928     nodeType      = TEXT_NODE;
1929     nodeName      = "#text";
1930     ownerDocument = owner;
1931     nodeValue     = value;
1935 /**
1936  *
1937  */
1938 TextImpl::~TextImpl()
1942 /**
1943  *
1944  */
1945 Text *TextImpl::splitText(unsigned long offset)
1946                 throw(DOMException)
1948     return NULL;
1951 /**
1952  *
1953  */
1954 bool TextImpl::getIsElementContentWhitespace()
1956     return false;
1959 /**
1960  *
1961  */
1962 DOMString TextImpl::getWholeText()
1964     return nodeValue;
1968 /**
1969  *
1970  */
1971 Text *TextImpl::replaceWholeText(const DOMString &content)
1972                              throw(DOMException)
1974     return NULL;
1978 /*#########################################################################
1979 ## CommentImpl
1980 #########################################################################*/
1982 /**
1983  *
1984  */
1985 CommentImpl::CommentImpl() : CharacterDataImpl()
1987     nodeType = COMMENT_NODE;
1988     nodeName = "#comment";
1992 /**
1993  *
1994  */
1995 CommentImpl::CommentImpl(DocumentImpl *owner, const DOMString &value)
1996                        : CharacterDataImpl()
1998     nodeType      = COMMENT_NODE;
1999     nodeName      = "#comment";
2000     ownerDocument = owner;
2001     nodeValue     = value;
2005 /**
2006  *
2007  */
2008 CommentImpl::~CommentImpl()
2015 /*#########################################################################
2016 ## TypeInfoImpl
2017 #########################################################################*/
2020 /**
2021  *
2022  */
2023 TypeInfoImpl::TypeInfoImpl(const DOMString &typeNamespaceArg,
2024                  const DOMString &typeNameArg,
2025                  const DerivationMethod derivationMethodArg)
2027     typeNamespace    = typeNamespaceArg;
2028     typeName         = typeNameArg;
2029     derivationMethod = derivationMethodArg;
2033 /**
2034  *
2035  */
2036 TypeInfoImpl::~TypeInfoImpl()
2041 /**
2042  *
2043  */
2044 DOMString TypeInfoImpl::getTypeName()
2046     return typeName;
2049 /**
2050  *
2051  */
2052 DOMString TypeInfoImpl::getTypeNamespace()
2054     return typeNamespace;
2057 /**
2058  *
2059  */
2060 bool TypeInfoImpl::isDerivedFrom(const DOMString &typeNamespaceArg,
2061                            const DOMString &typeNameArg,
2062                            const DerivationMethod derivationMethodArg)
2064     if (typeNamespaceArg == typeNamespace &&
2065         typeName         == typeNameArg &&
2066         derivationMethod == derivationMethodArg)
2067         return true;
2068     return false;
2073 /*#########################################################################
2074 ## UserDataHandlerImpl
2075 #########################################################################*/
2079 /**
2080  *
2081  */
2082 UserDataHandlerImpl::UserDataHandlerImpl()
2087 /**
2088  *
2089  */
2090 UserDataHandlerImpl::~UserDataHandlerImpl()
2094 /**
2095  *
2096  */
2097 void UserDataHandlerImpl::handle(unsigned short operation,
2098                      const DOMString &key,
2099                      const DOMUserData *data,
2100                      const Node *src,
2101                      const Node *dst)
2103     //do nothing.  do we need anything here?
2108 /*#########################################################################
2109 ## DOMErrorImpl
2110 #########################################################################*/
2114 /**
2115  *
2116  */
2117 DOMErrorImpl::DOMErrorImpl()
2122 /**
2123  *
2124  */
2125 DOMErrorImpl::~DOMErrorImpl()
2129 /**
2130  *
2131  */
2132 unsigned short DOMErrorImpl::getSeverity()
2134     return severity;
2137 /**
2138  *
2139  */
2140 DOMString DOMErrorImpl::getMessage()
2142     return message;
2145 /**
2146  *
2147  */
2148 DOMString DOMErrorImpl::getType()
2150     return type;
2153 /**
2154  *
2155  */
2156 DOMObject *DOMErrorImpl::getRelatedException()
2158     return NULL;
2161 /**
2162  *
2163  */
2164 DOMObject *DOMErrorImpl::getRelatedData()
2166     return NULL;
2169 /**
2170  *
2171  */
2172 DOMLocator *DOMErrorImpl::getLocation()
2174     //really should fill this in
2175     return NULL;
2181 /*#########################################################################
2182 ## DOMErrorHandlerImpl
2183 #########################################################################*/
2187 /**
2188  *
2189  */
2190 DOMErrorHandlerImpl::DOMErrorHandlerImpl()
2195 /**
2196  *
2197  */
2198 DOMErrorHandlerImpl::~DOMErrorHandlerImpl()
2202 /**
2203  *
2204  */
2205 bool DOMErrorHandlerImpl::handleError(const DOMError *error)
2207     if (!error)
2208         return false;
2209     return true;
2215 /*#########################################################################
2216 ## DOMLocatorImpl
2217 #########################################################################*/
2220 /**
2221  *
2222  */
2223 DOMLocatorImpl::DOMLocatorImpl()
2228 /**
2229  *
2230  */
2231 DOMLocatorImpl::~DOMLocatorImpl()
2236 /**
2237  *
2238  */
2239 long DOMLocatorImpl::getLineNumber()
2241     return lineNumber;
2244 /**
2245  *
2246  */
2247 long DOMLocatorImpl::getColumnNumber()
2249     return columnNumber;
2252 /**
2253  *
2254  */
2255 long DOMLocatorImpl::getByteOffset()
2257     return byteOffset;
2260 /**
2261  *
2262  */
2263 long DOMLocatorImpl::getUtf16Offset()
2265     return utf16Offset;
2269 /**
2270  *
2271  */
2272 Node *DOMLocatorImpl::getRelatedNode()
2274     return relatedNode;
2278 /**
2279  *
2280  */
2281 DOMString DOMLocatorImpl::getUri()
2283     return uri;
2288 /*#########################################################################
2289 ## DOMConfigurationImpl
2290 #########################################################################*/
2293 /**
2294  *
2295  */
2296 DOMConfigurationImpl::DOMConfigurationImpl()
2301 /**
2302  *
2303  */
2304 DOMConfigurationImpl::~DOMConfigurationImpl()
2308 /**
2309  *
2310  */
2311 void DOMConfigurationImpl::setParameter(const DOMString &name,
2312                           const DOMUserData *value) throw (DOMException)
2316 /**
2317  *
2318  */
2319 DOMUserData *DOMConfigurationImpl::getParameter(const DOMString &name)
2320                                   throw (DOMException)
2322     return NULL;
2325 /**
2326  *
2327  */
2328 bool DOMConfigurationImpl::canSetParameter(const DOMString &name,
2329                              const DOMUserData *data)
2331     return false;
2334 /**
2335  *
2336  */
2337 DOMStringList *DOMConfigurationImpl::getParameterNames()
2339     return NULL;
2344 /*#########################################################################
2345 ## CDATASectionImpl
2346 #########################################################################*/
2348 /**
2349  *
2350  */
2351 CDATASectionImpl::CDATASectionImpl() : TextImpl()
2353     nodeType = CDATA_SECTION_NODE;
2354     nodeName = "#cdata-section";
2357 /**
2358  *
2359  */
2360 CDATASectionImpl::CDATASectionImpl(DocumentImpl *owner, const DOMString &theValue)
2361                                  : TextImpl()
2363     nodeType      = CDATA_SECTION_NODE;
2364     nodeName      = "#cdata-section";
2365     ownerDocument = owner;
2366     nodeValue     = theValue;
2370 /**
2371  *
2372  */
2373 CDATASectionImpl::~CDATASectionImpl()
2381 /*#########################################################################
2382 ## DocumentTypeImpl
2383 #########################################################################*/
2385 /**
2386  *
2387  */
2388 DocumentTypeImpl::DocumentTypeImpl(const DOMString& theName,
2389                                    const DOMString& thePublicId,
2390                                    const DOMString& theSystemId)
2391                                   : NodeImpl()
2393     nodeType = DOCUMENT_TYPE_NODE;
2394     nodeName = theName;
2395     publicId = thePublicId;
2396     systemId = theSystemId;
2399 /**
2400  *
2401  */
2402 DocumentTypeImpl::~DocumentTypeImpl()
2406 /**
2407  *
2408  */
2409 DOMString DocumentTypeImpl::getName()
2411     return nodeName;
2414 /**
2415  *
2416  */
2417 NamedNodeMap DocumentTypeImpl::getEntities()
2419     return entities;
2422 /**
2423  *
2424  */
2425 NamedNodeMap DocumentTypeImpl::getNotations()
2427     return notations;
2430 /**
2431  *
2432  */
2433 DOMString DocumentTypeImpl::getPublicId()
2435     return publicId;
2438 /**
2439  *
2440  */
2441 DOMString DocumentTypeImpl::getSystemId()
2443     return systemId;
2446 /**
2447  *
2448  */
2449 DOMString DocumentTypeImpl::getInternalSubset()
2451     return DOMString("");
2459 /*#########################################################################
2460 ## NotationImpl
2461 #########################################################################*/
2465 /**
2466  *
2467  */
2468 NotationImpl::NotationImpl(DocumentImpl *owner) : NodeImpl()
2470     nodeType = NOTATION_NODE;
2471     ownerDocument = owner;
2475 /**
2476  *
2477  */
2478 NotationImpl::~NotationImpl()
2482 /**
2483  *
2484  */
2485 DOMString NotationImpl::getPublicId()
2487     return publicId;
2490 /**
2491  *
2492  */
2493 DOMString NotationImpl::getSystemId()
2495     return systemId;
2505 /*#########################################################################
2506 ## EntityImpl
2507 #########################################################################*/
2510 /**
2511  *
2512  */
2513 EntityImpl::EntityImpl() : NodeImpl()
2515     nodeType = ENTITY_NODE;
2519 /**
2520  *
2521  */
2522 EntityImpl::EntityImpl(DocumentImpl *owner) : NodeImpl()
2524     nodeType = ENTITY_NODE;
2525     ownerDocument = owner;
2529 /**
2530  *
2531  */
2532 EntityImpl::~EntityImpl()
2536 /**
2537  *
2538  */
2539 DOMString EntityImpl::getPublicId()
2541     return publicId;
2544 /**
2545  *
2546  */
2547 DOMString EntityImpl::getSystemId()
2549     return systemId;
2552 /**
2553  *
2554  */
2555 DOMString EntityImpl::getNotationName()
2557     return notationName;
2560 /**
2561  *
2562  */
2563 DOMString EntityImpl::getInputEncoding()
2565     return inputEncoding;
2568 /**
2569  *
2570  */
2571 DOMString EntityImpl::getXmlEncoding()
2573     return xmlEncoding;
2576 /**
2577  *
2578  */
2579 DOMString EntityImpl::getXmlVersion()
2581     return xmlVersion;
2589 /*#########################################################################
2590 ## EntityReferenceImpl
2591 #########################################################################*/
2595 /**
2596  *
2597  */
2598 EntityReferenceImpl::EntityReferenceImpl() : NodeImpl()
2600     nodeType = ENTITY_REFERENCE_NODE;
2604 /**
2605  *
2606  */
2607 EntityReferenceImpl::EntityReferenceImpl(DocumentImpl *owner,
2608                                          const DOMString &theName)
2609                                          : NodeImpl()
2611     nodeType = ENTITY_REFERENCE_NODE;
2612     nodeName = theName;
2613     ownerDocument = owner;
2617 /**
2618  *
2619  */
2620 EntityReferenceImpl::~EntityReferenceImpl()
2626 /*#########################################################################
2627 ## ProcessingInstructionImpl
2628 #########################################################################*/
2633 /**
2634  *
2635  */
2636 ProcessingInstructionImpl::ProcessingInstructionImpl(): NodeImpl()
2638     nodeType = PROCESSING_INSTRUCTION_NODE;
2643 /**
2644  *
2645  */
2646 ProcessingInstructionImpl::ProcessingInstructionImpl(DocumentImpl *owner,
2647                                                      const DOMString &target,
2648                                                      const DOMString &data)
2649                                                      : NodeImpl()
2651     nodeType      = PROCESSING_INSTRUCTION_NODE;
2652     ownerDocument = owner;
2653     nodeName      = target;
2654     nodeValue     = data;
2658 /**
2659  *
2660  */
2661 ProcessingInstructionImpl::~ProcessingInstructionImpl()
2668 /**
2669  *
2670  */
2671 DOMString ProcessingInstructionImpl::getTarget()
2673     return nodeName;
2676 /**
2677  *
2678  */
2679 DOMString ProcessingInstructionImpl::getData()
2681     return nodeValue;
2684 /**
2685  *
2686  */
2687 void ProcessingInstructionImpl::setData(const DOMString& val) throw(DOMException)
2689      //do something here
2698 /*#########################################################################
2699 ## DocumentFragmentImpl
2700 #########################################################################*/
2702 /**
2703  *
2704  */
2705 DocumentFragmentImpl::DocumentFragmentImpl() : NodeImpl()
2707     nodeType = DOCUMENT_FRAGMENT_NODE;
2708     nodeName = "#document-fragment";
2712 /**
2713  *
2714  */
2715 DocumentFragmentImpl::DocumentFragmentImpl(DocumentImpl *owner) : NodeImpl()
2717     nodeType = DOCUMENT_FRAGMENT_NODE;
2718     nodeName = "#document-fragment";
2719     ownerDocument = owner;
2723 /**
2724  *
2725  */
2726 DocumentFragmentImpl::~DocumentFragmentImpl()
2735 /*#########################################################################
2736 ## DocumentImpl
2737 #########################################################################*/
2741 /**
2742  *
2743  */
2744 DocumentType *DocumentImpl::getDoctype()
2746     return doctype;
2749 /**
2750  *
2751  */
2752 DOMImplementation *DocumentImpl::getImplementation()
2754     return parent;
2757 /**
2758  *
2759  */
2760 Element *DocumentImpl::getDocumentElement()
2762     return documentElement;
2765 /**
2766  *
2767  */
2768 Element *DocumentImpl::createElement(const DOMString& tagName)
2769                        throw(DOMException)
2771     ElementImpl *impl = new ElementImpl(this, tagName);
2772     return impl;
2775 /**
2776  *
2777  */
2778 DocumentFragment *DocumentImpl::createDocumentFragment()
2780     DocumentFragmentImpl *frag = new DocumentFragmentImpl(this);
2781     return frag;
2784 /**
2785  *
2786  */
2787 Text *DocumentImpl::createTextNode(const DOMString& data)
2789     TextImpl *text = new TextImpl(this, data);
2790     return text;
2793 /**
2794  *
2795  */
2796 Comment *DocumentImpl::createComment(const DOMString& data)
2798     CommentImpl *comment = new CommentImpl(this, data);
2799     return comment;
2802 /**
2803  *
2804  */
2805 CDATASection *DocumentImpl::createCDATASection(const DOMString& data)
2806                                  throw(DOMException)
2808     CDATASectionImpl *cdata = new CDATASectionImpl(this, data);
2809     return cdata;
2812 /**
2813  *
2814  */
2815 ProcessingInstruction *DocumentImpl::createProcessingInstruction(const DOMString& target,
2816                                                    const DOMString& data)
2817                                                    throw(DOMException)
2819     ProcessingInstructionImpl *cdata =
2820         new ProcessingInstructionImpl(this, target, data);
2821     return cdata;
2824 /**
2825  *
2826  */
2827 Attr *DocumentImpl::createAttribute(const DOMString& attrName)
2828                       throw(DOMException)
2830     AttrImpl *attr = new AttrImpl(this, attrName);
2831     return attr;
2834 /**
2835  *
2836  */
2837 EntityReference *DocumentImpl::createEntityReference(const DOMString& erName)
2838                                        throw(DOMException)
2840     EntityReferenceImpl *ref = new EntityReferenceImpl(this, erName);
2841     return ref;
2845 /**
2846  *
2847  */
2848 NodeList DocumentImpl::getElementsByTagName(const DOMString& tagname)
2850     NodeList list;
2851     ElementImpl::getElementsByTagNameRecursive(list,
2852                      tagname, documentElement);
2853     return list;
2857 /**
2858  *
2859  */
2860 Node *DocumentImpl::importNode(const Node *importedNode,
2861                  bool deep)
2862                  throw(DOMException)
2864     return NULL;
2867 /**
2868  *
2869  */
2870 Element *DocumentImpl::createElementNS(const DOMString& namespaceURI,
2871                          const DOMString& qualifiedName)
2872                          throw(DOMException)
2874     ElementImpl *elem = new ElementImpl(this, namespaceURI, qualifiedName);
2875     return elem;
2878 /**
2879  *
2880  */
2881 Attr *DocumentImpl::createAttributeNS(const DOMString& namespaceURI,
2882                         const DOMString& qualifiedName)
2883                         throw(DOMException)
2885     AttrImpl *attr = new AttrImpl(this, namespaceURI, qualifiedName);
2886     return attr;
2890 /**
2891  *
2892  */
2893 NodeList DocumentImpl::getElementsByTagNameNS(const DOMString& namespaceURI,
2894                                  const DOMString& localName)
2896     NodeList list;
2897     ElementImpl::getElementsByTagNameNSRecursive(list, namespaceURI,
2898                           localName, documentElement);
2899     return list;
2902 /**
2903  *
2904  */
2905 Element *DocumentImpl::getElementById(const DOMString& elementId)
2907     for (NamedElementItem *entry = elementsById.next; entry ; entry=entry->next)
2908         if (entry->name == elementId)
2909             return entry->elem;
2910     return NULL;
2914 /**
2915  *
2916  */
2917 DOMString DocumentImpl::getInputEncoding()
2919     return inputEncoding;
2923 /**
2924  *
2925  */
2926 DOMString DocumentImpl::getXmlEncoding()
2928     return xmlEncoding;
2931 /**
2932  *
2933  */
2934 bool DocumentImpl::getXmlStandalone()
2936     return xmlStandalone;
2939 /**
2940  *
2941  */
2942 void DocumentImpl::setXmlStandalone(bool val) throw (DOMException)
2944     xmlStandalone = val;
2947 /**
2948  *
2949  */
2950 DOMString DocumentImpl::getXmlVersion()
2952     return xmlVersion;
2955 /**
2956  *
2957  */
2958 void DocumentImpl::setXmlVersion(const DOMString &version) throw (DOMException)
2960     xmlVersion = version;
2963 /**
2964  *
2965  */
2966 bool DocumentImpl::getStrictErrorChecking()
2968     return strictErrorChecking;
2971 /**
2972  *
2973  */
2974 void DocumentImpl::setStrictErrorChecking(bool val)
2976     strictErrorChecking = val;
2980 /**
2981  *
2982  */
2983 DOMString DocumentImpl::getDocumentURI()
2985     if (!documentURI)
2986         return DOMString("");
2987     DOMString docURI = *documentURI;
2988     return docURI;
2991 /**
2992  *
2993  */
2994 void DocumentImpl::setDocumentURI(const DOMString &uri)
2996     //documentURI = stringCache(uri);
2999 /**
3000  *
3001  */
3002 Node *DocumentImpl::adoptNode(const Node *source) throw (DOMException)
3004     return (Node *)source;
3007 /**
3008  *
3009  */
3010 DOMConfiguration *DocumentImpl::getDomConfig()
3012     return domConfig;
3015 /**
3016  *
3017  */
3018 void DocumentImpl::normalizeDocument()
3020     //i assume that this means adjusting namespaces & prefixes
3021     if (documentElement)
3022         documentElement->normalizeNamespaces();
3025 /**
3026  *
3027  */
3028 Node *DocumentImpl::renameNode(const Node *n,
3029                                const DOMString &namespaceURI,
3030                                const DOMString &qualifiedName)
3031                                throw (DOMException)
3033     Node *node = (Node *) n;
3034     NodeImpl *nodeImpl = dynamic_cast<NodeImpl *> (node);
3035     //nodeImpl->namespaceURI = stringCache(namespaceURI);
3036     nodeImpl->setNodeName(qualifiedName);
3037     return node;
3042 //##################
3043 //# Non-API methods
3044 //##################
3046 /**
3047  *
3048  */
3049 DocumentImpl::DocumentImpl(const DOMImplementation *domImpl,
3050                  const DOMString &theNamespaceURI,
3051                  const DOMString &theQualifiedName,
3052                  const DocumentType *theDoctype) : NodeImpl()
3054     nodeType        = DOCUMENT_NODE;
3055     nodeName        = "#document";
3056     parent          = (DOMImplementation *)domImpl;
3057     //documentURI     = stringCache(theNamespaceURI);
3058     qualifiedName   = theQualifiedName;
3059     if (theDoctype) //only assign if not null.
3060         doctype     = (DocumentType *)theDoctype;
3061     else
3062         doctype     = new DocumentTypeImpl("", "", "");
3063     documentElement = new ElementImpl(this, "root");
3064     namespaceIndex  = 0;
3068 /**
3069  *
3070  */
3071 DocumentImpl::~DocumentImpl()
3073     delete documentElement;
3087 }  //namespace dom
3088 }  //namespace w3c
3089 }  //namespace org
3093 /*#########################################################################
3094 ## E N D    O F    F I L E
3095 #########################################################################*/