Skip to content

Commit

Permalink
Fix wrong recursion in getElementsByTagName implementation; close #35
Browse files Browse the repository at this point in the history
  • Loading branch information
lodo1995 committed Nov 7, 2016
1 parent c3e48eb commit 0ab3681
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 36 deletions.
57 changes: 26 additions & 31 deletions source/std/experimental/xml/domimpl.d
Original file line number Diff line number Diff line change
Expand Up @@ -1091,54 +1091,48 @@ class DOMImplementation(DOMString, Alloc = shared(GCAllocator), ErrorHandler = b
else
private DOMString tagname;

private Element findNext(Node node)
private bool check(Node node)
{
foreach (item; node.childNodes)
static if (ns)
{
static if (ns)
if (node.nodeType == dom.NodeType.element)
{
if (item.nodeType == dom.NodeType.element)
{
auto elem = cast(Element)item;
if (elem.namespaceURI == namespaceURI && elem.localName == localName)
return elem;
}
auto elem = cast(Element)node;
return elem.namespaceURI == namespaceURI && elem.localName == localName;
}
else
if (item.nodeType == dom.NodeType.element && item.nodeName == tagname)
return cast(Element)item;
return false;
}
else
return node.nodeType == dom.NodeType.element && node.nodeName == tagname;
}

auto res = findNext(item);
if (res !is null)
return res;
private Element findNext(Node node)
{
if (node.firstChild)
{
auto item = node.firstChild;
if (check(item))
return cast(Element)item;
else
return findNext(item);
}
return findNextBack(node);
else
return findNextBack(node);
}
private Element findNextBack(Node node)
{
if (node.nextSibling)
{
auto item = node.nextSibling;

static if (ns)
{
if (item.nodeType == dom.NodeType.element)
{
auto elem = cast(Element)item;
if (elem.namespaceURI == namespaceURI && elem.localName == localName)
return elem;
}
}
if (check(item))
return cast(Element)item;
else
if (item.nodeType == dom.NodeType.element && item.nodeName == tagname)
return cast(Element)item;

return findNext(item);
return findNext(item);
}
else if (node.parentNode && node.parentNode !is root)
{
else if (node.parentNode && node.parentNode !is node.ownerDocument)
return findNextBack(node.parentNode);
}
else
return null;
}
Expand All @@ -1152,6 +1146,7 @@ class DOMImplementation(DOMString, Alloc = shared(GCAllocator), ErrorHandler = b
auto node = findNext(root);
while (node !is null)
{
//writeln("Found node ", node.nodeName);
res++;
node = findNext(node);
}
Expand Down
16 changes: 11 additions & 5 deletions source/std/experimental/xml/domparser.d
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,8 @@ struct DOMBuilder(T, DOMImplementation = dom.DOMImplementation!(T.StringType))
domImpl = impl;
}

/++
+ Initializes this builder and the underlying components.
+/
void setSource(T.InputType input)
private void initialize()
{
cursor.setSource(input);
document = domImpl.createDocument(null, null, null);

if (cursor.kind == XMLKind.document)
Expand All @@ -85,6 +81,15 @@ struct DOMBuilder(T, DOMImplementation = dom.DOMImplementation!(T.StringType))
currentNode = document;
}

/++
+ Initializes this builder and the underlying components.
+/
void setSource(T.InputType input)
{
cursor.setSource(input);
initialize();
}

/++
+ Same as `cursor.enter`. When entering a node, that node is automatically
+ built into the DOM, so that its children can then be safely built if needed.
Expand Down Expand Up @@ -212,6 +217,7 @@ auto domBuilder(CursorType, DOMImplementation)(auto ref CursorType cursor, DOMIm
auto res = DOMBuilder!(CursorType, DOMImplementation)();
res.cursor = cursor;
res.domImpl = impl;
res.initialize;
return res;
}

Expand Down

0 comments on commit 0ab3681

Please sign in to comment.