diff --git a/scour/scour.py b/scour/scour.py index 9d19906..da57c3d 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -646,7 +646,7 @@ def removeUnusedDefs(doc, defElem, elemsToRemove=None, referencedIDs=None): # removeUnusedDefs do not change the XML itself; therefore there is no point in # recomputing findReferencedElements when we recurse into child nodes. if referencedIDs is None: - referencedIDs = findReferencedElements(doc.documentElement) + referencedIDs = set(findReferencedElements(doc.documentElement).keys()) keepTags = ['font', 'style', 'metadata', 'script', 'title', 'desc'] for elem in defElem.childNodes: @@ -660,10 +660,13 @@ def removeUnusedDefs(doc, defElem, elemsToRemove=None, referencedIDs=None): # we only inspect the children of a group in a defs if the group # is not referenced anywhere else if elem.nodeName == 'g' and elem.namespaceURI == NS['SVG']: - elemsToRemove = removeUnusedDefs(doc, elem, elemsToRemove, referencedIDs=referencedIDs) + removeUnusedDefs(doc, elem, elemsToRemove, referencedIDs=referencedIDs) # we only remove if it is not one of our tags we always keep (see above) + # also we can't remove an element if a child is referenced elif elem.nodeName not in keepTags: - elemsToRemove.append(elem) + if (set(findElementsWithId(elem).keys()).intersection(referencedIDs) == set() or + elem.tagName == 'defs'): + elemsToRemove.append(elem) return elemsToRemove diff --git a/test_scour.py b/test_scour.py index 549333f..0f969f7 100755 --- a/test_scour.py +++ b/test_scour.py @@ -379,6 +379,13 @@ def runTest(self): self.assertEqual(len(doc.getElementsByTagNameNS(SVGNS, 'circle')), 1, 'Unreferenced circle removed from defs with `--keep-unreferenced-defs`') +class KeepUnreferencedElementWithReferencedChild(unittest.TestCase): + def runTest(self): + doc = scourXmlFile('unittests/referenced_child.svg') + + self.assertEqual(len(doc.getElementsByTagNameNS(SVGNS, 'rect')), 1, + 'Referenced element was deleted') + class DoNotRemoveChainedRefsInDefs(unittest.TestCase): diff --git a/unittests/referenced_child.svg b/unittests/referenced_child.svg new file mode 100644 index 0000000..f5c79be --- /dev/null +++ b/unittests/referenced_child.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file