diff options
Diffstat (limited to 'src/domhelpers.cpp')
-rw-r--r-- | src/domhelpers.cpp | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/src/domhelpers.cpp b/src/domhelpers.cpp index 6cf8052..ac93f10 100644 --- a/src/domhelpers.cpp +++ b/src/domhelpers.cpp @@ -40,6 +40,8 @@ #include "domhelpers.h" #include "tags.h" +using std::make_pair; + bool DOMHelpers::isElement(const DOM::Node& node, const string& name) { return node != NULL && node.getNodeType() == DOM::Node::ELEMENT_NODE && @@ -176,3 +178,154 @@ void DOMHelpers::insertAfter(DOM::Node& parent, const DOM::Node& node, else parent.insertBefore(node, sibling); } + +DOM::Element DOMHelpers::getChildElement(const DOM::Node& parent, const string& name) +{ + DOM::Node child = parent.getFirstChild(); + while(child != NULL) + { + if(isElement(child, name)) + return (DOM::Element&)child; + } + + return DOM::Element(); +} + +bool DOMHelpers::hasAncestor(const DOM::Node& ancestor, const DOM::Node& node) +{ + DOM::Node n = node; + + while(n != NULL) + { + if(n == ancestor) + return true; + + n = n.getParentNode(); + } + + return false; +} + + +/* ---------------------------------------------------------------------------------- + * ElementTable + */ + +void ElementTable::load(const DOM::Node& parent, const string& name) +{ + clear(); + + DOM::Node child = parent.getFirstChild(); + while(child != NULL) + { + if(DOMHelpers::isElement(child, name)) + { + DOM::Element& el = (DOM::Element&)child; + wstring id = el.getAttribute(kAtId); + + if(!id.empty()) + insert(make_pair(id, el)); + } + } +} + +DOM::Element ElementTable::get(const wstring& id) const +{ + const_iterator it = find(id); + return it == end() ? DOM::Element() : it->second; +} + +void ElementTable::removeIds() +{ + iterator it = begin(); + iterator e = end(); + + for( ; it != e; it++) + it->second.removeAttribute(kAtId); +} + +/* ---------------------------------------------------------------------------------- + * ElementIterator + */ + +void ElementIterator::next() +{ + if(m_current == NULL) + return; + + DOM::Node n; + + // Always descend into children first + if(m_current.hasChildNodes()) + { + m_current = nextel(m_current.getFirstChild()); + if(m_current != NULL) + return; + } + + // Look for siblings along the current level + m_current = nextel(m_current.getNextSibling()); + if(m_current != NULL) + return; + + // Go back up to parent + m_current = m_current.getParentNode(); + + // But check top against parent + if(m_current == NULL || m_current == m_top) + m_current = NULL; +} + +DOM::Element ElementIterator::nextel(DOM::Node node) +{ + while(node != NULL) + { + if(node.getNodeType() == DOM::Element::ELEMENT_NODE) + return (DOM::Element&)node; + + node = node.getNextSibling(); + } + + return DOM::Element(); +} + +void ElementIterator::prev() +{ + /* Allow backing into the iterator */ + if(m_current == NULL) + m_current = m_top; + + DOM::Node n; + + // Always descend into children first + if(m_current.hasChildNodes()) + { + m_current = prevel(m_current.getLastChild()); + if(m_current != NULL) + return; + } + + // Look for siblings along the current level + m_current = prevel(m_current.getPreviousSibling()); + if(m_current != NULL) + return; + + // Go back up to parent + DOM::Node parent = m_current.getParentNode(); + if(parent != m_top) + m_current = (DOM::Element&)parent; +} + + +DOM::Element ElementIterator::prevel(DOM::Node node) +{ + while(node != NULL) + { + if(node.getNodeType() == DOM::Element::ELEMENT_NODE) + return (DOM::Element&)node; + + node = node.getPreviousSibling(); + } + + return DOM::Element(); +} |