diff --git a/release-notes.html b/release-notes.html index 15b9f6c..91594d8 100644 --- a/release-notes.html +++ b/release-notes.html @@ -13,12 +13,13 @@

Version 0.25

-

2010-05-09

+

2010-07-11

diff --git a/scour.py b/scour.py index 8e0bc3c..161b45c 100755 --- a/scour.py +++ b/scour.py @@ -403,7 +403,10 @@ referencingProps = ['fill', 'stroke', 'filter', 'clip-path', 'mask', 'marker-st def findReferencedElements(node, ids=None): """ Returns the number of times an ID is referenced as well as all elements - that reference it. + that reference it. node is the node at which to start the search. The + return value is a map which has the id as key and each value is an array + where the first value is a count and the second value is a list of nodes + that referenced it. Currently looks at fill, stroke, clip-path, mask, marker, and xlink:href attributes. @@ -775,21 +778,24 @@ def removeNestedGroups(node): num += removeNestedGroups(child) return num -def moveCommonAttributesToParentGroup(elem): +def moveCommonAttributesToParentGroup(elem, referencedElements): """ This recursively calls this function on all children of the passed in element and then iterates over all child elements and removes common inheritable attributes from the children and places them in the parent group. But only if the parent contains - nothing but element children and whitespace. + nothing but element children and whitespace. The attributes are only removed from the + children if the children are not referenced by other elements in the document. """ num = 0 childElements = [] # recurse first into the children (depth-first) for child in elem.childNodes: - if child.nodeType == 1: - childElements.append(child) - num += moveCommonAttributesToParentGroup(child) + if child.nodeType == 1: + # only add and recurse if the child is not referenced elsewhere + if not child.getAttribute('id') in referencedElements: + childElements.append(child) + num += moveCommonAttributesToParentGroup(child, referencedElements) # else if the parent has non-whitespace text children, do not # try to move common attributes elif child.nodeType == 3 and child.nodeValue.strip(): @@ -2655,8 +2661,9 @@ def scourString(in_string, options=None): # all have the same value for an attribute, it must not # get moved to the element. The element # doesn't accept fill=, stroke= etc.! + referencedIds = findReferencedElements(doc.documentElement) for child in doc.documentElement.childNodes: - numAttrsRemoved += moveCommonAttributesToParentGroup(child) + numAttrsRemoved += moveCommonAttributesToParentGroup(child, referencedIds) # remove unused attributes from parent numAttrsRemoved += removeUnusedAttributesOnParent(doc.documentElement) diff --git a/testscour.py b/testscour.py index bd70c40..8349234 100755 --- a/testscour.py +++ b/testscour.py @@ -1097,6 +1097,10 @@ class GroupNoCreation(unittest.TestCase): self.assertEquals(doc.getElementsByTagName('g').length, 0, 'Created a for a run of elements having dissimilar attributes') +class DoNotCommonizeAttributesOnReferencedElements(unittest.TestCase): + def runTest(self): + doc = scour.scourXmlFile('unittests/commonized-referenced-elements.svg') + self.assertEquals(doc.getElementsByTagName('circle')[0].getAttribute('fill'), '#0f0') # TODO: write tests for --enable-viewboxing # TODO; write a test for embedding rasters diff --git a/unittests/commonized-referenced-elements.svg b/unittests/commonized-referenced-elements.svg new file mode 100644 index 0000000..3a84239 --- /dev/null +++ b/unittests/commonized-referenced-elements.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file