00001 #ifndef hpp_CPP_DOMDeclaration_CPP_hpp
00002 #define hpp_CPP_DOMDeclaration_CPP_hpp
00003
00004
00005 #include "../Strings/Strings.hpp"
00006
00007 #include "../Tree/NTree.hpp"
00008
00009 #include "../Tree/Avl.hpp"
00010
00011 #include "Attributes.hpp"
00012
00013
00014 namespace DOM
00015 {
00016
00017 struct Node;
00018 }
00019
00020 namespace HTML
00021 {
00023 typedef Tree::NTree<const DOM::Node *> DOMTree;
00024 namespace Elements
00025 {
00026 class Element;
00027 namespace Allocators
00028 {
00029 class BaseAllocator;
00030 }
00031 }
00032 }
00033
00036 namespace DOM
00037 {
00038 namespace Exceptions
00039 {
00040 struct DOMException
00041 {
00042 enum { code = 0 };
00043 };
00044
00045 template <int codeImpl>
00046 struct TypedDOMException { enum { code = codeImpl }; };
00047
00048
00049 typedef TypedDOMException<1> IndexSize;
00050 typedef TypedDOMException<2> StringSize;
00051 typedef TypedDOMException<3> HierarchyRequest;
00052 typedef TypedDOMException<4> WrongDocument;
00053 typedef TypedDOMException<5> InvalidCharacter;
00054 typedef TypedDOMException<6> NoDataAllowed;
00055 typedef TypedDOMException<7> NoModificationAllowed;
00056 typedef TypedDOMException<8> NotFound;
00057 typedef TypedDOMException<9> NotSupported;
00058 typedef TypedDOMException<10> AttributeInUse;
00059 typedef TypedDOMException<11> InvalidState;
00060 typedef TypedDOMException<12> Syntax;
00061 typedef TypedDOMException<13> InvalidModification;
00062 typedef TypedDOMException<14> Namespace;
00063 typedef TypedDOMException<15> InvalidAccess;
00064 }
00065
00067 typedef Strings::VerySimpleReadOnlyString DOMString;
00069 typedef HTML::DOMTree DOMTree;
00070
00071
00073 struct NodeList
00074 {
00075 private:
00077 DOMTree::Node & parent;
00078
00079 public:
00081 const uint32 length;
00084 const Node * item(const uint32 index) throw() { if (!length) return 0; DOMTree::Node * child = parent.childAtIndex(index); return child ? child->getData() : 0; }
00085
00086 public:
00088 NodeList(DOMTree::Node & parentNode) : parent(parentNode), length(parent.getChildrenCount()) {}
00090 NodeList(DOMTree::Node * parentPtr) : parent(*parentPtr), length(parentPtr ? parent.getChildrenCount(): 0) {}
00092 NodeList(const NodeList & copy) : parent(copy.parent), length(copy.length) {}
00093
00095 virtual ~NodeList() { }
00096 };
00097
00101 struct NamedNodeMap
00102 {
00103 public:
00104
00105 typedef Tree::AVL::Tree<const Node *, HTML::GenericAttribute::AttributeID> AttribTree;
00106
00107 private:
00108 AttribTree attribTree;
00109
00111 AttribTree::IterT getItemIterFromName(const DOMString & name) const throw();
00112
00113 public:
00116 inline const Node * getNamedItem(const DOMString & name) const throw();
00120 const Node * setNamedItem(const Node * const arg);
00124 const Node * removeNamedItem(const DOMString & name);
00127 const Node * item(const uint32 index) const throw();
00129 inline const uint32 length() const { return attribTree.getSize(); }
00130
00131
00132 public:
00134 inline AttribTree::IterT getFirstIterator() const throw() { return attribTree.getFirstIterator(); }
00136 inline void Append(const Node * attribute, const HTML::GenericAttribute::AttributeID & AID) { attribTree.insertObject(attribute, AID); }
00137
00138 };
00139
00140
00141 class Document;
00142
00143 class DocumentType;
00144
00145
00146
00147
00148
00150 struct DOMImplementation
00151 {
00152
00153 private:
00155 const volatile HTML::Elements::Allocators::BaseAllocator * allocator;
00156
00157
00158 public:
00163 const bool hasFeature(const DOMString & feature, const DOMString & version) const throw();
00171 const DocumentType * createDocumentType(const DOMString & qualifiedName, const DOMString & publicId, const DOMString & systemId) const;
00179 const Document * createDocument(const DOMString & namespaceURI, const DOMString & qualifiedName, const DocumentType * docType) const;
00180
00181
00182 public:
00184 DOMImplementation(const volatile HTML::Elements::Allocators::BaseAllocator * _allocator) : allocator(_allocator) {}
00185
00186
00187 public:
00189 inline void setAllocator(const volatile HTML::Elements::Allocators::BaseAllocator * _allocator) { if (_allocator) allocator = _allocator; }
00190 };
00191
00193 const DOMImplementation & getCurrentDOMImplementation(const volatile HTML::Elements::Allocators::BaseAllocator * _allocator);
00194
00196 struct Node
00197 {
00198
00199 private:
00201 DOMTree::Node * treeNode;
00202
00203
00204 public:
00206 struct NodeType
00207 {
00208 enum Type
00209 {
00210 Element = 1,
00211 Attribute = 2,
00212 Text = 3,
00213 CDATA_Section = 4,
00214 EntityReference = 5,
00215 Entity = 6,
00216 ProcessingInstruction = 7,
00217 Comment = 8,
00218 Document = 9,
00219 DocumentType = 10,
00220 DocumentFragment = 11,
00221 Notation = 12,
00222 };
00223 };
00224
00226 const NodeType::Type nodeType;
00227
00228
00229 public:
00232 virtual DOMString nodeName() const { return DOMString("Unknown"); }
00235 virtual DOMString nodeValue() const { return DOMString(); }
00238 virtual void nodeValue(const DOMString & newValue) { throw Exceptions::NoModificationAllowed(); }
00240 inline const uint16 getNodeType() const { return (uint16)nodeType; }
00243 virtual DOMString namespaceURI() const { return DOMString(); }
00246 virtual DOMString localName() const { return DOMString(); }
00249 virtual DOMString prefix() const { return DOMString(); }
00252 void prefix(const DOMString &) const { throw Exceptions::NoModificationAllowed(); }
00253
00256 inline const Node * parentNode() const { return treeNode && treeNode->parentNode() ? treeNode->parentNode()->getData() : 0; }
00259 inline NodeList * childNodes() const { return new NodeList(*treeNode); }
00262 inline const Node * firstChild() const { return treeNode && treeNode->firstChild() ? treeNode->firstChild()->getData() : 0; }
00265 inline const Node * lastChild() const { DOMTree::Node * child = treeNode ? treeNode->lastChild() : 0; return child ? child->getData() : 0; }
00268 inline const Node * previousSibling() const { DOMTree::Node * child = treeNode ? treeNode->parentNode() : 0; uint32 index = 0; if (child && ((index = child->findChildIndex(this)) != child->getChildrenCount()) && (child = child->childAtIndex(index - 1))) return child ? child->getData() : 0; return 0; }
00271 inline const Node * nextSibling() const { DOMTree::Node * child = treeNode ? treeNode->nextNode() : 0; return child ? child->getData() : 0; }
00272
00273
00276 virtual const NamedNodeMap * attributes() const { return 0; }
00279 inline const DOM::Document * ownerDocument() const
00280 {
00281 DOMTree::Node * parent = treeNode ? treeNode->parentNode() : 0;
00282 if (!parent)
00283 return nodeType == NodeType::Document ? (const DOM::Document*)this : 0;
00284 while (parent->parentNode()) parent = parent->parentNode();
00285 if (parent->getData())
00286 return parent->getData()->nodeType == NodeType::Document ? (const DOM::Document*)parent->getData() : 0;
00287 return 0;
00288 }
00291 inline bool hasChildNodes() const throw() { return treeNode ? (treeNode->getChildrenCount() > 0) : false; }
00294 inline bool hasAttributes() const throw() { return nodeType == NodeType::Element ? (attributes() != 0) : false; }
00297 inline const uint32 getChildrenCount() const throw() { return treeNode ? treeNode->getChildrenCount() : 0; }
00298
00299
00300 public:
00303 virtual void returnToAllocator(const volatile HTML::Elements::Allocators::BaseAllocator * allocator);
00304
00305
00306 private:
00308 inline DOMTree::Node * removeIfAlreadyThere(const Node * node, uint32 & indexOf) { DOMTree::Node * tNode = 0; uint32 index = treeNode->findChildIndex(node); if (index != treeNode->getChildrenCount()) { tNode = treeNode->forgetChildAtIndex(index); if (indexOf > index) indexOf --; } return tNode; }
00309
00310
00311 public:
00317 inline const Node * insertBefore(const Node * newNode, const Node * refNode)
00318 {
00319
00320 if (!newNode || newNode == refNode || !treeNode) return newNode;
00321
00322 if (!refNode) { DOMTree::Node * node = new DOMTree::Node(newNode, treeNode); newNode->setTreeNode(node); treeNode->appendChild(node); return newNode; }
00323
00324 uint32 index = treeNode->findChildIndex(refNode);
00325 if (index == treeNode->getChildrenCount()) throw Exceptions::NotFound();
00326
00327 DOMTree::Node * node = removeIfAlreadyThere(newNode, index);
00328
00329 if (!node) { node = new DOMTree::Node(newNode, treeNode); newNode->setTreeNode(node); }
00330 treeNode->insertChildBefore(node, index);
00331 return newNode;
00332 }
00333
00339 inline const Node * replaceChild(const Node * newNode, const Node * oldNode)
00340 {
00341 if (!newNode || !oldNode || !treeNode) return 0;
00342
00343 if (newNode == oldNode) return oldNode;
00344
00345 uint32 index = treeNode->findChildIndex(oldNode);
00346 if (index == treeNode->getChildrenCount()) throw Exceptions::NotFound();
00347 DOMTree::Node * node = removeIfAlreadyThere(newNode, index);
00348 DOMTree::Node * child = treeNode->childAtIndex(index);
00349 const Node * ret = child->getData();
00350 child->getData() = newNode;
00351
00352 if (node) { node->getData() = 0; node->Suicide(); }
00353 return ret;
00354 }
00355
00360 inline const Node * removeChild(const Node * oldNode)
00361 {
00362 if (!oldNode) return 0;
00363 uint32 index = 0;
00364 DOMTree::Node * node = removeIfAlreadyThere(oldNode, index);
00365 if (!node) throw Exceptions::NotFound();
00366 const Node * ret = node->getData();
00367 node->getData() = 0; node->Suicide();
00368 return ret;
00369 }
00370
00374 inline const Node * appendChild(const Node * newNode) { return insertBefore(newNode, 0); }
00375
00381 inline Node * cloneNode(bool deepCloning) const throw() { return Clone(deepCloning); }
00382
00386 inline void normalize() throw() { }
00387
00392 static inline bool isSupported(const DOMString & feature, const DOMString & version) { return getCurrentDOMImplementation(0).hasFeature(feature, version); }
00393
00394
00395
00396
00397 public:
00399 inline void setTreeNode(DOMTree::Node * newTreeNode) const { const_cast<DOMTree::Node *>(treeNode) = newTreeNode; }
00400
00404 inline const Node * firstChildOfType(const NodeType::Type type) const
00405 {
00406 if (treeNode && treeNode->firstChild())
00407 {
00408 DOMTree::Node * child = treeNode->firstChild();
00409 while (child) { if (child->getData() && child->getData()->nodeType == type) return child->getData(); child = child->nextNode(); }
00410 }
00411 return 0;
00412 }
00413
00417 inline void Suicide() { if (treeNode) treeNode->Suicide(); }
00418
00419
00420 protected:
00422 Node(const NodeType::Type & type, DOMTree::Node * ref = 0) : nodeType(type), treeNode(ref) {}
00424 inline DOMTree::Node * getTreeNode() { return treeNode; }
00426 inline const DOMTree::Node * getTreeNode() const { return treeNode; }
00427 public:
00429 virtual ~Node() {}
00430
00431
00432 protected:
00434 virtual Node * Clone(bool deepCopy) const throw()
00435 {
00436
00437 Node * node = new Node(nodeType);
00438 DOMTree::Node * tNode = new DOMTree::Node(node);
00439 node->setTreeNode(tNode);
00440 if (deepCopy)
00441 {
00442 const Node * child = firstChild();
00443 while (child)
00444 {
00445 node->appendChild(child->Clone(true));
00446 child = child->nextSibling();
00447 }
00448 }
00449 return 0;
00450 }
00451 };
00452
00453
00454
00455
00457 class CharacterData : public Node
00458 {
00459
00460 private:
00462 DOMString sharedData;
00464 Strings::FastString ownedData;
00466 bool useSharedData;
00467
00468
00469 private:
00471 inline void Mutate() throw() { if (useSharedData) { ownedData = Strings::convert(sharedData); useSharedData = false; } }
00472
00473
00474 protected:
00476 inline void limitTo(uint32 count)
00477 {
00478 if (useSharedData)
00479 if (sharedData.limitTo(count)) return;
00480
00481 Mutate(); ownedData = ownedData.midString(0, count);
00482 }
00483
00485 inline bool isShared() const { return useSharedData; }
00486
00487
00488 public:
00491 virtual DOMString nodeValue() const { return data(); }
00493 virtual void nodeValue(const DOMString & newValue) { data(newValue); }
00494
00495
00496 public:
00499 inline DOMString data() const throw() { return useSharedData ? sharedData : DOMString((const char*)ownedData, ownedData.getLength()); }
00502 inline void data(const DOMString newData) { useSharedData = false; ownedData = Strings::convert(newData); }
00503
00506 inline const uint32 length() const throw() { return useSharedData ? sharedData.getLength() : ownedData.getLength(); }
00512 inline DOMString substringData(uint32 offset, uint32 count) { if ((int)offset < 0 || offset >= length()) throw Exceptions::IndexSize(); count = (length() - offset) < count ? (length() - offset) : count; if (useSharedData) return DOMString(&sharedData.getData()[offset], count); else return DOMString((const char*)ownedData + offset, count); }
00515 inline void appendData(const DOMString & arg) { Mutate(); ownedData += Strings::convert(arg); }
00520 inline void insertData(uint32 offset, const DOMString & arg) { if ((int)offset < 0 || offset >= length()) throw Exceptions::IndexSize(); Mutate(); ownedData.Insert(offset, Strings::convert(arg)); }
00525 inline void deleteData(uint32 offset, uint32 count) { if ((int)offset < 0 || (int)count < 0 || offset >= length()) throw Exceptions::IndexSize(); Mutate(); ownedData.Remove((int)offset, (int)count); }
00531 inline void replaceData(uint32 offset, uint32 count, const DOMString & arg) { deleteData(offset, count); insertData(offset, arg); }
00532
00533
00534 public:
00536 CharacterData(const NodeType::Type & type, const DOMString & _data, DOMTree::Node * ref = 0) : Node(type, ref), sharedData(_data), useSharedData(true) {}
00538 CharacterData(const NodeType::Type & type, const Strings::FastString & string, DOMTree::Node * ref = 0) : Node(type, ref), ownedData(string), useSharedData(false) {}
00539 };
00540
00541
00543 class Text : public CharacterData
00544 {
00545
00546 public:
00553 inline const Text * splitText(uint32 offset)
00554 {
00555 uint32 currentLen = length();
00556 DOMString rightString = substringData(offset, currentLen - offset);
00557
00558 limitTo(offset);
00559
00560
00561 Text * text = new Text(rightString);
00562
00563 return (Text*)insertBefore(text, nextSibling());
00564 }
00565
00566
00567 public:
00570 virtual DOMString nodeName() const { return DOMString("#text"); }
00573 virtual Node * Clone(bool deepCopy) const throw() { Node * node = new Text(isShared() ? data() : DOMString()); if (!isShared()) ((Text*)node)->data(data()); DOMTree::Node * tNode = new DOMTree::Node(node); node->setTreeNode(tNode); return node; }
00574
00575
00576 public:
00577 Text(const DOMString & text, DOMTree::Node * ref = 0) : CharacterData(NodeType::Text, text, ref) {}
00578 Text(const Strings::FastString & text, DOMTree::Node * ref = 0) : CharacterData(NodeType::Text, text, ref) {}
00579 };
00580
00581
00582
00583 class Element;
00584
00585 class Attr : public Node
00586 {
00587
00588 private:
00590 HTML::Attributes::Attribute * attribute;
00592 const DOM::Element * element;
00594 DOMString sharedData;
00596 Strings::FastString ownedData;
00598 bool useSharedData;
00599
00600
00601 private:
00603 inline void Mutate() throw() { if (useSharedData) { ownedData = Strings::convert(sharedData); useSharedData = false; } }
00604
00605
00606 public:
00608 inline DOMString name() const throw() { return DOMString(attribute->attributeName()); }
00611 inline bool specified() const throw() { return false; }
00614 inline DOMString value() const throw() { return useSharedData ? sharedData : DOMString((const char*)ownedData, ownedData.getLength()); }
00620 inline void value(const DOMString & newValue) { Mutate(); ownedData = Strings::convert(newValue); }
00621
00624 const DOM::Element * ownerElement() const { return element; }
00625
00626
00627 public:
00630 virtual DOMString nodeName() const { return name(); }
00633 virtual DOMString nodeValue() const { return value(); }
00635 virtual void nodeValue(const DOMString & newValue) { value(newValue); }
00636
00638 virtual Node * Clone(bool deepCopy) const throw() { return internalClone(deepCopy); }
00639
00640
00641 public:
00644 virtual void returnToAllocator(const volatile HTML::Elements::Allocators::BaseAllocator * allocator);
00645
00646
00647 public:
00649 inline HTML::Attributes::Attribute * getAttributeDeclaration() { return attribute; }
00650
00651
00652 public:
00653 Attr(HTML::Attributes::Attribute * attrib, const DOMString & value) : Node(Node::NodeType::Attribute), attribute(attrib), sharedData(value), useSharedData(true) {}
00654
00655 private:
00657 inline Node * internalClone(bool deepCopy, bool setSpecified = true) const throw()
00658 {
00659
00660 Attr * attr = new Attr(new HTML::Attributes::Attribute(*attribute), useSharedData ? sharedData : DOMString());
00661 if (!useSharedData) attr->value(value());
00662 DOMTree::Node * tNode = new DOMTree::Node(attr);
00663 attr->setTreeNode(tNode);
00664 if (setSpecified) attr->setSpecified(true);
00665 if (deepCopy)
00666 {
00667 const Node * child = firstChild();
00668 while (child)
00669 {
00670 attr->appendChild(child->cloneNode(true));
00671 child = child->nextSibling();
00672 }
00673 }
00674 return attr;
00675 }
00676
00679 inline void setSpecified(const bool set) { }
00681 inline void setOwnerElement(const DOM::Element * elem) { element = elem; }
00682
00683 public:
00684
00685 friend class DOM::Element;
00686
00687 friend class DOM::Document;
00688
00689 friend struct DOM::NamedNodeMap;
00690 };
00691
00692
00693
00694
00695
00697 class Element : public Node
00698 {
00699
00700 private:
00702 HTML::Elements::Element * element;
00704 NamedNodeMap attributeArray;
00705
00706
00707 public:
00709 inline HTML::Elements::Element * getElement() const { return element; }
00711 inline void setElement(HTML::Elements::Element * newEl) { element = newEl; }
00713 friend Document;
00714
00715
00716
00717 public:
00720 virtual DOMString nodeName() const { return tagName(); }
00723 virtual const NamedNodeMap * attributes() const { return &attributeArray; }
00725 virtual Node * Clone(bool deepCopy) const throw();
00726
00727
00728 public:
00730 inline DOMString tagName() const;
00734 inline const Attr * getAttributeNode(const DOMString & name) const { return checkConv(attributeArray.getNamedItem(name)); }
00738 inline DOMString getAttribute(const DOMString & name) const { const Attr * attrib = getAttributeNode(name); if (!attrib) return DOMString(); return attrib->value(); }
00742 inline const Attr * setAttributeNode(const Attr * node) { if (node) const_cast<DOM::Attr*>(node)->setOwnerElement(this); return checkConv(attributeArray.setNamedItem(node)); }
00747 inline void setAttribute(const DOMString & name, const DOMString & value);
00751 inline void removeAttribute(const DOMString & name) { const Node * node = attributeArray.removeNamedItem(name); delete const_cast<Attr*>((const Attr*)node); }
00756 inline const Attr * removeAttributeNode(const Attr * node) { return checkConv(attributeArray.removeNamedItem(node->name())); }
00760 NodeList * getElementsByTagName(const DOMString & name) const throw();
00764 inline bool hasAttribute(const DOMString & name) const throw() { return getAttributeNode(name) != 0; }
00765
00766
00767 public:
00772 NodeList * getChildrenByTag(const HTML::GenericElement::ElementID tag) const throw();
00776 const Element * getParentOfFirstChildOfType(const HTML::GenericElement::ElementID tag) const throw();
00780 const Element * getFirstParentOfType(const HTML::GenericElement::ElementID tag) const throw();
00781
00782
00783
00784 public:
00787 virtual void returnToAllocator(const volatile HTML::Elements::Allocators::BaseAllocator * allocator);
00788
00789 public:
00791 Element(HTML::Elements::Element * el) : Node(Node::NodeType::Element), element(el) {}
00792
00793
00794 private:
00796 inline const Attr * checkConv(const Node * attr) const { return attr && attr->nodeType == Node::NodeType::Attribute ? (const Attr*)attr : 0; }
00800 struct MatchElementByTag : public NodeList
00801 {
00803 DOMTree::Node root;
00805 const HTML::GenericElement::ElementID & elementID;
00807 int continueSearching;
00808
00810 int searchMethod(const DOM::Node * node);
00812 int removeDataLinks(const DOMTree::Node * node);
00813
00815 MatchElementByTag(const HTML::GenericElement::ElementID & id, const int contSearch = 0) : elementID(id), root(0), NodeList(root), continueSearching(contSearch) { const_cast<uint32 &>(length) = 0; }
00817 ~MatchElementByTag()
00818 {
00819
00820
00821
00822 root.applyOnChildrenNode(*this, &MatchElementByTag::removeDataLinks, true);
00823 }
00824 };
00825 };
00826
00827
00828
00830 class DocumentType : public Node
00831 {
00832
00833 private:
00835 DOMString typeName;
00837 DOMString publicID;
00839 DOMString systemID;
00840
00841
00842
00843 public:
00846 virtual DOMString nodeName() const { return name(); }
00847
00848 public:
00851 inline const DOMString & name() const { return typeName; }
00854 inline const NamedNodeMap * entities() const { return 0; }
00857 inline const NamedNodeMap * notations() const { return 0; }
00860 inline const DOMString & publicId() const { return publicID; }
00863 inline const DOMString & systemId() const { return systemID; }
00866 inline const DOMString internalSubset() const { return DOMString(); }
00867
00868
00869 public:
00871 DocumentType(const DOMString & input) : Node(Node::NodeType::DocumentType), typeName(extractTypeNameFrom(input)), publicID(extractPublicIDFrom(input)), systemID(extractSystemIDFrom(input)) {}
00873 DocumentType(const DOMString & name, const DOMString & pubID, const DOMString & sysID) : Node(Node::NodeType::DocumentType), typeName(name), publicID(pubID), systemID(sysID) {}
00874
00875
00876 private:
00877 DOMString extractItemFrom(const DOMString & input, const tchar * NameToSearch) const
00878 {
00879 DOMString ret;
00880 Strings::FastString xString = Strings::convert(input);
00881 int pos = 0;
00882 while (pos < xString.getLength())
00883 {
00884 Strings::FastString xItem = xString.extractToken(' ', pos);
00885 if (xItem.caselessEqual(NameToSearch))
00886 {
00887 int startPos = pos;
00888 if (pos == xString.getLength()) break;
00889 if (xString[pos] != '"')
00890 {
00891
00892 xItem = xString.extractToken(' ', pos);
00893 } else
00894 {
00895
00896 ++pos;
00897 xItem = xString.extractToken('"', pos);
00898 }
00899
00900 return DOMString(&input.getData()[startPos], pos - startPos - 1);
00901 }
00902 }
00903 return DOMString();
00904
00905 }
00906
00907 inline DOMString extractTypeNameFrom(const DOMString & input) const { return extractItemFrom(input, "DOCTYPE"); }
00908 inline DOMString extractPublicIDFrom(const DOMString & input) const { return extractItemFrom(input, "PUBLIC"); }
00909
00910 DOMString extractSystemIDFrom(const DOMString & input) const
00911 {
00912 DOMString ret = extractItemFrom(input, "SYSTEM");
00913 if (ret.getLength()) return ret;
00914 Strings::FastString xString = Strings::convert(input);
00915 int pos = 0;
00916 while (pos < xString.getLength())
00917 {
00918 Strings::FastString xItem = xString.extractToken(' ', pos);
00919 if (xItem.caselessEqual("PUBLIC"))
00920 {
00921
00922
00923 if (pos == xString.getLength()) break;
00924 if (xString[pos] != '"')
00925 {
00926
00927 xItem = xString.extractToken(' ', pos);
00928 } else
00929 {
00930
00931 ++pos;
00932 xItem = xString.extractToken('"', pos);
00933 ++pos;
00934 }
00935
00936 int startPos = pos;
00937 if (pos == xString.getLength()) break;
00938 if (xString[pos] != '"') break;
00939 ++pos;
00940 if (pos == xString.getLength()) break;
00941 xItem = xString.extractToken('"', pos);
00942
00943 return DOMString(&input.getData()[startPos], pos - startPos - 1);
00944 }
00945 }
00946 return DOMString();
00947 }
00948 };
00949
00950
00952 struct ProcessingInstruction {};
00954 struct DocumentFragment : public Node { DocumentFragment() : Node(NodeType::DocumentFragment) {} };
00956 struct CDATASection : public Text {};
00958 struct EntityReference : public Node {};
00959
00960
00961
00963 struct Comment : public CharacterData
00964 {
00965
00966 public:
00969 virtual DOMString nodeName() const { return DOMString("#comment"); }
00970
00973 virtual Node * Clone(bool deepCopy) const throw() { Node * node = new Comment(data()); DOMTree::Node * tNode = new DOMTree::Node(node); node->setTreeNode(tNode); return node; }
00974
00975
00976 public:
00977 Comment(const DOMString & data, DOMTree::Node * ref = 0) : CharacterData(NodeType::Comment, data, ref) {}
00978 Comment(const Strings::FastString & data, DOMTree::Node * ref = 0) : CharacterData(NodeType::Comment, data, ref) {}
00979 };
00980
00981
00983 class Document : public Node
00984 {
00985
00986 private:
00988 const DocumentType * documentType;
00990 const Element * element;
00992 const volatile HTML::Elements::Allocators::BaseAllocator * allocator;
00993
00994
00995 public:
00998 virtual DOMString nodeName() const { return DOMString("#document"); }
00999
01000
01001 public:
01004 inline const DocumentType * const doctype() const throw() { return documentType; }
01007 inline const DOMImplementation * const implementation() const throw() { return &getCurrentDOMImplementation(allocator);}
01010 inline const Element * const documentElement() const throw() { return element;}
01011
01017 Element * createElement(const DOMString & tagName) const;
01022 inline DocumentFragment * createDocumentFragment() const { return 0; }
01026 Text * createTextNode(const DOMString & data) const throw();
01030 Comment * createComment(const DOMString & data) const throw();
01036 inline CDATASection * createCDATASection(const DOMString & data) const { throw Exceptions::NotSupported(); }
01043 inline ProcessingInstruction * createProcessingInstruction(const DOMString & target, const DOMString & data) const { throw Exceptions::NotSupported(); }
01049 Attr * createAttribute(const DOMString & name) const;
01056 inline EntityReference * createEntityReference(const DOMString & name) const { throw Exceptions::NotSupported(); }
01060 NodeList * getElementsByTagName(const DOMString & tagName) const throw();
01067 const Node * importNode(const Node * importedNode, bool deep);
01070 inline Element * createElementNS(const DOMString & namespaceURI, const DOMString & qualifiedName) const { return 0; }
01073 inline Attr * createAttributeNS(const DOMString & namespaceURI, const DOMString & qualifiedName) const { return 0; }
01076 inline NodeList * getElementsByTagNameNS(const DOMString & namespaceURI, const DOMString & localName) const { return 0; }
01080 const Element * getElementById(const DOMString & elementId) const;
01081
01082
01083 public:
01086 virtual void returnToAllocator(const volatile HTML::Elements::Allocators::BaseAllocator * allocator);
01087
01088
01089 public:
01091 Document(const DOMString & namespaceURI, const DOMString & qualifiedName, const DocumentType * docType, const volatile HTML::Elements::Allocators::BaseAllocator * _allocator, DOMTree::Node * ref = 0, const Element * htmlElement = 0)
01092 : Node(NodeType::Document, ref), element(htmlElement), documentType(docType), allocator(_allocator)
01093 { }
01094
01098 inline bool setHTMLElement(const Element * htmlElement) { if (element || !htmlElement || htmlElement->tagName() != DOMString("HTML")) return false; element = htmlElement; element->setTreeNode(getTreeNode()); return true; }
01099
01100 private:
01104 struct MatchElementByTag : public NodeList
01105 {
01107 DOMTree::Node root;
01109 const HTML::GenericElement::ElementID & elementID;
01110
01112 int searchMethod(const DOM::Node * node);
01114 int removeDataLinks(const DOMTree::Node * node);
01115
01117 MatchElementByTag(const HTML::GenericElement::ElementID & id) : elementID(id), root(0), NodeList(root) { const_cast<uint32 &>(length) = 0; }
01119 ~MatchElementByTag()
01120 {
01121
01122
01123
01124 root.applyOnChildrenNode(*this, &MatchElementByTag::removeDataLinks, true);
01125 }
01126 };
01127
01131 struct MatchElementById : public NodeList
01132 {
01134 DOMTree::Node root;
01136 const DOMString & ID;
01137
01139 int searchMethod(const DOM::Node * node);
01141 int removeDataLinks(const DOMTree::Node * node);
01142
01144 MatchElementById(const DOMString & id) : ID(id), root(0), NodeList(root) {}
01146 ~MatchElementById()
01147 {
01148
01149
01150
01151 root.applyOnChildrenNode(*this, &MatchElementById::removeDataLinks, true);
01152 }
01153 };
01154 };
01155
01157 struct NodeDeleter : public Tree::DeleterObject<const DOM::Node *>
01158 {
01159 typedef Tree::NTree<const DOM::Node *> BaseTree;
01160 typedef BaseTree::Node Node;
01161
01162 const volatile HTML::Elements::Allocators::BaseAllocator & allocatorRef;
01163 inline void deleteNode(Node * node) const;
01164
01166 NodeDeleter(const volatile HTML::Elements::Allocators::BaseAllocator & _allocatorRef) : allocatorRef(_allocatorRef) {}
01167 };
01168
01170 static NodeDeleter & getDefaultNodeDeleter(const volatile HTML::Elements::Allocators::BaseAllocator & allocator);
01171
01172 }
01173
01174 #endif