mirror of
https://github.com/jezhiggins/arabica
synced 2025-01-17 18:12:04 +01:00
DOM Level 1 Conformance fixes found with first pass of W3C conf tests
This commit is contained in:
parent
244217f8f1
commit
33d08c77a1
20 changed files with 89 additions and 21 deletions
|
@ -31,6 +31,8 @@ class Attr : public Node<stringT, string_adaptorT>
|
|||
Attr(const Attr& rhs) : NodeT(rhs) { }
|
||||
explicit Attr(const NodeT& rhs) : NodeT(rhs)
|
||||
{
|
||||
if(NodeT::impl_ == 0) // null nodes can always be cast
|
||||
return;
|
||||
if(rhs.getNodeType() != NodeT::ATTRIBUTE_NODE)
|
||||
throw std::bad_cast();
|
||||
} // Attr
|
||||
|
|
|
@ -25,6 +25,8 @@ class CDATASection : public Text<stringT, string_adaptorT>
|
|||
CDATASection(const CDATASection& rhs) : Text<stringT, string_adaptorT>(rhs) { }
|
||||
explicit CDATASection(const Node<stringT, string_adaptorT>& rhs) : Text<stringT, string_adaptorT>(rhs, 0)
|
||||
{
|
||||
if(NodeT::impl_ == 0) // null nodes can always be cast
|
||||
return;
|
||||
if(rhs.getNodeType() != Node_base::CDATA_SECTION_NODE)
|
||||
//throw std::runtime_error("bad_cast: Cannot convert Node to CDATA section");
|
||||
throw std::bad_cast();
|
||||
|
|
|
@ -27,6 +27,8 @@ class CharacterData : public Node<stringT, string_adaptorT>
|
|||
CharacterData(const CharacterData& rhs) : NodeT(rhs) { }
|
||||
explicit CharacterData(const NodeT& rhs) : NodeT(rhs)
|
||||
{
|
||||
if(NodeT::impl_ == 0) // null nodes can always be cast
|
||||
return;
|
||||
typename NodeT::Type type = rhs.getNodeType();
|
||||
if((type != NodeT::TEXT_NODE) && (type != NodeT::CDATA_SECTION_NODE))
|
||||
throw std::runtime_error("bad_cast: Cannot cast Node to Character Data");
|
||||
|
|
|
@ -24,7 +24,9 @@ class Comment : public CharacterData<stringT, string_adaptorT>
|
|||
Comment(const Comment& rhs) : CharacterData<stringT, string_adaptorT>(rhs) { }
|
||||
explicit Comment(const Node<stringT, string_adaptorT>& rhs) : CharacterData<stringT, string_adaptorT>(rhs)
|
||||
{
|
||||
if(dynamic_cast<Comment_impl<stringT, string_adaptorT>*>(rhs.impl()) == 0)
|
||||
if(NodeT::impl_ == 0) // null nodes can always be cast
|
||||
return;
|
||||
if(rhs.getNodeType() != Node<stringT, string_adaptorT>::COMMENT_NODE)
|
||||
throw std::bad_cast();
|
||||
} // Comment
|
||||
}; // class Comment
|
||||
|
|
|
@ -45,6 +45,8 @@ class Document : public Node<stringT, string_adaptorT>
|
|||
Document(const Document& rhs) : Node<stringT, string_adaptorT>(rhs) { }
|
||||
explicit Document(const Node<stringT, string_adaptorT>& rhs) : Node<stringT, string_adaptorT>(rhs)
|
||||
{
|
||||
if(NodeT::impl_ == 0) // null nodes can always be cast
|
||||
return;
|
||||
if(rhs.getNodeType() != Node<stringT, string_adaptorT>::DOCUMENT_NODE)
|
||||
throw std::bad_cast();
|
||||
} // Document
|
||||
|
|
|
@ -26,6 +26,8 @@ class DocumentFragment : public Node<stringT, string_adaptorT>
|
|||
DocumentFragment(const DocumentFragment& rhs) : Node<stringT, string_adaptorT>(rhs) { }
|
||||
explicit DocumentFragment(const Node<stringT, string_adaptorT>& rhs) : Node<stringT, string_adaptorT>(rhs)
|
||||
{
|
||||
if(NodeT::impl_ == 0) // null nodes can always be cast
|
||||
return;
|
||||
if(rhs.getNodeType() != Node<stringT, string_adaptorT>::DOCUMENT_FRAGMENT_NODE)
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ class DocumentType : public Node<stringT, string_adaptorT>
|
|||
DocumentType(const DocumentType& rhs) : NodeT(rhs) { }
|
||||
explicit DocumentType(const NodeT& rhs) : NodeT(rhs)
|
||||
{
|
||||
if(NodeT::impl_ == 0) // null nodes can always be cast
|
||||
return;
|
||||
if(rhs.getNodeType() != NodeT::DOCUMENT_TYPE_NODE)
|
||||
throw std::bad_cast();
|
||||
} // DocumentType
|
||||
|
|
|
@ -34,6 +34,8 @@ class Element : public Node<stringT, string_adaptorT>
|
|||
Element(const Element& rhs) : NodeT(rhs) { }
|
||||
explicit Element(const NodeT& rhs) : NodeT(rhs)
|
||||
{
|
||||
if(NodeT::impl_ == 0) // null nodes can always be cast
|
||||
return;
|
||||
if(rhs.getNodeType() != NodeT::ELEMENT_NODE)
|
||||
throw std::bad_cast();
|
||||
} // Element
|
||||
|
|
|
@ -24,22 +24,24 @@ class Entity : public Node<stringT, string_adaptorT>
|
|||
typedef Entity_impl<stringT, string_adaptorT> Entity_implT;
|
||||
|
||||
Entity() : Node<stringT, string_adaptorT>() { }
|
||||
explicit Entity(Entity_impl<stringT, string_adaptorT>* impl) : Node<stringT>(impl) { }
|
||||
explicit Entity(Entity_impl<stringT, string_adaptorT>* impl) : Node<stringT, string_adaptorT>(impl) { }
|
||||
Entity(const Entity& rhs) : Node<stringT, string_adaptorT>(rhs) { }
|
||||
explicit Entity(const Node<stringT, string_adaptorT>& rhs) : Node<stringT>(rhs)
|
||||
explicit Entity(const Node<stringT, string_adaptorT>& rhs) : Node<stringT, string_adaptorT>(rhs)
|
||||
{
|
||||
if(rhs.getNodeType() != Node<stringT, string_adaptorT>::Entity_NODE)
|
||||
if(NodeT::impl_ == 0) // null nodes can always be cast
|
||||
return;
|
||||
if(rhs.getNodeType() != Node_base::ENTITY_NODE)
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
||||
stringT getPublicId() const { nImpl()->getPublicId(); }
|
||||
stringT getPublicId() const { return nImpl()->getPublicId(); }
|
||||
|
||||
stringT getSystemId() const { nImpl()->getSystemId(); }
|
||||
stringT getSystemId() const { return nImpl()->getSystemId(); }
|
||||
|
||||
stringT getNotationName() const { nImpl()->getNotationName(); }
|
||||
stringT getNotationName() const { return nImpl()->getNotationName(); }
|
||||
|
||||
private:
|
||||
Entity_implT* nImpl() { return dynamic_cast<Entity_implT*>(NodeT::impl()); }
|
||||
Entity_implT* nImpl() const { return dynamic_cast<Entity_implT*>(*NodeT::impl_); }
|
||||
}; // class Entity
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
|
|
@ -28,7 +28,9 @@ class EntityReference : public Node<stringT, string_adaptorT>
|
|||
EntityReference(const EntityReference& rhs) : NodeT(rhs) { }
|
||||
explicit EntityReference(const NodeT& rhs) : NodeT(rhs)
|
||||
{
|
||||
if(dynamic_cast<EntityReference_implT*>(rhs.impl()) == 0)
|
||||
if(NodeT::impl_ == 0) // null nodes can always be cast
|
||||
return;
|
||||
if(rhs.getNodeType() != Node_base::ENTITY_REFERENCE_NODE)
|
||||
throw std::bad_cast();
|
||||
} // EntityReference
|
||||
}; // class EntityReference
|
||||
|
|
|
@ -39,7 +39,12 @@ class NodeList
|
|||
|
||||
Node<stringT, string_adaptorT> item(unsigned int index) const { return impl_->item(index); }
|
||||
|
||||
unsigned int getLength() const { return impl_->getLength(); }
|
||||
unsigned int getLength() const
|
||||
{
|
||||
if(impl_ == 0)
|
||||
return 0;
|
||||
return impl_->getLength();
|
||||
} // getLength
|
||||
|
||||
private:
|
||||
Proxy<NodeList_impl<stringT, string_adaptorT> > impl_;
|
||||
|
|
|
@ -29,16 +29,18 @@ class Notation : public Node<stringT, string_adaptorT>
|
|||
Notation(const Notation& rhs) : NodeT(rhs) { }
|
||||
explicit Notation(const NodeT& rhs) : NodeT(rhs)
|
||||
{
|
||||
if(NodeT::impl_ == 0) // null nodes can always be cast
|
||||
return;
|
||||
if(rhs.getNodeType() != Node_base::NOTATION_NODE)
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
||||
stringT getPublicId() const { nImpl()->getPublicId(); }
|
||||
stringT getPublicId() const { return nImpl()->getPublicId(); }
|
||||
|
||||
stringT getSystemId() const { nImpl()->getSystemId(); }
|
||||
stringT getSystemId() const { return nImpl()->getSystemId(); }
|
||||
|
||||
private:
|
||||
Notation_implT* nImpl() { return dynamic_cast<Notation_implT*>(NodeT::impl()); }
|
||||
Notation_implT* nImpl() const { return dynamic_cast<Notation_implT*>(*NodeT::impl_); }
|
||||
}; // class Notation
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
|
|
@ -26,6 +26,8 @@ class ProcessingInstruction : public Node<stringT, string_adaptorT>
|
|||
ProcessingInstruction(const ProcessingInstruction& rhs) : Node<stringT, string_adaptorT>(rhs) { }
|
||||
explicit ProcessingInstruction(const Node<stringT, string_adaptorT>& rhs) : Node<stringT, string_adaptorT>(rhs)
|
||||
{
|
||||
if(NodeT::impl_ == 0) // null nodes can always be cast
|
||||
return;
|
||||
if(rhs.getNodeType() != Node<stringT, string_adaptorT>::PROCESSING_INSTRUCTION_NODE)
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
|
|
@ -134,6 +134,14 @@ class AttrImpl : public DOM::Attr_impl<stringT, string_adaptorT>,
|
|||
|
||||
void setSpecified(bool specified) { specified_ = specified; }
|
||||
|
||||
bool isOrphaned()
|
||||
{
|
||||
if(!ownerElement_)
|
||||
return true;
|
||||
|
||||
return NodeT::ownerDoc_->isOrphaned(this);
|
||||
} // isOrphaned
|
||||
|
||||
protected:
|
||||
void cloneChildren(AttrImpl* clone) const
|
||||
{
|
||||
|
|
|
@ -61,9 +61,15 @@ class AttrMap : public NamedNodeMapImpl<stringT, string_adaptorT>
|
|||
|
||||
DOMAttr_implT* setAttributeNode(DOMAttr_implT* newAttr)
|
||||
{
|
||||
return dynamic_cast<DOMAttr_implT*>(setNamedItem(newAttr));
|
||||
} // setAttributeNode
|
||||
virtual DOMNode_implT* setNamedItem(DOMNode_implT* newAttr)
|
||||
{
|
||||
throwIfReadOnly();
|
||||
checkNotInUse(newAttr);
|
||||
dynamic_cast<AttrImplT*>(newAttr)->setOwnerElement(ownerElement_);
|
||||
return dynamic_cast<DOMAttr_implT*>(NamedNodeMapImplT::setNamedItem(newAttr));
|
||||
} // setAttributeNode
|
||||
} // setNamedItem
|
||||
|
||||
DOMAttr_implT* removeAttributeNode(DOMAttr_implT* oldAttr)
|
||||
{
|
||||
|
@ -103,9 +109,15 @@ class AttrMap : public NamedNodeMapImpl<stringT, string_adaptorT>
|
|||
|
||||
DOMAttr_implT* setAttributeNodeNS(DOMAttr_implT* newAttr)
|
||||
{
|
||||
return dynamic_cast<DOMAttr_implT*>(setNamedItemNS(newAttr));
|
||||
} // setAttributeNodeNS
|
||||
virtual DOMNode_implT* setNamedItemNS(DOMNode_implT* newAttr)
|
||||
{
|
||||
throwIfReadOnly();
|
||||
checkNotInUse(newAttr);
|
||||
dynamic_cast<AttrImplT*>(newAttr)->setOwnerElement(ownerElement_);
|
||||
return dynamic_cast<DOMAttr_implT*>(NamedNodeMapImplT::setNamedItemNS(newAttr));
|
||||
} // setAttributeNodeNS
|
||||
} // setNamedItem
|
||||
|
||||
bool hasAttribute(const stringT& name) const
|
||||
{
|
||||
|
@ -181,6 +193,13 @@ class AttrMap : public NamedNodeMapImpl<stringT, string_adaptorT>
|
|||
return 0;
|
||||
} // getDefaultAttrs
|
||||
|
||||
void checkNotInUse(DOMNode_implT* newAttr)
|
||||
{
|
||||
AttrImplT* attr = dynamic_cast<AttrImplT*>(newAttr);
|
||||
if(!attr->isOrphaned())
|
||||
throw DOM::DOMException(DOM::DOMException::INUSE_ATTRIBUTE_ERR);
|
||||
} // checkNotInUse
|
||||
|
||||
ElementImplT* ownerElement_;
|
||||
}; // class AttrMap
|
||||
|
||||
|
|
|
@ -437,6 +437,11 @@ class DocumentImpl : public DOM::Document_impl<stringT, string_adaptorT>,
|
|||
orphans_.insert(node);
|
||||
} // orphaned
|
||||
|
||||
bool isOrphaned(NodeImplT* node) const
|
||||
{
|
||||
return orphans_.find(node) != orphans_.end();
|
||||
} // isOrphaned
|
||||
|
||||
void purge(NodeImplT* node)
|
||||
{
|
||||
orphans_.erase(node);
|
||||
|
|
|
@ -94,10 +94,10 @@ class ElementByTagList : public DOM::NodeList_impl<stringT, string_adaptorT>
|
|||
private:
|
||||
void populate() const
|
||||
{
|
||||
NodeListT dummy;
|
||||
NodeListT dummy;
|
||||
nodes_.swap(dummy);
|
||||
|
||||
checkNode(rootNode_);
|
||||
checkChildren(rootNode_);
|
||||
|
||||
changes_ = ownerDoc_->changes();
|
||||
} // populate
|
||||
|
@ -116,11 +116,15 @@ class ElementByTagList : public DOM::NodeList_impl<stringT, string_adaptorT>
|
|||
if((tagName_ == node->getNodeName()) || (allNames_ && node->getNodeType() == DOM::Node<stringT, string_adaptorT>::ELEMENT_NODE))
|
||||
nodes_.push_back(node);
|
||||
|
||||
checkChildren(node);
|
||||
} // checkNode
|
||||
|
||||
void checkChildren(DOM::Node_impl<stringT, string_adaptorT>* node) const
|
||||
{
|
||||
for(DOM::Node_impl<stringT, string_adaptorT>* child = node->getFirstChild(); child != 0; child = child->getNextSibling())
|
||||
if(child->getNodeType() == DOM::Node<stringT, string_adaptorT>::ELEMENT_NODE)
|
||||
checkNode(child);
|
||||
} // checkNode
|
||||
|
||||
} // checkChildren
|
||||
|
||||
typedef std::deque<DOM::Node_impl<stringT, string_adaptorT>*> NodeListT;
|
||||
mutable NodeListT nodes_;
|
||||
|
|
|
@ -160,13 +160,14 @@ class NamedNodeMapImpl : public DOM::NamedNodeMap_impl<stringT, string_adaptorT>
|
|||
return nodes_[index];
|
||||
} // item
|
||||
|
||||
private:
|
||||
protected:
|
||||
void throwIfReadOnly() const
|
||||
{
|
||||
if(readOnly_)
|
||||
throw DOM::DOMException(DOM::DOMException::NO_MODIFICATION_ALLOWED_ERR);
|
||||
} // throwIfReadOnly
|
||||
|
||||
private:
|
||||
typedef std::deque<NodeImplT*> NodeListT;
|
||||
|
||||
NodeImplT* getNode(typename NodeListT::const_iterator n) const
|
||||
|
|
|
@ -416,8 +416,8 @@ class NodeImplWithChildren : public NodeImpl<stringT, string_adaptorT>,
|
|||
} // if ...
|
||||
|
||||
checkCanAdd(newChild);
|
||||
typename std::deque<NodeImplT*>::iterator result = findChild(oldChild);
|
||||
removeIfRequired(newChild);
|
||||
typename std::deque<NodeImplT*>::iterator result = findChild(oldChild);
|
||||
*result = newChild;
|
||||
newChild->setParentNode(this);
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ class Text : public CharacterData<stringT, string_adaptorT>
|
|||
Text(const Text& rhs) : CharacterDataT(rhs) { }
|
||||
explicit Text(const NodeT& rhs) : CharacterDataT(rhs, 0)
|
||||
{
|
||||
if(NodeT::impl_ == 0) // null nodes can always be cast
|
||||
return;
|
||||
typename Text::Type type = rhs.getNodeType();
|
||||
if((type != Text::TEXT_NODE) && (type != Text::CDATA_SECTION_NODE))
|
||||
//throw std::runtime_error("bad_cast: Cannot cast Node to Text");
|
||||
|
|
Loading…
Reference in a new issue