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()
114 {
115 }
117 /**
118 *
119 */
120 DOMImplementationImpl::~DOMImplementationImpl()
121 {
122 }
124 /**
125 *
126 */
127 bool DOMImplementationImpl::hasFeature(const DOMString& feature,
128 const DOMString& version)
129 {
130 return false;
131 }
134 /**
135 *
136 */
137 DocumentType *DOMImplementationImpl::createDocumentType(const DOMString& qualifiedName,
138 const DOMString& publicId,
139 const DOMString& systemId)
140 throw(DOMException)
141 {
142 DocumentTypeImpl *typeImpl = new DocumentTypeImpl(qualifiedName,
143 publicId, systemId);
144 return typeImpl;
145 }
147 /**
148 *
149 */
150 Document *DOMImplementationImpl::createDocument(
151 const DOMString& namespaceURI,
152 const DOMString& qualifiedName,
153 DocumentType *doctype)
154 throw(DOMException)
155 {
156 DocumentImpl *doc = new DocumentImpl(this,
157 namespaceURI,
158 qualifiedName,
159 doctype);
160 return doc;
161 }
163 /**
164 *
165 */
166 DOMObject *DOMImplementationImpl::getFeature(const DOMString& feature,
167 const DOMString& version)
169 {
170 return NULL;
171 }
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)
186 {
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;
198 }
200 /**
201 *
202 */
203 DOMString NodeImpl::getNodeName()
204 {
205 return nodeName;
206 }
208 /**
209 *
210 */
211 DOMString NodeImpl::getNodeValue() throw (DOMException)
212 {
213 return nodeValue;
214 }
216 /**
217 *
218 */
219 void NodeImpl::setNodeValue(const DOMString& val) throw (DOMException)
220 {
221 nodeValue = val;
222 }
224 /**
225 *
226 */
227 unsigned short NodeImpl::getNodeType()
228 {
229 return nodeType;
230 }
232 /**
233 *
234 */
235 Node *NodeImpl::getParentNode()
236 {
237 return parent;
238 }
240 /**
241 *
242 */
243 NodeList NodeImpl::getChildNodes()
244 {
245 NodeList list;
246 for (NodeImpl *node = firstChild ; node ; node=node->next)
247 list.add(node);
248 return list;
249 }
251 /**
252 *
253 */
254 Node *NodeImpl::getFirstChild()
255 {
256 return firstChild;
257 }
259 /**
260 *
261 */
262 Node *NodeImpl::getLastChild()
263 {
264 return lastChild;
265 }
267 /**
268 *
269 */
270 Node *NodeImpl::getPreviousSibling()
271 {
272 return prev;
273 }
275 /**
276 *
277 */
278 Node *NodeImpl::getNextSibling()
279 {
280 return next;
281 }
283 /**
284 *
285 */
286 NamedNodeMap &NodeImpl::getAttributes()
287 {
288 NamedNodeMap &attrs = attributes;
289 return attrs;
290 }
293 /**
294 *
295 */
296 Document *NodeImpl::getOwnerDocument()
297 {
298 return ownerDocument;
299 }
301 /**
302 *
303 */
304 Node *NodeImpl::insertBefore(const Node *newChild,
305 const Node *refChild)
306 throw(DOMException)
307 {
308 Node *node = NULL;
309 return node;
310 }
312 /**
313 *
314 */
315 Node *NodeImpl::replaceChild(const Node *newChild,
316 const Node *oldChild)
317 throw(DOMException)
318 {
319 Node *node = NULL;
320 return node;
321 }
323 /**
324 *
325 */
326 Node *NodeImpl::removeChild(const Node *oldChild)
327 throw(DOMException)
328 {
329 Node *node = NULL;
330 return node;
331 }
333 /**
334 *
335 */
336 Node *NodeImpl::appendChild(const Node *newChild)
337 throw(DOMException)
338 {
339 if (!newChild)
340 return NULL;
342 Node *child = (Node *)newChild;
343 NodeImpl *childImpl = dynamic_cast<NodeImpl *> (child);
345 childImpl->parent = this;
346 childImpl->ownerDocument = ownerDocument;
348 if (!firstChild || !lastChild)
349 {
350 //Set up our first member
351 firstChild = childImpl;
352 lastChild = childImpl;
353 }
354 else
355 {
356 //link at the last position
357 lastChild->next = childImpl;
358 childImpl->prev = lastChild;
359 lastChild = childImpl;
360 }
362 return child;
363 }
365 /**
366 *
367 */
368 bool NodeImpl::hasChildNodes()
369 {
370 return (firstChild != NULL);
371 }
373 /**
374 *
375 */
376 Node *NodeImpl::cloneNode(bool deep)
377 {
378 NodeImpl *node = new NodeImpl(ownerDocument, nodeName);
379 node->parent = parent;
380 node->prev = prev;
381 node->next = next;
382 node->userData = userData;
383 node->nodeValue = nodeValue;
385 if (deep)
386 {
387 node->firstChild = node->lastChild = NULL;
388 for (NodeImpl *child = firstChild ; child ; child=child->next)
389 {
390 node->appendChild(child->cloneNode(deep));
391 }
392 }
393 else
394 {
395 node->firstChild = firstChild;
396 node->lastChild = lastChild;
397 }
399 return node;
400 }
402 /**
403 * Concatenate adjoining text subnodes, remove null-length nodes
404 */
405 void NodeImpl::normalize()
406 {
407 //First, concatenate adjoining text nodes
408 NodeImpl *next = NULL;
409 for (NodeImpl *child = firstChild ; child ; child=next)
410 {
411 if (child->getNodeType() != Node::TEXT_NODE)
412 continue;
413 next = NULL;
414 DOMString sval = child->getNodeValue();
415 for (NodeImpl *sibling = child->next ; sibling ; sibling=next)
416 {
417 next = sibling->next;
418 if (sibling->getNodeType() != Node::TEXT_NODE)
419 break;
420 sval.append(sibling->getNodeValue());
421 //unlink and delete
422 child->next = sibling->next;
423 if (sibling->next)
424 sibling->next->prev = child;
425 delete sibling;
426 }
427 child->setNodeValue(sval);
428 }
430 //Next, we remove zero-length text subnodes
431 next = NULL;
432 for (NodeImpl *child = firstChild ; child ; child=next)
433 {
434 next = child->next;
435 if (child->getNodeType() != Node::TEXT_NODE)
436 continue;
437 if (child->getNodeValue().size() == 0)
438 {
439 //unlink and delete
440 if (child->prev)
441 child->prev->next = child->next;
442 if (child->next)
443 child->next->prev = child->prev;
444 delete child;
445 }
446 }
448 }
450 /**
451 *
452 */
453 bool NodeImpl::isSupported(const DOMString& feature,
454 const DOMString& version)
455 {
456 //again, no idea
457 return false;
458 }
460 /**
461 *
462 */
463 DOMString NodeImpl::getNamespaceURI()
464 {
465 return namespaceURI;
466 }
468 /**
469 *
470 */
471 DOMString NodeImpl::getPrefix()
472 {
473 return prefix;
474 }
476 /**
477 *
478 */
479 void NodeImpl::setPrefix(const DOMString& val) throw(DOMException)
480 {
481 prefix = val;
482 if (prefix.size()>0)
483 nodeName = prefix + ":" + localName;
484 else
485 nodeName = localName;
486 }
488 /**
489 *
490 */
491 DOMString NodeImpl::getLocalName()
492 {
493 return localName;
494 }
496 /**
497 *
498 */
499 bool NodeImpl::hasAttributes()
500 {
501 return (attributes.getLength() > 0);
502 }
504 /**
505 *
506 */
507 DOMString NodeImpl::getBaseURI()
508 {
509 return baseURI;
510 }
512 /**
513 *
514 */
515 unsigned short NodeImpl::compareDocumentPosition(const Node *otherArg)
516 {
517 if (!otherArg || this == otherArg)
518 return 0;//no flags
520 Node *node;
521 Node *other = (Node *)otherArg;
523 //Look above me
524 for (node=getParentNode() ; node ; node=node->getParentNode())
525 if (node == other)
526 return DOCUMENT_POSITION_CONTAINED_BY;
528 //Look above the other guy. See me?
529 for (node=other->getParentNode() ; node ; node=node->getParentNode())
530 if (node == this)
531 return DOCUMENT_POSITION_CONTAINS;
534 return DOCUMENT_POSITION_DISCONNECTED |
535 DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
536 }
538 /**
539 *
540 */
541 DOMString NodeImpl::getTextContext() throw(DOMException)
542 {
543 //no idea
544 return DOMString("");
545 }
548 /**
549 *
550 */
551 void NodeImpl::setTextContext(const DOMString &val) throw(DOMException)
552 {
553 //no idea
554 }
557 /**
558 * From DOM3 Namespace algorithms
559 */
560 DOMString NodeImpl::lookupPrefix(const DOMString &theNamespaceURI)
561 {
563 if (theNamespaceURI.size()==0)
564 {
565 return DOMString("");
566 }
568 switch (nodeType)
569 {
570 case Node::ELEMENT_NODE:
571 {
572 ElementImpl *elem = (ElementImpl *)this;
573 return lookupNamespacePrefix(theNamespaceURI, elem);
574 }
575 case Node::DOCUMENT_NODE:
576 {
577 Document *doc = (Document *)this;
578 Element *elem = doc->getDocumentElement();
579 return elem->lookupPrefix(theNamespaceURI);
580 }
581 case Node::ENTITY_NODE :
582 case Node::NOTATION_NODE:
583 case Node::DOCUMENT_FRAGMENT_NODE:
584 case Node::DOCUMENT_TYPE_NODE:
585 return DOMString(""); // type is unknown
586 case Node::ATTRIBUTE_NODE:
587 {
588 Attr *attr = (Attr *)this;
589 Element *elem = (Element *)attr->getOwnerElement();
590 if ( elem )
591 {
592 return elem->lookupPrefix(theNamespaceURI);
593 }
594 return DOMString("");
595 }
596 default:
597 {
598 //Get ancestor element, if any
599 if ( Node *ancestor = getAncestorElement(this) )
600 {
601 return ancestor->lookupPrefix(theNamespaceURI);
602 }
603 return DOMString("");
604 }
605 }//switch
606 return DOMString("");
607 }
610 /**
611 *
612 */
613 bool NodeImpl::isDefaultNamespace(const DOMString &theNamespaceURI)
614 {
615 switch (nodeType)
616 {
617 case ELEMENT_NODE:
618 if ( namespaceURI.size()>0 && prefix.size()==0 )
619 {
620 return (namespaceURI == theNamespaceURI);
621 }
622 if ( Node *attr = attributes.getNamedItem("xmlns"))
623 {
624 return (attr->getNodeValue() == theNamespaceURI);
625 }
628 if ( Node *ancestor = getAncestorElement(this) )
629 {
630 return ancestor->isDefaultNamespace(theNamespaceURI);
631 }
632 else
633 {
634 return false;
635 }
636 case DOCUMENT_NODE:
637 { //just use braces for local declaration
638 Document *doc = (Document *)this;
639 Element *elem = doc->getDocumentElement();
640 return elem->isDefaultNamespace(theNamespaceURI);
641 }
642 case ENTITY_NODE:
643 case NOTATION_NODE:
644 case DOCUMENT_TYPE_NODE:
645 case DOCUMENT_FRAGMENT_NODE:
646 return false;
647 case ATTRIBUTE_NODE:
648 {//braces only for scope
649 Attr *attr = (Attr *)this;
650 Element *ownerElement = attr->getOwnerElement();
651 if ( ownerElement )
652 {
653 return ownerElement->isDefaultNamespace(theNamespaceURI);
654 }
655 else
656 {
657 return false;
658 }
659 }
660 default:
661 if ( Node *ancestor = getAncestorElement(this) )
662 {
663 return ancestor->isDefaultNamespace(theNamespaceURI);
664 }
665 else
666 {
667 return false;
668 }
669 }//switch
671 return false;
672 }
675 /**
676 *
677 */
678 DOMString NodeImpl::lookupNamespaceURI(const DOMString &thePrefix)
679 {
680 switch (nodeType)
681 {
682 case ELEMENT_NODE:
683 {
684 if ( namespaceURI.size()>0 && prefix == thePrefix )
685 {
686 DOMString nsURI = namespaceURI;
687 return (nsURI);
688 }
689 if ( hasAttributes() )
690 {
691 NamedNodeMap attributes = getAttributes();
692 int nrAttrs = attributes.getLength();
693 for (int i=0 ; i<nrAttrs ; i++)
694 {
695 Node *attr = attributes.item(i);
696 if (attr->getPrefix() == "xmlns" && attr->getLocalName() == thePrefix )
697 { // non default namespace
698 if (attr->getNodeValue().size()>0)
699 {
700 return (attr->getNodeValue());
701 }
702 return DOMString("");
703 }
704 else if (attr->getLocalName() == "xmlns" && thePrefix.size()==0)
705 { // default namespace
706 if (attr->getNodeValue().size()>0)
707 {
708 return (attr->getNodeValue());
709 }
710 return DOMString("");
711 }
712 }
713 }
715 if ( Node *ancestor = getAncestorElement(this) )
716 {
717 return ancestor->lookupNamespaceURI(thePrefix);
718 }
719 return DOMString("");
720 }
721 case DOCUMENT_NODE:
722 {
723 Document *doc = (Document *)this;
724 Element *elem = doc->getDocumentElement();
725 return elem->lookupNamespaceURI(thePrefix);
726 }
727 case ENTITY_NODE:
728 case NOTATION_NODE:
729 case DOCUMENT_TYPE_NODE:
730 case DOCUMENT_FRAGMENT_NODE:
731 return DOMString("");
733 case ATTRIBUTE_NODE:
734 {
735 if (Element *ownerElement = ((Attr *)this)->getOwnerElement())
736 {
737 return ownerElement->lookupNamespaceURI(thePrefix);
738 }
739 else
740 {
741 return DOMString("");
742 }
743 }
744 default:
745 if ( Node *ancestor = getAncestorElement(this) )
746 {
747 return ancestor->lookupNamespaceURI(thePrefix);
748 }
749 else
750 {
751 return DOMString("");
752 }
753 }//switch
754 }
757 /**
758 *
759 */
760 bool NodeImpl::isEqualNode(const Node *nodeArg)
761 {
762 if (!nodeArg)
763 return false;
765 if (this == nodeArg)
766 return true;
768 Node *node = (Node *)nodeArg;
770 if (getNodeType() != node->getNodeType() ||
771 getNodeName() != node->getNodeName() ||
772 getLocalName() != node->getLocalName() ||
773 getNamespaceURI() != node->getNamespaceURI() ||
774 getPrefix() != node->getPrefix() ||
775 getNodeValue() != node->getNodeValue() ||
776 getBaseURI() != node->getBaseURI() )
777 return false;
779 return true;
780 }
784 /**
785 *
786 */
787 DOMObject *NodeImpl::getFeature(const DOMString &feature,
788 const DOMString &version)
789 {
790 //dont know
791 return NULL;
792 }
794 /**
795 *
796 */
797 DOMUserData *NodeImpl::setUserData(const DOMString &key,
798 const DOMUserData *data,
799 const UserDataHandler *handler)
800 {
801 UserDataEntry *entry = userDataEntries;
802 UserDataEntry *prev = NULL;
803 while (entry)
804 {
805 if (entry->key == key)
806 {
807 DOMUserData *oldData = entry->data;
808 entry->data = (DOMUserData *)data;
809 entry->handler = (UserDataHandler *)handler;
810 return oldData;
811 }
812 prev = entry;
813 entry = entry->next;
814 }
816 //Make a new one
817 UserDataEntry *newEntry = new UserDataEntry(key, data, handler);
818 if (!prev)
819 userDataEntries = newEntry;
820 else
821 prev->next = newEntry;
823 return NULL;
824 }
826 /**
827 *
828 */
829 DOMUserData *NodeImpl::getUserData(const DOMString &key)
830 {
831 UserDataEntry *entry = userDataEntries;
832 while (entry)
833 {
834 if (entry->key == key)
835 return entry->data;
836 entry = entry->next;
837 }
838 return NULL;
839 }
843 //##################
844 //# Non-API methods
845 //##################
847 /**
848 *
849 */
850 void NodeImpl::setNodeName(const DOMString &qualifiedName)
851 {
852 nodeName = qualifiedName;
853 prefix = "";
854 localName = "";
855 for (unsigned int i=0 ; i<qualifiedName.size() ; i++)
856 {
857 int ch = qualifiedName[i];
858 if (ch == ':')
859 {
860 prefix = localName;
861 localName = "";
862 }
863 else
864 {
865 localName.push_back((XMLCh)ch);
866 }
867 }
868 }
870 /**
871 *
872 */
873 void NodeImpl::setNamespaceURI(const DOMString &theNamespaceURI)
874 {
875 namespaceURI = theNamespaceURI;
876 }
879 /**
880 * From DOM3 Namespace algorithms
881 */
882 DOMString NodeImpl::lookupNamespacePrefix(const DOMString &theNamespaceURI,
883 Node *originalElement)
884 {
885 if (!originalElement)
886 return DOMString("");
888 if ( namespaceURI.size()>0 && namespaceURI==theNamespaceURI &&
889 prefix.size()>0 &&
890 originalElement->lookupNamespaceURI(prefix) == theNamespaceURI)
891 {
892 return (prefix);
893 }
895 if ( hasAttributes() )
896 {
897 NamedNodeMap attributes = getAttributes();
898 int nrAttrs = attributes.getLength();
899 for (int i=0 ; i<nrAttrs ; i++)
900 {
901 Node *attr = attributes.item(i);
902 DOMString attrLocalName = attr->getLocalName();
903 if (attr->getPrefix() == "xmlns" &&
904 attr->getNodeValue() == theNamespaceURI &&
905 originalElement->lookupNamespaceURI(attrLocalName)
906 == theNamespaceURI)
907 {
908 return (attrLocalName);
909 }
910 }
911 }
913 //Get ancestor element, if any
914 NodeImpl *ancestor = parent;
915 while (ancestor && ancestor->getNodeType()!= Node::ELEMENT_NODE)
916 ancestor = ancestor->parent;
918 if ( ancestor )
919 {
920 return ancestor->lookupNamespacePrefix(theNamespaceURI, originalElement);
921 }
923 return DOMString("");
924 }
927 /**
928 *
929 */
930 NodeImpl::NodeImpl() : Node()
931 {
932 init();
933 }
936 /**
937 *
938 */
939 NodeImpl::NodeImpl(const NodeImpl &other) : Node()
940 {
941 init();
942 assign(other);
943 }
945 /**
946 *
947 */
948 NodeImpl &NodeImpl::operator=(const NodeImpl &other)
949 {
950 init();
951 assign(other);
952 return *this;
953 }
956 /**
957 *
958 */
959 NodeImpl::NodeImpl(DocumentImpl *owner)
960 {
961 init();
962 ownerDocument = owner;
963 }
965 /**
966 *
967 */
968 NodeImpl::NodeImpl(DocumentImpl *owner, const DOMString &nodeName)
969 {
970 init();
971 ownerDocument = owner;
972 setNodeName(nodeName);
973 }
975 /**
976 *
977 */
978 NodeImpl::NodeImpl(DocumentImpl *owner, const DOMString &theNamespaceURI,
979 const DOMString &qualifiedName)
980 {
981 init();
982 ownerDocument = owner;
983 //if (owner)
984 // namespaceURI = owner->stringCache(theNamespaceURI);
985 setNodeName(qualifiedName);
986 }
990 /**
991 *
992 */
993 void NodeImpl::init()
994 {
995 nodeType = 0; //none yet
996 nodeValue = "";
997 setNodeName("");
998 namespaceURI = "";
999 parent = NULL;
1000 prev = NULL;
1001 next = NULL;
1002 userData = NULL;
1003 firstChild = NULL;
1004 lastChild = NULL;
1005 ownerDocument = NULL;
1006 userDataEntries = NULL;
1007 }
1009 /**
1010 *
1011 */
1012 void NodeImpl::assign(const NodeImpl &other)
1013 {
1014 ownerDocument = other.ownerDocument;
1015 prefix = other.prefix;
1016 localName = other.localName;
1017 nodeName = other.nodeName;
1018 nodeValue = other.nodeValue;
1019 namespaceURI = other.namespaceURI;
1020 attributes = other.attributes;
1021 }
1024 /**
1025 *
1026 */
1027 NodeImpl::~NodeImpl()
1028 {
1029 if (userDataEntries)
1030 delete userDataEntries;
1031 }
1035 /*#########################################################################
1036 ## CharacterDataImpl
1037 #########################################################################*/
1040 /**
1041 *
1042 */
1043 CharacterDataImpl::CharacterDataImpl() : NodeImpl()
1044 {
1045 }
1047 /**
1048 *
1049 */
1050 CharacterDataImpl::CharacterDataImpl(DocumentImpl *owner,
1051 const DOMString &theValue) : NodeImpl()
1052 {
1053 ownerDocument = owner;
1054 nodeValue = theValue;
1055 }
1057 /**
1058 *
1059 */
1060 CharacterDataImpl::~CharacterDataImpl()
1061 {
1062 }
1064 /**
1065 *
1066 */
1067 DOMString CharacterDataImpl::getData() throw(DOMException)
1068 {
1069 return nodeValue;
1070 }
1072 /**
1073 *
1074 */
1075 void CharacterDataImpl::setData(const DOMString& val) throw(DOMException)
1076 {
1077 nodeValue = val;
1078 }
1080 /**
1081 *
1082 */
1083 unsigned long CharacterDataImpl::getLength()
1084 {
1085 return nodeValue.size();
1086 }
1088 /**
1089 *
1090 */
1091 DOMString CharacterDataImpl::substringData(unsigned long offset,
1092 unsigned long count)
1093 throw(DOMException)
1094 {
1095 return nodeValue.substr(offset, count);
1096 }
1098 /**
1099 *
1100 */
1101 void CharacterDataImpl::appendData(const DOMString& arg) throw(DOMException)
1102 {
1103 nodeValue += arg;
1104 }
1106 /**
1107 *
1108 */
1109 void CharacterDataImpl::insertData(unsigned long offset,
1110 const DOMString& arg)
1111 throw(DOMException)
1112 {
1113 nodeValue.insert(offset, arg);
1114 }
1116 /**
1117 *
1118 */
1119 void CharacterDataImpl::deleteData(unsigned long offset,
1120 unsigned long count)
1121 throw(DOMException)
1122 {
1123 nodeValue.erase(offset, count);
1124 }
1126 /**
1127 *
1128 */
1129 void CharacterDataImpl::replaceData(unsigned long offset,
1130 unsigned long count,
1131 const DOMString& arg)
1132 throw(DOMException)
1133 {
1134 nodeValue.replace(offset, count, arg);
1135 }
1142 /*#########################################################################
1143 ## AttrImpl
1144 #########################################################################*/
1146 /**
1147 *
1148 */
1149 DOMString AttrImpl::getName()
1150 {
1151 return nodeName;
1152 }
1154 /**
1155 *
1156 */
1157 bool AttrImpl::getSpecified()
1158 {
1159 return (nodeValue.size() > 0);
1160 }
1162 /**
1163 *
1164 */
1165 DOMString AttrImpl::getValue()
1166 {
1167 return nodeValue;
1168 }
1170 /**
1171 *
1172 */
1173 void AttrImpl::setValue(const DOMString& val) throw(DOMException)
1174 {
1175 nodeValue = val;
1176 }
1178 /**
1179 *
1180 */
1181 Element *AttrImpl::getOwnerElement()
1182 {
1183 return ownerElement;
1184 }
1187 /**
1188 *
1189 */
1190 TypeInfo *AttrImpl::getSchemaTypeInfo()
1191 {
1192 return NULL;
1193 }
1196 /**
1197 *
1198 */
1199 bool AttrImpl::getIsId()
1200 {
1201 return (nodeName == "id");
1202 }
1206 //##################
1207 //# Non-API methods
1208 //##################
1211 void AttrImpl::setOwnerElement(const Element *elem)
1212 {
1213 ownerElement = (Element *)elem;
1214 }
1216 /**
1217 *
1218 */
1219 AttrImpl::AttrImpl(DocumentImpl *owner, const DOMString &theName)
1220 : NodeImpl()
1221 {
1222 nodeType = ATTRIBUTE_NODE;
1223 ownerDocument = owner;
1224 setNodeName(theName);
1225 }
1227 /**
1228 *
1229 */
1230 AttrImpl::AttrImpl(DocumentImpl *owner,
1231 const DOMString &theNamespaceURI,
1232 const DOMString &theQualifiedName)
1233 : NodeImpl()
1234 {
1235 nodeType = ATTRIBUTE_NODE;
1236 ownerDocument = owner;
1237 //if (owner)
1238 // namespaceURI = owner->stringCache(theNamespaceURI);
1239 setNodeName(theQualifiedName);
1240 }
1242 /**
1243 *
1244 */
1245 AttrImpl::~AttrImpl()
1246 {
1247 }
1253 /*#########################################################################
1254 ## ElementImpl
1255 #########################################################################*/
1258 /**
1259 *
1260 */
1261 DOMString ElementImpl::getTagName()
1262 {
1263 if (prefix.size() > 0)
1264 return prefix + ":" + nodeName;
1265 else
1266 return nodeName;
1267 }
1269 /**
1270 *
1271 */
1272 DOMString ElementImpl::getAttribute(const DOMString& name)
1273 {
1274 Node *node = attributes.getNamedItem(name);
1275 if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1276 return DOMString("");
1277 Attr *attr = dynamic_cast<Attr *>(node);
1278 return attr->getValue();
1279 }
1281 /**
1282 *
1283 */
1284 void ElementImpl::setAttribute(const DOMString& name,
1285 const DOMString& value)
1286 throw(DOMException)
1287 {
1288 AttrImpl *attr = new AttrImpl(ownerDocument, name);
1289 attr->setValue(value);
1290 attr->setOwnerElement(this);
1291 attributes.setNamedItem(attr);
1292 }
1294 /**
1295 *
1296 */
1297 void ElementImpl::removeAttribute(const DOMString& name)
1298 throw(DOMException)
1299 {
1300 attributes.removeNamedItem(name);
1301 }
1303 /**
1304 *
1305 */
1306 Attr *ElementImpl::getAttributeNode(const DOMString& name)
1307 {
1308 Node *node = attributes.getNamedItem(name);
1309 if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1310 return NULL;
1311 Attr *attr = dynamic_cast<Attr *>(node);
1312 return attr;
1313 }
1315 /**
1316 *
1317 */
1318 Attr *ElementImpl::setAttributeNode(Attr *attr)
1319 throw(DOMException)
1320 {
1321 attributes.setNamedItem(attr);
1322 return attr;
1323 }
1325 /**
1326 *
1327 */
1328 Attr *ElementImpl::removeAttributeNode(Attr *attr)
1329 throw(DOMException)
1330 {
1331 if (!attr)
1332 return NULL;
1333 attributes.removeNamedItem(attr->getName());
1334 return attr;
1335 }
1338 /**
1339 *
1340 */
1341 void ElementImpl::getElementsByTagNameRecursive(NodeList &list,
1342 const DOMString& name, Element *elem)
1343 {
1344 if (!elem)
1345 return;
1347 if (name == elem->getTagName())
1348 list.add(elem);
1349 for (Node *node = elem->getFirstChild() ; node ; node=node->getNextSibling())
1350 {
1351 if (node->getNodeType() != Node::ELEMENT_NODE)
1352 continue;
1353 Element *childElem = dynamic_cast<Element *>(node);
1354 getElementsByTagNameRecursive(list, name, childElem);
1355 }
1356 }
1359 /**
1360 *
1361 */
1362 NodeList ElementImpl::getElementsByTagName(const DOMString& tagName)
1363 {
1364 NodeList list;
1365 getElementsByTagNameRecursive(list, tagName, this);
1366 return list;
1367 }
1369 /**
1370 *
1371 */
1372 DOMString ElementImpl::getAttributeNS(const DOMString& namespaceURI,
1373 const DOMString& localName)
1374 {
1375 Node *node = attributes.getNamedItemNS(namespaceURI, localName);
1376 if (!node || node->getNodeType()!=ATTRIBUTE_NODE)
1377 return DOMString("");
1378 Attr *attr = dynamic_cast<Attr *>(node);
1379 return attr->getValue();
1380 }
1382 /**
1383 *
1384 */
1385 void ElementImpl::setAttributeNS(const DOMString& namespaceURI,
1386 const DOMString& qualifiedName,
1387 const DOMString& value)
1388 throw(DOMException)
1389 {
1390 AttrImpl *attr = new AttrImpl(ownerDocument, namespaceURI, qualifiedName);
1391 attr->setValue(value);
1392 attr->setOwnerElement(this);
1393 attributes.setNamedItemNS(attr);
1394 }
1396 /**
1397 *
1398 */
1399 void ElementImpl::removeAttributeNS(const DOMString& namespaceURI,
1400 const DOMString& localName)
1401 throw(DOMException)
1402 {
1403 attributes.removeNamedItemNS(namespaceURI, localName);
1404 }
1406 /**
1407 *
1408 */
1409 Attr *ElementImpl::getAttributeNodeNS(const DOMString& namespaceURI,
1410 const DOMString& localName)
1411 {
1412 Node *node = attributes.getNamedItemNS(namespaceURI, localName);
1413 if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1414 return NULL;
1415 Attr *attr = dynamic_cast<Attr *>(node);
1416 return attr;
1417 }
1419 /**
1420 *
1421 */
1422 Attr *ElementImpl::setAttributeNodeNS(Attr *attr)
1423 throw(DOMException)
1424 {
1425 attributes.setNamedItemNS(attr);
1426 return attr;
1427 }
1430 /**
1431 *
1432 */
1433 void ElementImpl::getElementsByTagNameNSRecursive(NodeList &list,
1434 const DOMString& namespaceURI, const DOMString& tagName, Element *elem)
1435 {
1436 if (!elem)
1437 return;
1439 if (namespaceURI == elem->getNamespaceURI() && tagName == elem->getTagName())
1440 list.add(elem);
1441 for (Node *node = elem->getFirstChild() ; node ; node=node->getNextSibling())
1442 {
1443 if (node->getNodeType() != Node::ELEMENT_NODE)
1444 continue;
1445 Element *childElem = dynamic_cast<Element *>(node);
1446 getElementsByTagNameNSRecursive(list, namespaceURI, tagName, childElem);
1447 }
1448 }
1450 /**
1451 *
1452 */
1453 NodeList ElementImpl::getElementsByTagNameNS(const DOMString& namespaceURI,
1454 const DOMString& localName)
1455 {
1456 NodeList list;
1457 getElementsByTagNameNSRecursive(list, namespaceURI, localName, this);
1458 return list;
1459 }
1461 /**
1462 *
1463 */
1464 bool ElementImpl::hasAttribute(const DOMString& attrName)
1465 {
1466 Node *node = attributes.getNamedItem(attrName);
1467 if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1468 return false;
1469 return true;
1470 }
1472 /**
1473 *
1474 */
1475 bool ElementImpl::hasAttributeNS(const DOMString& namespaceURI,
1476 const DOMString& localName)
1477 {
1478 Node *node = attributes.getNamedItemNS(namespaceURI, localName);
1479 if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1480 return false;
1481 return true;
1482 }
1484 /**
1485 *
1486 */
1487 TypeInfo *ElementImpl::getSchemaTypeInto()
1488 {
1489 //fixme
1490 return NULL;
1491 }
1494 /**
1495 *
1496 */
1497 void ElementImpl::setIdAttribute(const DOMString &name,
1498 bool isId) throw (DOMException)
1499 {
1500 //fixme
1501 }
1503 /**
1504 *
1505 */
1506 void ElementImpl::setIdAttributeNS(const DOMString &namespaceURI,
1507 const DOMString &localName,
1508 bool isId) throw (DOMException)
1509 {
1510 //fixme
1511 }
1513 /**
1514 *
1515 */
1516 void ElementImpl::setIdAttributeNode(const Attr *idAttr,
1517 bool isId) throw (DOMException)
1518 {
1519 //fixme
1520 }
1523 //##################
1524 //# Non-API methods
1525 //##################
1528 /**
1529 *
1530 */
1531 ElementImpl::ElementImpl() : NodeImpl()
1532 {
1533 nodeType = ELEMENT_NODE;
1534 }
1536 /**
1537 *
1538 */
1539 ElementImpl::ElementImpl(DocumentImpl *owner, const DOMString &tagName)
1540 : NodeImpl()
1541 {
1542 nodeType = ELEMENT_NODE;
1543 ownerDocument = owner;
1544 setNodeName(tagName);
1545 }
1547 /**
1548 *
1549 */
1550 ElementImpl::ElementImpl(DocumentImpl *owner,
1551 const DOMString &theNamespaceURI,
1552 const DOMString &qualifiedName) :
1553 NodeImpl()
1554 {
1555 nodeType = ELEMENT_NODE;
1556 ownerDocument = owner;
1557 setNodeName(qualifiedName);
1558 }
1560 /**
1561 *
1562 */
1563 ElementImpl::~ElementImpl()
1564 {
1565 }
1568 /**
1569 *
1570 */
1571 void ElementImpl::normalizeNamespaces()
1572 {
1573 //printf("### NORMALIZE\n");
1575 NamedNodeMap attrs = getAttributes();
1577 //#######################################
1578 //# Pick up local namespace declarations
1579 //#######################################
1580 bindingsClear(); //Reset bindings on this node
1582 int nrAttrs = attrs.getLength();
1583 for (int i=0; i<nrAttrs ; i++)
1584 {
1585 Node *attrNode = attrs.item(i);
1586 if (attrNode->getNodeType() != Node::ATTRIBUTE_NODE)
1587 continue;
1588 AttrImpl *attr = dynamic_cast<AttrImpl *>(attrNode);
1589 DOMString attrNS = attr->getNamespaceURI();
1590 DOMString attrName = attr->getLocalName();
1591 DOMString attrPrefix = attr->getPrefix();
1592 DOMString attrValue = attr->getNodeValue();
1593 if (attrName != "xmlns" && attrPrefix != "xmlns")
1594 continue;
1596 //is the namespace declaration is invalid?
1597 if (attrValue == XMLNSNAME || attrName == attrPrefix)
1598 {
1599 // Note: The prefix xmlns is used only to declare namespace bindings and
1600 // is by definition bound to the namespace name http://www.w3.org/2000/xmlns/.
1601 // It must not be declared. No other prefix may be bound to this namespace name.
1603 //==> Report an error.
1604 printf("normalizeNamespaces() error: Namespace %s cannot be reassigned\n",
1605 XMLNSNAME);
1607 }
1608 else
1609 {
1610 //==> Record the namespace declaration
1611 attr->setNamespaceURI(XMLNSNAME);
1612 if (attrPrefix.size() > 0)
1613 bindingsAdd(attrPrefix, attrValue);
1614 else
1615 bindingsAdd("*", attrValue);//default
1617 }
1618 }
1621 //#######################################
1622 //# Fixup element's namespace
1623 //#######################################
1624 if ( namespaceURI.size() > 0 )
1625 {
1626 DOMString key = prefix;
1627 if (key.size() == 0)
1628 key = "*";
1629 DOMString binding = bindingsFind(key);
1630 //Element's prefix/namespace pair (or default namespace, if no prefix)
1631 // are within the scope of a binding
1632 if ( binding == namespaceURI )
1633 {
1634 //==> do nothing, declaration in scope is inherited
1636 // See section "B.1.1: Scope of a binding" for an example
1638 }
1639 else
1640 {
1642 /*
1643 ==> Create a local namespace declaration attr for this namespace,
1644 with Element's current prefix (or a default namespace, if
1645 no prefix). If there's a conflicting local declaration
1646 already present, change its value to use this namespace.
1648 See section "B.1.2: Conflicting namespace declaration" for an example
1649 */
1650 DOMString attrName = "xmlns";
1651 if (prefix.size() > 0)
1652 {
1653 attrName.append(":");
1654 attrName.append(prefix);
1655 }
1656 setAttribute(attrName, namespaceURI);
1657 // NOTE that this may break other nodes within this Element's
1658 // subtree, if they're already using this prefix.
1659 // They will be repaired when we reach them.
1660 }
1661 }
1662 else // Element has no namespace URI:
1663 {
1664 //###############################################
1665 //# Bob -- alter this from the specs a bit.
1666 //# Since the XmlReader does not set namespaces,
1667 //# do it here
1668 //###############################################
1669 DOMString localName = getLocalName();
1670 if ( localName.size()==0 )
1671 {
1672 // DOM Level 1 node
1673 /*
1674 ==> if in process of validation against a namespace aware schema
1675 (i.e XML Schema) report a fatal error: the processor can not recover
1676 in this situation.
1677 Otherwise, report an error: no namespace fixup will be performed on this node.
1678 */
1679 printf("normalizeNamespaces() error: no localName\n");
1680 }
1681 else
1682 {
1683 // Element has no pseudo-prefix
1684 //there's a conflicting local default namespace declaration already present
1685 if ( prefix.size()==0 )
1686 {
1687 //==> change its value to use this empty namespace.
1688 namespaceURI = bindingsFind("*");
1689 //setAttribute("xmlns", "");
1690 }
1691 else //#BOB . I added this.
1692 {
1693 namespaceURI = bindingsFind(prefix);
1694 }
1695 // NOTE that this may break other nodes within this Element's
1696 // subtree, if they're already using the default namespaces.
1697 // They will be repaired when we reach them.
1698 }
1699 }
1702 //#######################################
1703 //# Examine and polish the attributes
1704 //#######################################
1705 nrAttrs = attrs.getLength();
1706 for (int i=0; i<nrAttrs ; i++)// all non-namespace Attrs of Element
1707 {
1708 Node *attrNode = attrs.item(i);
1709 if (attrNode->getNodeType() != Node::ATTRIBUTE_NODE)
1710 continue;
1711 Attr *attr = dynamic_cast<Attr *>(attrNode);
1712 DOMString attrNS = attr->getNamespaceURI();
1713 DOMString attrPrefix = attr->getPrefix();
1714 DOMString attrValue = attr->getNodeValue();
1715 if (attrNS == XMLNSNAME)
1716 continue;
1718 if ( attrNS.size()>0 ) //Attr[i] has a namespace URI
1719 {
1720 DOMString attrBinding = bindingsFind(attrPrefix);
1721 /*
1722 if attribute has no prefix (default namespace decl does not apply to attributes)
1723 OR
1724 attribute prefix is not declared
1725 OR
1726 conflict: attribute has a prefix that conflicts with a binding
1727 already active in scope
1728 */
1729 if ( attrPrefix.size() == 0 || attrBinding.size() == 0)
1730 {
1731 //namespaceURI matches an in scope declaration of one or more prefixes)
1732 DOMString prefixForNS = lookupNamespacePrefix(attrNS, this);
1733 if ( prefixForNS.size() > 0 )
1734 {
1735 // pick the most local binding available;
1736 // if there is more than one pick one arbitrarily
1738 //==> change attribute's prefix.
1739 attr->setPrefix(prefixForNS);
1740 }
1741 else
1742 {
1743 // the current prefix is not null and it has no in scope declaration)
1744 if ( attrPrefix.size() > 0 || attrBinding.size() == 0 )
1745 {
1746 //==> declare this prefix
1747 DOMString newAttrName = "xmlns:";
1748 newAttrName.append(attrPrefix);
1749 setAttribute(newAttrName, attrNS);
1750 bindingsAdd(attrPrefix, attrNS);
1751 }
1752 else
1753 {
1754 // find a prefix following the pattern "NS" +index (starting at 1)
1755 // make sure this prefix is not declared in the current scope.
1756 // create a local namespace declaration attribute
1758 //==> declare this prefix
1759 char buf[16];
1760 sprintf(buf, "%d" , ownerDocument->namespaceIndex++);
1761 DOMString newPrefix = "NS";
1762 newPrefix.append(buf);
1763 DOMString newAttrName = "xmlns:";
1764 newAttrName.append(newPrefix);
1765 setAttribute(newAttrName, attrNS);
1766 bindingsAdd(newPrefix, attrNS);
1767 //==> change attribute's prefix.
1768 }
1769 }
1770 }
1771 }
1772 else // Attr has no namespace URI
1773 {
1774 // Attr has no localName
1775 if ( attr->getLocalName().size() == 0 )
1776 {
1777 // DOM Level 1 node
1778 /*
1779 ==> if in process of validation against a namespace aware schema
1780 (i.e XML Schema) report a fatal error: the processor can not recover
1781 in this situation.
1782 Otherwise, report an error: no namespace fixup will be performed on this node.
1783 */
1784 printf("normalizeNamespaces: no local name for attribute\n");
1785 }
1786 else
1787 {
1788 // attr has no namespace URI and no prefix
1789 // no action is required, since attrs don't use default
1790 //==> do nothing
1791 }
1792 }
1793 } // end for-all-Attrs
1796 //#######################################
1797 //# Recursively normalize children
1798 //#######################################
1799 for (Node *child=getFirstChild() ; child ; child=child->getNextSibling())
1800 {
1801 if (child->getNodeType() != Node::ELEMENT_NODE)
1802 continue;
1803 ElementImpl *childElement = dynamic_cast<ElementImpl *>(child);
1804 childElement->normalizeNamespaces();
1805 }
1807 }
1810 /*#########################################################################
1811 ## TextImpl
1812 #########################################################################*/
1815 /**
1816 *
1817 */
1818 TextImpl::TextImpl() : CharacterDataImpl()
1819 {
1820 nodeType = TEXT_NODE;
1821 nodeName = "#text";
1822 }
1825 /**
1826 *
1827 */
1828 TextImpl::TextImpl(DocumentImpl *owner, const DOMString &value)
1829 : CharacterDataImpl()
1830 {
1831 nodeType = TEXT_NODE;
1832 nodeName = "#text";
1833 ownerDocument = owner;
1834 nodeValue = value;
1835 }
1838 /**
1839 *
1840 */
1841 TextImpl::~TextImpl()
1842 {
1843 }
1845 /**
1846 *
1847 */
1848 Text *TextImpl::splitText(unsigned long offset)
1849 throw(DOMException)
1850 {
1851 return NULL;
1852 }
1854 /**
1855 *
1856 */
1857 bool TextImpl::getIsElementContentWhitespace()
1858 {
1859 return false;
1860 }
1862 /**
1863 *
1864 */
1865 DOMString TextImpl::getWholeText()
1866 {
1867 return nodeValue;
1868 }
1871 /**
1872 *
1873 */
1874 Text *TextImpl::replaceWholeText(const DOMString &content)
1875 throw(DOMException)
1876 {
1877 return NULL;
1878 }
1881 /*#########################################################################
1882 ## CommentImpl
1883 #########################################################################*/
1885 /**
1886 *
1887 */
1888 CommentImpl::CommentImpl() : CharacterDataImpl()
1889 {
1890 nodeType = COMMENT_NODE;
1891 nodeName = "#comment";
1892 }
1895 /**
1896 *
1897 */
1898 CommentImpl::CommentImpl(DocumentImpl *owner, const DOMString &value)
1899 : CharacterDataImpl()
1900 {
1901 nodeType = COMMENT_NODE;
1902 nodeName = "#comment";
1903 ownerDocument = owner;
1904 nodeValue = value;
1905 }
1908 /**
1909 *
1910 */
1911 CommentImpl::~CommentImpl()
1912 {
1913 }
1918 /*#########################################################################
1919 ## TypeInfoImpl
1920 #########################################################################*/
1923 /**
1924 *
1925 */
1926 TypeInfoImpl::TypeInfoImpl(const DOMString &typeNamespaceArg,
1927 const DOMString &typeNameArg,
1928 const DerivationMethod derivationMethodArg)
1929 {
1930 typeNamespace = typeNamespaceArg;
1931 typeName = typeNameArg;
1932 derivationMethod = derivationMethodArg;
1933 }
1936 /**
1937 *
1938 */
1939 TypeInfoImpl::~TypeInfoImpl()
1940 {
1941 }
1944 /**
1945 *
1946 */
1947 DOMString TypeInfoImpl::getTypeName()
1948 {
1949 return typeName;
1950 }
1952 /**
1953 *
1954 */
1955 DOMString TypeInfoImpl::getTypeNamespace()
1956 {
1957 return typeNamespace;
1958 }
1960 /**
1961 *
1962 */
1963 bool TypeInfoImpl::isDerivedFrom(const DOMString &typeNamespaceArg,
1964 const DOMString &typeNameArg,
1965 const DerivationMethod derivationMethodArg)
1966 {
1967 if (typeNamespaceArg == typeNamespace &&
1968 typeName == typeNameArg &&
1969 derivationMethod == derivationMethodArg)
1970 return true;
1971 return false;
1972 }
1976 /*#########################################################################
1977 ## UserDataHandlerImpl
1978 #########################################################################*/
1982 /**
1983 *
1984 */
1985 UserDataHandlerImpl::UserDataHandlerImpl()
1986 {
1987 }
1990 /**
1991 *
1992 */
1993 UserDataHandlerImpl::~UserDataHandlerImpl()
1994 {
1995 }
1997 /**
1998 *
1999 */
2000 void UserDataHandlerImpl::handle(unsigned short operation,
2001 const DOMString &key,
2002 const DOMUserData *data,
2003 const Node *src,
2004 const Node *dst)
2005 {
2006 //do nothing. do we need anything here?
2007 }
2011 /*#########################################################################
2012 ## DOMErrorImpl
2013 #########################################################################*/
2017 /**
2018 *
2019 */
2020 DOMErrorImpl::DOMErrorImpl()
2021 {
2022 }
2025 /**
2026 *
2027 */
2028 DOMErrorImpl::~DOMErrorImpl()
2029 {
2030 }
2032 /**
2033 *
2034 */
2035 unsigned short DOMErrorImpl::getSeverity()
2036 {
2037 return severity;
2038 }
2040 /**
2041 *
2042 */
2043 DOMString DOMErrorImpl::getMessage()
2044 {
2045 return message;
2046 }
2048 /**
2049 *
2050 */
2051 DOMString DOMErrorImpl::getType()
2052 {
2053 return type;
2054 }
2056 /**
2057 *
2058 */
2059 DOMObject *DOMErrorImpl::getRelatedException()
2060 {
2061 return NULL;
2062 }
2064 /**
2065 *
2066 */
2067 DOMObject *DOMErrorImpl::getRelatedData()
2068 {
2069 return NULL;
2070 }
2072 /**
2073 *
2074 */
2075 DOMLocator *DOMErrorImpl::getLocation()
2076 {
2077 //really should fill this in
2078 return NULL;
2079 }
2084 /*#########################################################################
2085 ## DOMErrorHandlerImpl
2086 #########################################################################*/
2090 /**
2091 *
2092 */
2093 DOMErrorHandlerImpl::DOMErrorHandlerImpl()
2094 {
2095 }
2098 /**
2099 *
2100 */
2101 DOMErrorHandlerImpl::~DOMErrorHandlerImpl()
2102 {
2103 }
2105 /**
2106 *
2107 */
2108 bool DOMErrorHandlerImpl::handleError(const DOMError *error)
2109 {
2110 if (!error)
2111 return false;
2112 return true;
2113 }
2118 /*#########################################################################
2119 ## DOMLocatorImpl
2120 #########################################################################*/
2123 /**
2124 *
2125 */
2126 DOMLocatorImpl::DOMLocatorImpl()
2127 {
2128 }
2131 /**
2132 *
2133 */
2134 DOMLocatorImpl::~DOMLocatorImpl()
2135 {
2136 }
2139 /**
2140 *
2141 */
2142 long DOMLocatorImpl::getLineNumber()
2143 {
2144 return lineNumber;
2145 }
2147 /**
2148 *
2149 */
2150 long DOMLocatorImpl::getColumnNumber()
2151 {
2152 return columnNumber;
2153 }
2155 /**
2156 *
2157 */
2158 long DOMLocatorImpl::getByteOffset()
2159 {
2160 return byteOffset;
2161 }
2163 /**
2164 *
2165 */
2166 long DOMLocatorImpl::getUtf16Offset()
2167 {
2168 return utf16Offset;
2169 }
2172 /**
2173 *
2174 */
2175 Node *DOMLocatorImpl::getRelatedNode()
2176 {
2177 return relatedNode;
2178 }
2181 /**
2182 *
2183 */
2184 DOMString DOMLocatorImpl::getUri()
2185 {
2186 return uri;
2187 }
2191 /*#########################################################################
2192 ## DOMConfigurationImpl
2193 #########################################################################*/
2196 /**
2197 *
2198 */
2199 DOMConfigurationImpl::DOMConfigurationImpl()
2200 {
2201 }
2204 /**
2205 *
2206 */
2207 DOMConfigurationImpl::~DOMConfigurationImpl()
2208 {
2209 }
2211 /**
2212 *
2213 */
2214 void DOMConfigurationImpl::setParameter(const DOMString &name,
2215 const DOMUserData *value) throw (DOMException)
2216 {
2217 }
2219 /**
2220 *
2221 */
2222 DOMUserData *DOMConfigurationImpl::getParameter(const DOMString &name)
2223 throw (DOMException)
2224 {
2225 return NULL;
2226 }
2228 /**
2229 *
2230 */
2231 bool DOMConfigurationImpl::canSetParameter(const DOMString &name,
2232 const DOMUserData *data)
2233 {
2234 return false;
2235 }
2237 /**
2238 *
2239 */
2240 DOMStringList *DOMConfigurationImpl::getParameterNames()
2241 {
2242 return NULL;
2243 }
2247 /*#########################################################################
2248 ## CDATASectionImpl
2249 #########################################################################*/
2251 /**
2252 *
2253 */
2254 CDATASectionImpl::CDATASectionImpl() : TextImpl()
2255 {
2256 nodeType = CDATA_SECTION_NODE;
2257 nodeName = "#cdata-section";
2258 }
2260 /**
2261 *
2262 */
2263 CDATASectionImpl::CDATASectionImpl(DocumentImpl *owner, const DOMString &theValue)
2264 : TextImpl()
2265 {
2266 nodeType = CDATA_SECTION_NODE;
2267 nodeName = "#cdata-section";
2268 ownerDocument = owner;
2269 nodeValue = theValue;
2270 }
2273 /**
2274 *
2275 */
2276 CDATASectionImpl::~CDATASectionImpl()
2277 {
2278 }
2284 /*#########################################################################
2285 ## DocumentTypeImpl
2286 #########################################################################*/
2288 /**
2289 *
2290 */
2291 DocumentTypeImpl::DocumentTypeImpl(const DOMString& theName,
2292 const DOMString& thePublicId,
2293 const DOMString& theSystemId)
2294 : NodeImpl()
2295 {
2296 nodeType = DOCUMENT_TYPE_NODE;
2297 nodeName = theName;
2298 publicId = thePublicId;
2299 systemId = theSystemId;
2300 }
2302 /**
2303 *
2304 */
2305 DocumentTypeImpl::~DocumentTypeImpl()
2306 {
2307 }
2309 /**
2310 *
2311 */
2312 DOMString DocumentTypeImpl::getName()
2313 {
2314 return nodeName;
2315 }
2317 /**
2318 *
2319 */
2320 NamedNodeMap DocumentTypeImpl::getEntities()
2321 {
2322 return entities;
2323 }
2325 /**
2326 *
2327 */
2328 NamedNodeMap DocumentTypeImpl::getNotations()
2329 {
2330 return notations;
2331 }
2333 /**
2334 *
2335 */
2336 DOMString DocumentTypeImpl::getPublicId()
2337 {
2338 return publicId;
2339 }
2341 /**
2342 *
2343 */
2344 DOMString DocumentTypeImpl::getSystemId()
2345 {
2346 return systemId;
2347 }
2349 /**
2350 *
2351 */
2352 DOMString DocumentTypeImpl::getInternalSubset()
2353 {
2354 return DOMString("");
2355 }
2362 /*#########################################################################
2363 ## NotationImpl
2364 #########################################################################*/
2368 /**
2369 *
2370 */
2371 NotationImpl::NotationImpl(DocumentImpl *owner) : NodeImpl()
2372 {
2373 nodeType = NOTATION_NODE;
2374 ownerDocument = owner;
2375 }
2378 /**
2379 *
2380 */
2381 NotationImpl::~NotationImpl()
2382 {
2383 }
2385 /**
2386 *
2387 */
2388 DOMString NotationImpl::getPublicId()
2389 {
2390 return publicId;
2391 }
2393 /**
2394 *
2395 */
2396 DOMString NotationImpl::getSystemId()
2397 {
2398 return systemId;
2399 }
2408 /*#########################################################################
2409 ## EntityImpl
2410 #########################################################################*/
2413 /**
2414 *
2415 */
2416 EntityImpl::EntityImpl() : NodeImpl()
2417 {
2418 nodeType = ENTITY_NODE;
2419 }
2422 /**
2423 *
2424 */
2425 EntityImpl::EntityImpl(DocumentImpl *owner) : NodeImpl()
2426 {
2427 nodeType = ENTITY_NODE;
2428 ownerDocument = owner;
2429 }
2432 /**
2433 *
2434 */
2435 EntityImpl::~EntityImpl()
2436 {
2437 }
2439 /**
2440 *
2441 */
2442 DOMString EntityImpl::getPublicId()
2443 {
2444 return publicId;
2445 }
2447 /**
2448 *
2449 */
2450 DOMString EntityImpl::getSystemId()
2451 {
2452 return systemId;
2453 }
2455 /**
2456 *
2457 */
2458 DOMString EntityImpl::getNotationName()
2459 {
2460 return notationName;
2461 }
2463 /**
2464 *
2465 */
2466 DOMString EntityImpl::getInputEncoding()
2467 {
2468 return inputEncoding;
2469 }
2471 /**
2472 *
2473 */
2474 DOMString EntityImpl::getXmlEncoding()
2475 {
2476 return xmlEncoding;
2477 }
2479 /**
2480 *
2481 */
2482 DOMString EntityImpl::getXmlVersion()
2483 {
2484 return xmlVersion;
2485 }
2492 /*#########################################################################
2493 ## EntityReferenceImpl
2494 #########################################################################*/
2498 /**
2499 *
2500 */
2501 EntityReferenceImpl::EntityReferenceImpl() : NodeImpl()
2502 {
2503 nodeType = ENTITY_REFERENCE_NODE;
2504 }
2507 /**
2508 *
2509 */
2510 EntityReferenceImpl::EntityReferenceImpl(DocumentImpl *owner,
2511 const DOMString &theName)
2512 : NodeImpl()
2513 {
2514 nodeType = ENTITY_REFERENCE_NODE;
2515 nodeName = theName;
2516 ownerDocument = owner;
2517 }
2520 /**
2521 *
2522 */
2523 EntityReferenceImpl::~EntityReferenceImpl()
2524 {
2525 }
2529 /*#########################################################################
2530 ## ProcessingInstructionImpl
2531 #########################################################################*/
2536 /**
2537 *
2538 */
2539 ProcessingInstructionImpl::ProcessingInstructionImpl(): NodeImpl()
2540 {
2541 nodeType = PROCESSING_INSTRUCTION_NODE;
2542 }
2546 /**
2547 *
2548 */
2549 ProcessingInstructionImpl::ProcessingInstructionImpl(DocumentImpl *owner,
2550 const DOMString &target,
2551 const DOMString &data)
2552 : NodeImpl()
2553 {
2554 nodeType = PROCESSING_INSTRUCTION_NODE;
2555 ownerDocument = owner;
2556 nodeName = target;
2557 nodeValue = data;
2558 }
2561 /**
2562 *
2563 */
2564 ProcessingInstructionImpl::~ProcessingInstructionImpl()
2565 {
2566 }
2571 /**
2572 *
2573 */
2574 DOMString ProcessingInstructionImpl::getTarget()
2575 {
2576 return nodeName;
2577 }
2579 /**
2580 *
2581 */
2582 DOMString ProcessingInstructionImpl::getData()
2583 {
2584 return nodeValue;
2585 }
2587 /**
2588 *
2589 */
2590 void ProcessingInstructionImpl::setData(const DOMString& val) throw(DOMException)
2591 {
2592 //do something here
2593 }
2601 /*#########################################################################
2602 ## DocumentFragmentImpl
2603 #########################################################################*/
2605 /**
2606 *
2607 */
2608 DocumentFragmentImpl::DocumentFragmentImpl() : NodeImpl()
2609 {
2610 nodeType = DOCUMENT_FRAGMENT_NODE;
2611 nodeName = "#document-fragment";
2612 }
2615 /**
2616 *
2617 */
2618 DocumentFragmentImpl::DocumentFragmentImpl(DocumentImpl *owner) : NodeImpl()
2619 {
2620 nodeType = DOCUMENT_FRAGMENT_NODE;
2621 nodeName = "#document-fragment";
2622 ownerDocument = owner;
2623 }
2626 /**
2627 *
2628 */
2629 DocumentFragmentImpl::~DocumentFragmentImpl()
2630 {
2631 }
2638 /*#########################################################################
2639 ## DocumentImpl
2640 #########################################################################*/
2644 /**
2645 *
2646 */
2647 DocumentType *DocumentImpl::getDoctype()
2648 {
2649 return doctype;
2650 }
2652 /**
2653 *
2654 */
2655 DOMImplementation *DocumentImpl::getImplementation()
2656 {
2657 return parent;
2658 }
2660 /**
2661 *
2662 */
2663 Element *DocumentImpl::getDocumentElement()
2664 {
2665 return documentElement;
2666 }
2668 /**
2669 *
2670 */
2671 Element *DocumentImpl::createElement(const DOMString& tagName)
2672 throw(DOMException)
2673 {
2674 ElementImpl *impl = new ElementImpl(this, tagName);
2675 return impl;
2676 }
2678 /**
2679 *
2680 */
2681 DocumentFragment *DocumentImpl::createDocumentFragment()
2682 {
2683 DocumentFragmentImpl *frag = new DocumentFragmentImpl(this);
2684 return frag;
2685 }
2687 /**
2688 *
2689 */
2690 Text *DocumentImpl::createTextNode(const DOMString& data)
2691 {
2692 TextImpl *text = new TextImpl(this, data);
2693 return text;
2694 }
2696 /**
2697 *
2698 */
2699 Comment *DocumentImpl::createComment(const DOMString& data)
2700 {
2701 CommentImpl *comment = new CommentImpl(this, data);
2702 return comment;
2703 }
2705 /**
2706 *
2707 */
2708 CDATASection *DocumentImpl::createCDATASection(const DOMString& data)
2709 throw(DOMException)
2710 {
2711 CDATASectionImpl *cdata = new CDATASectionImpl(this, data);
2712 return cdata;
2713 }
2715 /**
2716 *
2717 */
2718 ProcessingInstruction *DocumentImpl::createProcessingInstruction(const DOMString& target,
2719 const DOMString& data)
2720 throw(DOMException)
2721 {
2722 ProcessingInstructionImpl *cdata =
2723 new ProcessingInstructionImpl(this, target, data);
2724 return cdata;
2725 }
2727 /**
2728 *
2729 */
2730 Attr *DocumentImpl::createAttribute(const DOMString& attrName)
2731 throw(DOMException)
2732 {
2733 AttrImpl *attr = new AttrImpl(this, attrName);
2734 return attr;
2735 }
2737 /**
2738 *
2739 */
2740 EntityReference *DocumentImpl::createEntityReference(const DOMString& erName)
2741 throw(DOMException)
2742 {
2743 EntityReferenceImpl *ref = new EntityReferenceImpl(this, erName);
2744 return ref;
2745 }
2748 /**
2749 *
2750 */
2751 NodeList DocumentImpl::getElementsByTagName(const DOMString& tagname)
2752 {
2753 NodeList list;
2754 ElementImpl::getElementsByTagNameRecursive(list,
2755 tagname, documentElement);
2756 return list;
2757 }
2760 /**
2761 *
2762 */
2763 Node *DocumentImpl::importNode(const Node *importedNode,
2764 bool deep)
2765 throw(DOMException)
2766 {
2767 return NULL;
2768 }
2770 /**
2771 *
2772 */
2773 Element *DocumentImpl::createElementNS(const DOMString& namespaceURI,
2774 const DOMString& qualifiedName)
2775 throw(DOMException)
2776 {
2777 ElementImpl *elem = new ElementImpl(this, namespaceURI, qualifiedName);
2778 return elem;
2779 }
2781 /**
2782 *
2783 */
2784 Attr *DocumentImpl::createAttributeNS(const DOMString& namespaceURI,
2785 const DOMString& qualifiedName)
2786 throw(DOMException)
2787 {
2788 AttrImpl *attr = new AttrImpl(this, namespaceURI, qualifiedName);
2789 return attr;
2790 }
2793 /**
2794 *
2795 */
2796 NodeList DocumentImpl::getElementsByTagNameNS(const DOMString& namespaceURI,
2797 const DOMString& localName)
2798 {
2799 NodeList list;
2800 ElementImpl::getElementsByTagNameNSRecursive(list, namespaceURI,
2801 localName, documentElement);
2802 return list;
2803 }
2805 /**
2806 *
2807 */
2808 Element *DocumentImpl::getElementById(const DOMString& elementId)
2809 {
2810 for (NamedElementItem *entry = elementsById.next; entry ; entry=entry->next)
2811 if (entry->name == elementId)
2812 return entry->elem;
2813 return NULL;
2814 }
2817 /**
2818 *
2819 */
2820 DOMString DocumentImpl::getInputEncoding()
2821 {
2822 return inputEncoding;
2823 }
2826 /**
2827 *
2828 */
2829 DOMString DocumentImpl::getXmlEncoding()
2830 {
2831 return xmlEncoding;
2832 }
2834 /**
2835 *
2836 */
2837 bool DocumentImpl::getXmlStandalone()
2838 {
2839 return xmlStandalone;
2840 }
2842 /**
2843 *
2844 */
2845 void DocumentImpl::setXmlStandalone(bool val) throw (DOMException)
2846 {
2847 xmlStandalone = val;
2848 }
2850 /**
2851 *
2852 */
2853 DOMString DocumentImpl::getXmlVersion()
2854 {
2855 return xmlVersion;
2856 }
2858 /**
2859 *
2860 */
2861 void DocumentImpl::setXmlVersion(const DOMString &version) throw (DOMException)
2862 {
2863 xmlVersion = version;
2864 }
2866 /**
2867 *
2868 */
2869 bool DocumentImpl::getStrictErrorChecking()
2870 {
2871 return strictErrorChecking;
2872 }
2874 /**
2875 *
2876 */
2877 void DocumentImpl::setStrictErrorChecking(bool val)
2878 {
2879 strictErrorChecking = val;
2880 }
2883 /**
2884 *
2885 */
2886 DOMString DocumentImpl::getDocumentURI()
2887 {
2888 if (!documentURI)
2889 return DOMString("");
2890 DOMString docURI = *documentURI;
2891 return docURI;
2892 }
2894 /**
2895 *
2896 */
2897 void DocumentImpl::setDocumentURI(const DOMString &uri)
2898 {
2899 //documentURI = stringCache(uri);
2900 }
2902 /**
2903 *
2904 */
2905 Node *DocumentImpl::adoptNode(const Node *source) throw (DOMException)
2906 {
2907 return (Node *)source;
2908 }
2910 /**
2911 *
2912 */
2913 DOMConfiguration *DocumentImpl::getDomConfig()
2914 {
2915 return domConfig;
2916 }
2918 /**
2919 *
2920 */
2921 void DocumentImpl::normalizeDocument()
2922 {
2923 //i assume that this means adjusting namespaces & prefixes
2924 if (documentElement)
2925 documentElement->normalizeNamespaces();
2926 }
2928 /**
2929 *
2930 */
2931 Node *DocumentImpl::renameNode(const Node *n,
2932 const DOMString &namespaceURI,
2933 const DOMString &qualifiedName)
2934 throw (DOMException)
2935 {
2936 Node *node = (Node *) n;
2937 NodeImpl *nodeImpl = dynamic_cast<NodeImpl *> (node);
2938 //nodeImpl->namespaceURI = stringCache(namespaceURI);
2939 nodeImpl->setNodeName(qualifiedName);
2940 return node;
2941 }
2945 //##################
2946 //# Non-API methods
2947 //##################
2949 /**
2950 *
2951 */
2952 DocumentImpl::DocumentImpl(const DOMImplementation *domImpl,
2953 const DOMString &theNamespaceURI,
2954 const DOMString &theQualifiedName,
2955 const DocumentType *theDoctype) : NodeImpl()
2956 {
2957 nodeType = DOCUMENT_NODE;
2958 nodeName = "#document";
2959 parent = (DOMImplementation *)domImpl;
2960 //documentURI = stringCache(theNamespaceURI);
2961 qualifiedName = theQualifiedName;
2962 if (theDoctype) //only assign if not null.
2963 doctype = (DocumentType *)theDoctype;
2964 else
2965 doctype = new DocumentTypeImpl("", "", "");
2966 documentElement = new ElementImpl(this, "root");
2967 namespaceIndex = 0;
2968 }
2971 /**
2972 *
2973 */
2974 DocumentImpl::~DocumentImpl()
2975 {
2976 delete documentElement;
2977 }
2990 } //namespace dom
2991 } //namespace w3c
2992 } //namespace org
2996 /*#########################################################################
2997 ## E N D O F F I L E
2998 #########################################################################*/