summaryrefslogtreecommitdiff
path: root/src/domhelpers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/domhelpers.cpp')
-rw-r--r--src/domhelpers.cpp153
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();
+}