Rewrite findReferencedElements without recursion

A classic "Depth-First-Search via call stack recusion to
Depth-First-Search with stack" rewrite.  The only thing worth noting
is that the nodes with same parent are visited in opposite order than
originally.  While trivially fixable, none of the callers appear to rely
on the order for anything at all, so I have left that out.

Signed-off-by: Niels Thykier <niels@thykier.net>
This commit is contained in:
Niels Thykier 2018-02-17 14:18:14 +00:00
parent 180d7f8ddb
commit c182faba0d

View file

@ -549,20 +549,23 @@ def findElementsWithId(node, elems=None):
referencingProps = ['fill', 'stroke', 'filter', 'clip-path', 'mask', 'marker-start', 'marker-end', 'marker-mid'] referencingProps = ['fill', 'stroke', 'filter', 'clip-path', 'mask', 'marker-start', 'marker-end', 'marker-mid']
def findReferencedElements(node, ids=None): def findReferencedElements(start_node):
""" """
Returns IDs of all referenced elements Returns IDs of all referenced elements
- node is the node at which to start the search. - start_node is the node at which to start the search.
- returns a map which has the id as key and - returns a map which has the id as key and
each value is is a list of nodes each value is is a list of nodes
Currently looks at 'xlink:href' and all attributes in 'referencingProps' Currently looks at 'xlink:href' and all attributes in 'referencingProps'
""" """
global referencingProps global referencingProps
if ids is None: ids = {}
ids = {}
if 1: # Indent-only # Search all nodes in depth-first search
stack = [start_node]
while stack:
node = stack.pop()
# TODO: input argument ids is clunky here (see below how it is called) # TODO: input argument ids is clunky here (see below how it is called)
# GZ: alternative to passing dict, use **kwargs # GZ: alternative to passing dict, use **kwargs
@ -578,7 +581,7 @@ def findReferencedElements(node, ids=None):
for propname in rule['properties']: for propname in rule['properties']:
propval = rule['properties'][propname] propval = rule['properties'][propname]
findReferencingProperty(node, propname, propval, ids) findReferencingProperty(node, propname, propval, ids)
return ids continue
# else if xlink:href is set, then grab the id # else if xlink:href is set, then grab the id
href = node.getAttributeNS(NS['XLINK'], 'href') href = node.getAttributeNS(NS['XLINK'], 'href')
@ -607,9 +610,8 @@ def findReferencedElements(node, ids=None):
findReferencingProperty(node, attr, val, ids) findReferencingProperty(node, attr, val, ids)
if node.hasChildNodes(): if node.hasChildNodes():
for child in node.childNodes: stack.extend(n for n in node.childNodes if n.nodeType == Node.ELEMENT_NODE)
if child.nodeType == Node.ELEMENT_NODE:
findReferencedElements(child, ids)
return ids return ids