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 if (!newChild)
309 return NULL;
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;
336 }
338 /**
339 *
340 */
341 Node *NodeImpl::replaceChild(const Node *newChild,
342 const Node *oldChild)
343 throw(DOMException)
344 {
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;
372 }
374 /**
375 *
376 */
377 Node *NodeImpl::removeChild(const Node *oldChild)
378 throw(DOMException)
379 {
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;
395 }
397 /**
398 *
399 */
400 Node *NodeImpl::appendChild(const Node *newChild)
401 throw(DOMException)
402 {
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;
427 }
429 /**
430 *
431 */
432 bool NodeImpl::hasChildNodes()
433 {
434 return (firstChild != NULL);
435 }
437 /**
438 *
439 */
440 Node *NodeImpl::cloneNode(bool deep)
441 {
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;
464 }
466 /**
467 * Concatenate adjoining text subnodes, remove null-length nodes
468 */
469 void NodeImpl::normalize()
470 {
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 }
512 }
514 /**
515 *
516 */
517 bool NodeImpl::isSupported(const DOMString& feature,
518 const DOMString& version)
519 {
520 //again, no idea
521 return false;
522 }
524 /**
525 *
526 */
527 DOMString NodeImpl::getNamespaceURI()
528 {
529 return namespaceURI;
530 }
532 /**
533 *
534 */
535 DOMString NodeImpl::getPrefix()
536 {
537 return prefix;
538 }
540 /**
541 *
542 */
543 void NodeImpl::setPrefix(const DOMString& val) throw(DOMException)
544 {
545 prefix = val;
546 if (prefix.size()>0)
547 nodeName = prefix + ":" + localName;
548 else
549 nodeName = localName;
550 }
552 /**
553 *
554 */
555 DOMString NodeImpl::getLocalName()
556 {
557 return localName;
558 }
560 /**
561 *
562 */
563 bool NodeImpl::hasAttributes()
564 {
565 return (attributes.getLength() > 0);
566 }
568 /**
569 *
570 */
571 DOMString NodeImpl::getBaseURI()
572 {
573 return baseURI;
574 }
576 /**
577 *
578 */
579 unsigned short NodeImpl::compareDocumentPosition(const Node *otherArg)
580 {
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;
600 }
602 /**
603 *
604 */
605 DOMString NodeImpl::getTextContent() throw(DOMException)
606 {
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;
628 }
631 /**
632 *
633 */
634 void NodeImpl::setTextContent(const DOMString &val) throw(DOMException)
635 {
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);
647 }
650 /**
651 * From DOM3 Namespace algorithms
652 */
653 DOMString NodeImpl::lookupPrefix(const DOMString &theNamespaceURI)
654 {
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("");
700 }
703 /**
704 *
705 */
706 bool NodeImpl::isDefaultNamespace(const DOMString &theNamespaceURI)
707 {
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;
765 }
768 /**
769 *
770 */
771 DOMString NodeImpl::lookupNamespaceURI(const DOMString &thePrefix)
772 {
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
847 }
850 /**
851 *
852 */
853 bool NodeImpl::isEqualNode(const Node *nodeArg)
854 {
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;
873 }
877 /**
878 *
879 */
880 DOMObject *NodeImpl::getFeature(const DOMString &feature,
881 const DOMString &version)
882 {
883 //dont know
884 return NULL;
885 }
887 /**
888 *
889 */
890 DOMUserData *NodeImpl::setUserData(const DOMString &key,
891 const DOMUserData *data,
892 const UserDataHandler *handler)
893 {
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;
917 }
919 /**
920 *
921 */
922 DOMUserData *NodeImpl::getUserData(const DOMString &key)
923 {
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;
932 }
936 //##################
937 //# Non-API methods
938 //##################
940 /**
941 *
942 */
943 void NodeImpl::setNodeName(const DOMString &qualifiedName)
944 {
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 }
961 }
963 /**
964 *
965 */
966 void NodeImpl::setNamespaceURI(const DOMString &theNamespaceURI)
967 {
968 namespaceURI = theNamespaceURI;
969 }
972 /**
973 * From DOM3 Namespace algorithms
974 */
975 DOMString NodeImpl::lookupNamespacePrefix(const DOMString &theNamespaceURI,
976 Node *originalElement)
977 {
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("");
1017 }
1020 /**
1021 *
1022 */
1023 NodeImpl::NodeImpl() : Node()
1024 {
1025 init();
1026 }
1029 /**
1030 *
1031 */
1032 NodeImpl::NodeImpl(const NodeImpl &other) : Node()
1033 {
1034 init();
1035 assign(other);
1036 }
1038 /**
1039 *
1040 */
1041 NodeImpl &NodeImpl::operator=(const NodeImpl &other)
1042 {
1043 init();
1044 assign(other);
1045 return *this;
1046 }
1049 /**
1050 *
1051 */
1052 NodeImpl::NodeImpl(DocumentImpl *owner)
1053 {
1054 init();
1055 ownerDocument = owner;
1056 }
1058 /**
1059 *
1060 */
1061 NodeImpl::NodeImpl(DocumentImpl *owner, const DOMString &nodeName)
1062 {
1063 init();
1064 ownerDocument = owner;
1065 setNodeName(nodeName);
1066 }
1068 /**
1069 *
1070 */
1071 NodeImpl::NodeImpl(DocumentImpl *owner, const DOMString &theNamespaceURI,
1072 const DOMString &qualifiedName)
1073 {
1074 init();
1075 ownerDocument = owner;
1076 //if (owner)
1077 // namespaceURI = owner->stringCache(theNamespaceURI);
1078 setNodeName(qualifiedName);
1079 }
1083 /**
1084 *
1085 */
1086 void NodeImpl::init()
1087 {
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;
1100 }
1102 /**
1103 *
1104 */
1105 void NodeImpl::assign(const NodeImpl &other)
1106 {
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;
1114 }
1117 /**
1118 *
1119 */
1120 NodeImpl::~NodeImpl()
1121 {
1122 if (userDataEntries)
1123 delete userDataEntries;
1124 //Delete children
1125 for (Node *n = getFirstChild() ; n ;
1126 n=n->getNextSibling() )
1127 delete n;
1128 }
1132 /*#########################################################################
1133 ## CharacterDataImpl
1134 #########################################################################*/
1137 /**
1138 *
1139 */
1140 CharacterDataImpl::CharacterDataImpl() : NodeImpl()
1141 {
1142 }
1144 /**
1145 *
1146 */
1147 CharacterDataImpl::CharacterDataImpl(DocumentImpl *owner,
1148 const DOMString &theValue) : NodeImpl()
1149 {
1150 ownerDocument = owner;
1151 nodeValue = theValue;
1152 }
1154 /**
1155 *
1156 */
1157 CharacterDataImpl::~CharacterDataImpl()
1158 {
1159 }
1161 /**
1162 *
1163 */
1164 DOMString CharacterDataImpl::getData() throw(DOMException)
1165 {
1166 return nodeValue;
1167 }
1169 /**
1170 *
1171 */
1172 void CharacterDataImpl::setData(const DOMString& val) throw(DOMException)
1173 {
1174 nodeValue = val;
1175 }
1177 /**
1178 *
1179 */
1180 unsigned long CharacterDataImpl::getLength()
1181 {
1182 return nodeValue.size();
1183 }
1185 /**
1186 *
1187 */
1188 DOMString CharacterDataImpl::substringData(unsigned long offset,
1189 unsigned long count)
1190 throw(DOMException)
1191 {
1192 return nodeValue.substr(offset, count);
1193 }
1195 /**
1196 *
1197 */
1198 void CharacterDataImpl::appendData(const DOMString& arg) throw(DOMException)
1199 {
1200 nodeValue += arg;
1201 }
1203 /**
1204 *
1205 */
1206 void CharacterDataImpl::insertData(unsigned long offset,
1207 const DOMString& arg)
1208 throw(DOMException)
1209 {
1210 nodeValue.insert(offset, arg);
1211 }
1213 /**
1214 *
1215 */
1216 void CharacterDataImpl::deleteData(unsigned long offset,
1217 unsigned long count)
1218 throw(DOMException)
1219 {
1220 nodeValue.erase(offset, count);
1221 }
1223 /**
1224 *
1225 */
1226 void CharacterDataImpl::replaceData(unsigned long offset,
1227 unsigned long count,
1228 const DOMString& arg)
1229 throw(DOMException)
1230 {
1231 nodeValue.replace(offset, count, arg);
1232 }
1239 /*#########################################################################
1240 ## AttrImpl
1241 #########################################################################*/
1243 /**
1244 *
1245 */
1246 DOMString AttrImpl::getName()
1247 {
1248 return nodeName;
1249 }
1251 /**
1252 *
1253 */
1254 bool AttrImpl::getSpecified()
1255 {
1256 return (nodeValue.size() > 0);
1257 }
1259 /**
1260 *
1261 */
1262 DOMString AttrImpl::getValue()
1263 {
1264 return nodeValue;
1265 }
1267 /**
1268 *
1269 */
1270 void AttrImpl::setValue(const DOMString& val) throw(DOMException)
1271 {
1272 nodeValue = val;
1273 }
1275 /**
1276 *
1277 */
1278 Element *AttrImpl::getOwnerElement()
1279 {
1280 return ownerElement;
1281 }
1284 /**
1285 *
1286 */
1287 TypeInfo *AttrImpl::getSchemaTypeInfo()
1288 {
1289 return NULL;
1290 }
1293 /**
1294 *
1295 */
1296 bool AttrImpl::getIsId()
1297 {
1298 return (nodeName == "id");
1299 }
1303 //##################
1304 //# Non-API methods
1305 //##################
1308 void AttrImpl::setOwnerElement(const Element *elem)
1309 {
1310 ownerElement = (Element *)elem;
1311 }
1313 /**
1314 *
1315 */
1316 AttrImpl::AttrImpl(DocumentImpl *owner, const DOMString &theName)
1317 : NodeImpl()
1318 {
1319 nodeType = ATTRIBUTE_NODE;
1320 ownerDocument = owner;
1321 setNodeName(theName);
1322 }
1324 /**
1325 *
1326 */
1327 AttrImpl::AttrImpl(DocumentImpl *owner,
1328 const DOMString &theNamespaceURI,
1329 const DOMString &theQualifiedName)
1330 : NodeImpl()
1331 {
1332 nodeType = ATTRIBUTE_NODE;
1333 ownerDocument = owner;
1334 //if (owner)
1335 // namespaceURI = owner->stringCache(theNamespaceURI);
1336 setNodeName(theQualifiedName);
1337 }
1339 /**
1340 *
1341 */
1342 AttrImpl::~AttrImpl()
1343 {
1344 }
1350 /*#########################################################################
1351 ## ElementImpl
1352 #########################################################################*/
1355 /**
1356 *
1357 */
1358 DOMString ElementImpl::getTagName()
1359 {
1360 if (prefix.size() > 0)
1361 return prefix + ":" + nodeName;
1362 else
1363 return nodeName;
1364 }
1366 /**
1367 *
1368 */
1369 DOMString ElementImpl::getAttribute(const DOMString& name)
1370 {
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();
1376 }
1378 /**
1379 *
1380 */
1381 void ElementImpl::setAttribute(const DOMString& name,
1382 const DOMString& value)
1383 throw(DOMException)
1384 {
1385 AttrImpl *attr = new AttrImpl(ownerDocument, name);
1386 attr->setValue(value);
1387 attr->setOwnerElement(this);
1388 attributes.setNamedItem(attr);
1389 }
1391 /**
1392 *
1393 */
1394 void ElementImpl::removeAttribute(const DOMString& name)
1395 throw(DOMException)
1396 {
1397 attributes.removeNamedItem(name);
1398 }
1400 /**
1401 *
1402 */
1403 Attr *ElementImpl::getAttributeNode(const DOMString& name)
1404 {
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;
1410 }
1412 /**
1413 *
1414 */
1415 Attr *ElementImpl::setAttributeNode(Attr *attr)
1416 throw(DOMException)
1417 {
1418 attributes.setNamedItem(attr);
1419 return attr;
1420 }
1422 /**
1423 *
1424 */
1425 Attr *ElementImpl::removeAttributeNode(Attr *attr)
1426 throw(DOMException)
1427 {
1428 if (!attr)
1429 return NULL;
1430 attributes.removeNamedItem(attr->getName());
1431 return attr;
1432 }
1435 /**
1436 *
1437 */
1438 void ElementImpl::getElementsByTagNameRecursive(NodeList &list,
1439 const DOMString& name, Element *elem)
1440 {
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 }
1453 }
1456 /**
1457 *
1458 */
1459 NodeList ElementImpl::getElementsByTagName(const DOMString& tagName)
1460 {
1461 NodeList list;
1462 getElementsByTagNameRecursive(list, tagName, this);
1463 return list;
1464 }
1466 /**
1467 *
1468 */
1469 DOMString ElementImpl::getAttributeNS(const DOMString& namespaceURI,
1470 const DOMString& localName)
1471 {
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();
1477 }
1479 /**
1480 *
1481 */
1482 void ElementImpl::setAttributeNS(const DOMString& namespaceURI,
1483 const DOMString& qualifiedName,
1484 const DOMString& value)
1485 throw(DOMException)
1486 {
1487 AttrImpl *attr = new AttrImpl(ownerDocument, namespaceURI, qualifiedName);
1488 attr->setValue(value);
1489 attr->setOwnerElement(this);
1490 attributes.setNamedItemNS(attr);
1491 }
1493 /**
1494 *
1495 */
1496 void ElementImpl::removeAttributeNS(const DOMString& namespaceURI,
1497 const DOMString& localName)
1498 throw(DOMException)
1499 {
1500 attributes.removeNamedItemNS(namespaceURI, localName);
1501 }
1503 /**
1504 *
1505 */
1506 Attr *ElementImpl::getAttributeNodeNS(const DOMString& namespaceURI,
1507 const DOMString& localName)
1508 {
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;
1514 }
1516 /**
1517 *
1518 */
1519 Attr *ElementImpl::setAttributeNodeNS(Attr *attr)
1520 throw(DOMException)
1521 {
1522 attributes.setNamedItemNS(attr);
1523 return attr;
1524 }
1527 /**
1528 *
1529 */
1530 void ElementImpl::getElementsByTagNameNSRecursive(NodeList &list,
1531 const DOMString& namespaceURI, const DOMString& tagName, Element *elem)
1532 {
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 }
1545 }
1547 /**
1548 *
1549 */
1550 NodeList ElementImpl::getElementsByTagNameNS(const DOMString& namespaceURI,
1551 const DOMString& localName)
1552 {
1553 NodeList list;
1554 getElementsByTagNameNSRecursive(list, namespaceURI, localName, this);
1555 return list;
1556 }
1558 /**
1559 *
1560 */
1561 bool ElementImpl::hasAttribute(const DOMString& attrName)
1562 {
1563 Node *node = attributes.getNamedItem(attrName);
1564 if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1565 return false;
1566 return true;
1567 }
1569 /**
1570 *
1571 */
1572 bool ElementImpl::hasAttributeNS(const DOMString& namespaceURI,
1573 const DOMString& localName)
1574 {
1575 Node *node = attributes.getNamedItemNS(namespaceURI, localName);
1576 if (!node || node->getNodeType() != ATTRIBUTE_NODE)
1577 return false;
1578 return true;
1579 }
1581 /**
1582 *
1583 */
1584 TypeInfo *ElementImpl::getSchemaTypeInto()
1585 {
1586 //fixme
1587 return NULL;
1588 }
1591 /**
1592 *
1593 */
1594 void ElementImpl::setIdAttribute(const DOMString &name,
1595 bool isId) throw (DOMException)
1596 {
1597 //fixme
1598 }
1600 /**
1601 *
1602 */
1603 void ElementImpl::setIdAttributeNS(const DOMString &namespaceURI,
1604 const DOMString &localName,
1605 bool isId) throw (DOMException)
1606 {
1607 //fixme
1608 }
1610 /**
1611 *
1612 */
1613 void ElementImpl::setIdAttributeNode(const Attr *idAttr,
1614 bool isId) throw (DOMException)
1615 {
1616 //fixme
1617 }
1620 //##################
1621 //# Non-API methods
1622 //##################
1625 /**
1626 *
1627 */
1628 ElementImpl::ElementImpl() : NodeImpl()
1629 {
1630 nodeType = ELEMENT_NODE;
1631 }
1633 /**
1634 *
1635 */
1636 ElementImpl::ElementImpl(DocumentImpl *owner, const DOMString &tagName)
1637 : NodeImpl()
1638 {
1639 nodeType = ELEMENT_NODE;
1640 ownerDocument = owner;
1641 setNodeName(tagName);
1642 }
1644 /**
1645 *
1646 */
1647 ElementImpl::ElementImpl(DocumentImpl *owner,
1648 const DOMString &theNamespaceURI,
1649 const DOMString &qualifiedName) :
1650 NodeImpl()
1651 {
1652 nodeType = ELEMENT_NODE;
1653 ownerDocument = owner;
1654 setNodeName(qualifiedName);
1655 }
1657 /**
1658 *
1659 */
1660 ElementImpl::~ElementImpl()
1661 {
1662 }
1665 /**
1666 *
1667 */
1668 void ElementImpl::normalizeNamespaces()
1669 {
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 }
1904 }
1907 /*#########################################################################
1908 ## TextImpl
1909 #########################################################################*/
1912 /**
1913 *
1914 */
1915 TextImpl::TextImpl() : CharacterDataImpl()
1916 {
1917 nodeType = TEXT_NODE;
1918 nodeName = "#text";
1919 }
1922 /**
1923 *
1924 */
1925 TextImpl::TextImpl(DocumentImpl *owner, const DOMString &value)
1926 : CharacterDataImpl()
1927 {
1928 nodeType = TEXT_NODE;
1929 nodeName = "#text";
1930 ownerDocument = owner;
1931 nodeValue = value;
1932 }
1935 /**
1936 *
1937 */
1938 TextImpl::~TextImpl()
1939 {
1940 }
1942 /**
1943 *
1944 */
1945 Text *TextImpl::splitText(unsigned long offset)
1946 throw(DOMException)
1947 {
1948 return NULL;
1949 }
1951 /**
1952 *
1953 */
1954 bool TextImpl::getIsElementContentWhitespace()
1955 {
1956 return false;
1957 }
1959 /**
1960 *
1961 */
1962 DOMString TextImpl::getWholeText()
1963 {
1964 return nodeValue;
1965 }
1968 /**
1969 *
1970 */
1971 Text *TextImpl::replaceWholeText(const DOMString &content)
1972 throw(DOMException)
1973 {
1974 return NULL;
1975 }
1978 /*#########################################################################
1979 ## CommentImpl
1980 #########################################################################*/
1982 /**
1983 *
1984 */
1985 CommentImpl::CommentImpl() : CharacterDataImpl()
1986 {
1987 nodeType = COMMENT_NODE;
1988 nodeName = "#comment";
1989 }
1992 /**
1993 *
1994 */
1995 CommentImpl::CommentImpl(DocumentImpl *owner, const DOMString &value)
1996 : CharacterDataImpl()
1997 {
1998 nodeType = COMMENT_NODE;
1999 nodeName = "#comment";
2000 ownerDocument = owner;
2001 nodeValue = value;
2002 }
2005 /**
2006 *
2007 */
2008 CommentImpl::~CommentImpl()
2009 {
2010 }
2015 /*#########################################################################
2016 ## TypeInfoImpl
2017 #########################################################################*/
2020 /**
2021 *
2022 */
2023 TypeInfoImpl::TypeInfoImpl(const DOMString &typeNamespaceArg,
2024 const DOMString &typeNameArg,
2025 const DerivationMethod derivationMethodArg)
2026 {
2027 typeNamespace = typeNamespaceArg;
2028 typeName = typeNameArg;
2029 derivationMethod = derivationMethodArg;
2030 }
2033 /**
2034 *
2035 */
2036 TypeInfoImpl::~TypeInfoImpl()
2037 {
2038 }
2041 /**
2042 *
2043 */
2044 DOMString TypeInfoImpl::getTypeName()
2045 {
2046 return typeName;
2047 }
2049 /**
2050 *
2051 */
2052 DOMString TypeInfoImpl::getTypeNamespace()
2053 {
2054 return typeNamespace;
2055 }
2057 /**
2058 *
2059 */
2060 bool TypeInfoImpl::isDerivedFrom(const DOMString &typeNamespaceArg,
2061 const DOMString &typeNameArg,
2062 const DerivationMethod derivationMethodArg)
2063 {
2064 if (typeNamespaceArg == typeNamespace &&
2065 typeName == typeNameArg &&
2066 derivationMethod == derivationMethodArg)
2067 return true;
2068 return false;
2069 }
2073 /*#########################################################################
2074 ## UserDataHandlerImpl
2075 #########################################################################*/
2079 /**
2080 *
2081 */
2082 UserDataHandlerImpl::UserDataHandlerImpl()
2083 {
2084 }
2087 /**
2088 *
2089 */
2090 UserDataHandlerImpl::~UserDataHandlerImpl()
2091 {
2092 }
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)
2102 {
2103 //do nothing. do we need anything here?
2104 }
2108 /*#########################################################################
2109 ## DOMErrorImpl
2110 #########################################################################*/
2114 /**
2115 *
2116 */
2117 DOMErrorImpl::DOMErrorImpl()
2118 {
2119 }
2122 /**
2123 *
2124 */
2125 DOMErrorImpl::~DOMErrorImpl()
2126 {
2127 }
2129 /**
2130 *
2131 */
2132 unsigned short DOMErrorImpl::getSeverity()
2133 {
2134 return severity;
2135 }
2137 /**
2138 *
2139 */
2140 DOMString DOMErrorImpl::getMessage()
2141 {
2142 return message;
2143 }
2145 /**
2146 *
2147 */
2148 DOMString DOMErrorImpl::getType()
2149 {
2150 return type;
2151 }
2153 /**
2154 *
2155 */
2156 DOMObject *DOMErrorImpl::getRelatedException()
2157 {
2158 return NULL;
2159 }
2161 /**
2162 *
2163 */
2164 DOMObject *DOMErrorImpl::getRelatedData()
2165 {
2166 return NULL;
2167 }
2169 /**
2170 *
2171 */
2172 DOMLocator *DOMErrorImpl::getLocation()
2173 {
2174 //really should fill this in
2175 return NULL;
2176 }
2181 /*#########################################################################
2182 ## DOMErrorHandlerImpl
2183 #########################################################################*/
2187 /**
2188 *
2189 */
2190 DOMErrorHandlerImpl::DOMErrorHandlerImpl()
2191 {
2192 }
2195 /**
2196 *
2197 */
2198 DOMErrorHandlerImpl::~DOMErrorHandlerImpl()
2199 {
2200 }
2202 /**
2203 *
2204 */
2205 bool DOMErrorHandlerImpl::handleError(const DOMError *error)
2206 {
2207 if (!error)
2208 return false;
2209 return true;
2210 }
2215 /*#########################################################################
2216 ## DOMLocatorImpl
2217 #########################################################################*/
2220 /**
2221 *
2222 */
2223 DOMLocatorImpl::DOMLocatorImpl()
2224 {
2225 }
2228 /**
2229 *
2230 */
2231 DOMLocatorImpl::~DOMLocatorImpl()
2232 {
2233 }
2236 /**
2237 *
2238 */
2239 long DOMLocatorImpl::getLineNumber()
2240 {
2241 return lineNumber;
2242 }
2244 /**
2245 *
2246 */
2247 long DOMLocatorImpl::getColumnNumber()
2248 {
2249 return columnNumber;
2250 }
2252 /**
2253 *
2254 */
2255 long DOMLocatorImpl::getByteOffset()
2256 {
2257 return byteOffset;
2258 }
2260 /**
2261 *
2262 */
2263 long DOMLocatorImpl::getUtf16Offset()
2264 {
2265 return utf16Offset;
2266 }
2269 /**
2270 *
2271 */
2272 Node *DOMLocatorImpl::getRelatedNode()
2273 {
2274 return relatedNode;
2275 }
2278 /**
2279 *
2280 */
2281 DOMString DOMLocatorImpl::getUri()
2282 {
2283 return uri;
2284 }
2288 /*#########################################################################
2289 ## DOMConfigurationImpl
2290 #########################################################################*/
2293 /**
2294 *
2295 */
2296 DOMConfigurationImpl::DOMConfigurationImpl()
2297 {
2298 }
2301 /**
2302 *
2303 */
2304 DOMConfigurationImpl::~DOMConfigurationImpl()
2305 {
2306 }
2308 /**
2309 *
2310 */
2311 void DOMConfigurationImpl::setParameter(const DOMString &name,
2312 const DOMUserData *value) throw (DOMException)
2313 {
2314 }
2316 /**
2317 *
2318 */
2319 DOMUserData *DOMConfigurationImpl::getParameter(const DOMString &name)
2320 throw (DOMException)
2321 {
2322 return NULL;
2323 }
2325 /**
2326 *
2327 */
2328 bool DOMConfigurationImpl::canSetParameter(const DOMString &name,
2329 const DOMUserData *data)
2330 {
2331 return false;
2332 }
2334 /**
2335 *
2336 */
2337 DOMStringList *DOMConfigurationImpl::getParameterNames()
2338 {
2339 return NULL;
2340 }
2344 /*#########################################################################
2345 ## CDATASectionImpl
2346 #########################################################################*/
2348 /**
2349 *
2350 */
2351 CDATASectionImpl::CDATASectionImpl() : TextImpl()
2352 {
2353 nodeType = CDATA_SECTION_NODE;
2354 nodeName = "#cdata-section";
2355 }
2357 /**
2358 *
2359 */
2360 CDATASectionImpl::CDATASectionImpl(DocumentImpl *owner, const DOMString &theValue)
2361 : TextImpl()
2362 {
2363 nodeType = CDATA_SECTION_NODE;
2364 nodeName = "#cdata-section";
2365 ownerDocument = owner;
2366 nodeValue = theValue;
2367 }
2370 /**
2371 *
2372 */
2373 CDATASectionImpl::~CDATASectionImpl()
2374 {
2375 }
2381 /*#########################################################################
2382 ## DocumentTypeImpl
2383 #########################################################################*/
2385 /**
2386 *
2387 */
2388 DocumentTypeImpl::DocumentTypeImpl(const DOMString& theName,
2389 const DOMString& thePublicId,
2390 const DOMString& theSystemId)
2391 : NodeImpl()
2392 {
2393 nodeType = DOCUMENT_TYPE_NODE;
2394 nodeName = theName;
2395 publicId = thePublicId;
2396 systemId = theSystemId;
2397 }
2399 /**
2400 *
2401 */
2402 DocumentTypeImpl::~DocumentTypeImpl()
2403 {
2404 }
2406 /**
2407 *
2408 */
2409 DOMString DocumentTypeImpl::getName()
2410 {
2411 return nodeName;
2412 }
2414 /**
2415 *
2416 */
2417 NamedNodeMap DocumentTypeImpl::getEntities()
2418 {
2419 return entities;
2420 }
2422 /**
2423 *
2424 */
2425 NamedNodeMap DocumentTypeImpl::getNotations()
2426 {
2427 return notations;
2428 }
2430 /**
2431 *
2432 */
2433 DOMString DocumentTypeImpl::getPublicId()
2434 {
2435 return publicId;
2436 }
2438 /**
2439 *
2440 */
2441 DOMString DocumentTypeImpl::getSystemId()
2442 {
2443 return systemId;
2444 }
2446 /**
2447 *
2448 */
2449 DOMString DocumentTypeImpl::getInternalSubset()
2450 {
2451 return DOMString("");
2452 }
2459 /*#########################################################################
2460 ## NotationImpl
2461 #########################################################################*/
2465 /**
2466 *
2467 */
2468 NotationImpl::NotationImpl(DocumentImpl *owner) : NodeImpl()
2469 {
2470 nodeType = NOTATION_NODE;
2471 ownerDocument = owner;
2472 }
2475 /**
2476 *
2477 */
2478 NotationImpl::~NotationImpl()
2479 {
2480 }
2482 /**
2483 *
2484 */
2485 DOMString NotationImpl::getPublicId()
2486 {
2487 return publicId;
2488 }
2490 /**
2491 *
2492 */
2493 DOMString NotationImpl::getSystemId()
2494 {
2495 return systemId;
2496 }
2505 /*#########################################################################
2506 ## EntityImpl
2507 #########################################################################*/
2510 /**
2511 *
2512 */
2513 EntityImpl::EntityImpl() : NodeImpl()
2514 {
2515 nodeType = ENTITY_NODE;
2516 }
2519 /**
2520 *
2521 */
2522 EntityImpl::EntityImpl(DocumentImpl *owner) : NodeImpl()
2523 {
2524 nodeType = ENTITY_NODE;
2525 ownerDocument = owner;
2526 }
2529 /**
2530 *
2531 */
2532 EntityImpl::~EntityImpl()
2533 {
2534 }
2536 /**
2537 *
2538 */
2539 DOMString EntityImpl::getPublicId()
2540 {
2541 return publicId;
2542 }
2544 /**
2545 *
2546 */
2547 DOMString EntityImpl::getSystemId()
2548 {
2549 return systemId;
2550 }
2552 /**
2553 *
2554 */
2555 DOMString EntityImpl::getNotationName()
2556 {
2557 return notationName;
2558 }
2560 /**
2561 *
2562 */
2563 DOMString EntityImpl::getInputEncoding()
2564 {
2565 return inputEncoding;
2566 }
2568 /**
2569 *
2570 */
2571 DOMString EntityImpl::getXmlEncoding()
2572 {
2573 return xmlEncoding;
2574 }
2576 /**
2577 *
2578 */
2579 DOMString EntityImpl::getXmlVersion()
2580 {
2581 return xmlVersion;
2582 }
2589 /*#########################################################################
2590 ## EntityReferenceImpl
2591 #########################################################################*/
2595 /**
2596 *
2597 */
2598 EntityReferenceImpl::EntityReferenceImpl() : NodeImpl()
2599 {
2600 nodeType = ENTITY_REFERENCE_NODE;
2601 }
2604 /**
2605 *
2606 */
2607 EntityReferenceImpl::EntityReferenceImpl(DocumentImpl *owner,
2608 const DOMString &theName)
2609 : NodeImpl()
2610 {
2611 nodeType = ENTITY_REFERENCE_NODE;
2612 nodeName = theName;
2613 ownerDocument = owner;
2614 }
2617 /**
2618 *
2619 */
2620 EntityReferenceImpl::~EntityReferenceImpl()
2621 {
2622 }
2626 /*#########################################################################
2627 ## ProcessingInstructionImpl
2628 #########################################################################*/
2633 /**
2634 *
2635 */
2636 ProcessingInstructionImpl::ProcessingInstructionImpl(): NodeImpl()
2637 {
2638 nodeType = PROCESSING_INSTRUCTION_NODE;
2639 }
2643 /**
2644 *
2645 */
2646 ProcessingInstructionImpl::ProcessingInstructionImpl(DocumentImpl *owner,
2647 const DOMString &target,
2648 const DOMString &data)
2649 : NodeImpl()
2650 {
2651 nodeType = PROCESSING_INSTRUCTION_NODE;
2652 ownerDocument = owner;
2653 nodeName = target;
2654 nodeValue = data;
2655 }
2658 /**
2659 *
2660 */
2661 ProcessingInstructionImpl::~ProcessingInstructionImpl()
2662 {
2663 }
2668 /**
2669 *
2670 */
2671 DOMString ProcessingInstructionImpl::getTarget()
2672 {
2673 return nodeName;
2674 }
2676 /**
2677 *
2678 */
2679 DOMString ProcessingInstructionImpl::getData()
2680 {
2681 return nodeValue;
2682 }
2684 /**
2685 *
2686 */
2687 void ProcessingInstructionImpl::setData(const DOMString& val) throw(DOMException)
2688 {
2689 //do something here
2690 }
2698 /*#########################################################################
2699 ## DocumentFragmentImpl
2700 #########################################################################*/
2702 /**
2703 *
2704 */
2705 DocumentFragmentImpl::DocumentFragmentImpl() : NodeImpl()
2706 {
2707 nodeType = DOCUMENT_FRAGMENT_NODE;
2708 nodeName = "#document-fragment";
2709 }
2712 /**
2713 *
2714 */
2715 DocumentFragmentImpl::DocumentFragmentImpl(DocumentImpl *owner) : NodeImpl()
2716 {
2717 nodeType = DOCUMENT_FRAGMENT_NODE;
2718 nodeName = "#document-fragment";
2719 ownerDocument = owner;
2720 }
2723 /**
2724 *
2725 */
2726 DocumentFragmentImpl::~DocumentFragmentImpl()
2727 {
2728 }
2735 /*#########################################################################
2736 ## DocumentImpl
2737 #########################################################################*/
2741 /**
2742 *
2743 */
2744 DocumentType *DocumentImpl::getDoctype()
2745 {
2746 return doctype;
2747 }
2749 /**
2750 *
2751 */
2752 DOMImplementation *DocumentImpl::getImplementation()
2753 {
2754 return parent;
2755 }
2757 /**
2758 *
2759 */
2760 Element *DocumentImpl::getDocumentElement()
2761 {
2762 return documentElement;
2763 }
2765 /**
2766 *
2767 */
2768 Element *DocumentImpl::createElement(const DOMString& tagName)
2769 throw(DOMException)
2770 {
2771 ElementImpl *impl = new ElementImpl(this, tagName);
2772 return impl;
2773 }
2775 /**
2776 *
2777 */
2778 DocumentFragment *DocumentImpl::createDocumentFragment()
2779 {
2780 DocumentFragmentImpl *frag = new DocumentFragmentImpl(this);
2781 return frag;
2782 }
2784 /**
2785 *
2786 */
2787 Text *DocumentImpl::createTextNode(const DOMString& data)
2788 {
2789 TextImpl *text = new TextImpl(this, data);
2790 return text;
2791 }
2793 /**
2794 *
2795 */
2796 Comment *DocumentImpl::createComment(const DOMString& data)
2797 {
2798 CommentImpl *comment = new CommentImpl(this, data);
2799 return comment;
2800 }
2802 /**
2803 *
2804 */
2805 CDATASection *DocumentImpl::createCDATASection(const DOMString& data)
2806 throw(DOMException)
2807 {
2808 CDATASectionImpl *cdata = new CDATASectionImpl(this, data);
2809 return cdata;
2810 }
2812 /**
2813 *
2814 */
2815 ProcessingInstruction *DocumentImpl::createProcessingInstruction(const DOMString& target,
2816 const DOMString& data)
2817 throw(DOMException)
2818 {
2819 ProcessingInstructionImpl *cdata =
2820 new ProcessingInstructionImpl(this, target, data);
2821 return cdata;
2822 }
2824 /**
2825 *
2826 */
2827 Attr *DocumentImpl::createAttribute(const DOMString& attrName)
2828 throw(DOMException)
2829 {
2830 AttrImpl *attr = new AttrImpl(this, attrName);
2831 return attr;
2832 }
2834 /**
2835 *
2836 */
2837 EntityReference *DocumentImpl::createEntityReference(const DOMString& erName)
2838 throw(DOMException)
2839 {
2840 EntityReferenceImpl *ref = new EntityReferenceImpl(this, erName);
2841 return ref;
2842 }
2845 /**
2846 *
2847 */
2848 NodeList DocumentImpl::getElementsByTagName(const DOMString& tagname)
2849 {
2850 NodeList list;
2851 ElementImpl::getElementsByTagNameRecursive(list,
2852 tagname, documentElement);
2853 return list;
2854 }
2857 /**
2858 *
2859 */
2860 Node *DocumentImpl::importNode(const Node *importedNode,
2861 bool deep)
2862 throw(DOMException)
2863 {
2864 return NULL;
2865 }
2867 /**
2868 *
2869 */
2870 Element *DocumentImpl::createElementNS(const DOMString& namespaceURI,
2871 const DOMString& qualifiedName)
2872 throw(DOMException)
2873 {
2874 ElementImpl *elem = new ElementImpl(this, namespaceURI, qualifiedName);
2875 return elem;
2876 }
2878 /**
2879 *
2880 */
2881 Attr *DocumentImpl::createAttributeNS(const DOMString& namespaceURI,
2882 const DOMString& qualifiedName)
2883 throw(DOMException)
2884 {
2885 AttrImpl *attr = new AttrImpl(this, namespaceURI, qualifiedName);
2886 return attr;
2887 }
2890 /**
2891 *
2892 */
2893 NodeList DocumentImpl::getElementsByTagNameNS(const DOMString& namespaceURI,
2894 const DOMString& localName)
2895 {
2896 NodeList list;
2897 ElementImpl::getElementsByTagNameNSRecursive(list, namespaceURI,
2898 localName, documentElement);
2899 return list;
2900 }
2902 /**
2903 *
2904 */
2905 Element *DocumentImpl::getElementById(const DOMString& elementId)
2906 {
2907 for (NamedElementItem *entry = elementsById.next; entry ; entry=entry->next)
2908 if (entry->name == elementId)
2909 return entry->elem;
2910 return NULL;
2911 }
2914 /**
2915 *
2916 */
2917 DOMString DocumentImpl::getInputEncoding()
2918 {
2919 return inputEncoding;
2920 }
2923 /**
2924 *
2925 */
2926 DOMString DocumentImpl::getXmlEncoding()
2927 {
2928 return xmlEncoding;
2929 }
2931 /**
2932 *
2933 */
2934 bool DocumentImpl::getXmlStandalone()
2935 {
2936 return xmlStandalone;
2937 }
2939 /**
2940 *
2941 */
2942 void DocumentImpl::setXmlStandalone(bool val) throw (DOMException)
2943 {
2944 xmlStandalone = val;
2945 }
2947 /**
2948 *
2949 */
2950 DOMString DocumentImpl::getXmlVersion()
2951 {
2952 return xmlVersion;
2953 }
2955 /**
2956 *
2957 */
2958 void DocumentImpl::setXmlVersion(const DOMString &version) throw (DOMException)
2959 {
2960 xmlVersion = version;
2961 }
2963 /**
2964 *
2965 */
2966 bool DocumentImpl::getStrictErrorChecking()
2967 {
2968 return strictErrorChecking;
2969 }
2971 /**
2972 *
2973 */
2974 void DocumentImpl::setStrictErrorChecking(bool val)
2975 {
2976 strictErrorChecking = val;
2977 }
2980 /**
2981 *
2982 */
2983 DOMString DocumentImpl::getDocumentURI()
2984 {
2985 if (!documentURI)
2986 return DOMString("");
2987 DOMString docURI = *documentURI;
2988 return docURI;
2989 }
2991 /**
2992 *
2993 */
2994 void DocumentImpl::setDocumentURI(const DOMString &uri)
2995 {
2996 //documentURI = stringCache(uri);
2997 }
2999 /**
3000 *
3001 */
3002 Node *DocumentImpl::adoptNode(const Node *source) throw (DOMException)
3003 {
3004 return (Node *)source;
3005 }
3007 /**
3008 *
3009 */
3010 DOMConfiguration *DocumentImpl::getDomConfig()
3011 {
3012 return domConfig;
3013 }
3015 /**
3016 *
3017 */
3018 void DocumentImpl::normalizeDocument()
3019 {
3020 //i assume that this means adjusting namespaces & prefixes
3021 if (documentElement)
3022 documentElement->normalizeNamespaces();
3023 }
3025 /**
3026 *
3027 */
3028 Node *DocumentImpl::renameNode(const Node *n,
3029 const DOMString &namespaceURI,
3030 const DOMString &qualifiedName)
3031 throw (DOMException)
3032 {
3033 Node *node = (Node *) n;
3034 NodeImpl *nodeImpl = dynamic_cast<NodeImpl *> (node);
3035 //nodeImpl->namespaceURI = stringCache(namespaceURI);
3036 nodeImpl->setNodeName(qualifiedName);
3037 return node;
3038 }
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()
3053 {
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;
3065 }
3068 /**
3069 *
3070 */
3071 DocumentImpl::~DocumentImpl()
3072 {
3073 delete documentElement;
3074 }
3087 } //namespace dom
3088 } //namespace w3c
3089 } //namespace org
3093 /*#########################################################################
3094 ## E N D O F F I L E
3095 #########################################################################*/