scour.py: Use named constants rather than literal integers for `nodeType'

This commit is contained in:
Michael Witten 2017-08-24 20:52:07 +00:00
parent 6734d1ea58
commit 0df46a6cbc

View file

@ -56,6 +56,7 @@ import re
import sys import sys
import time import time
import xml.dom.minidom import xml.dom.minidom
from xml.dom import Node
from collections import namedtuple from collections import namedtuple
from decimal import Context, Decimal, InvalidOperation, getcontext from decimal import Context, Decimal, InvalidOperation, getcontext
@ -540,7 +541,7 @@ def findElementsWithId(node, elems=None):
for child in node.childNodes: for child in node.childNodes:
# from http://www.w3.org/TR/DOM-Level-2-Core/idl-definitions.html # from http://www.w3.org/TR/DOM-Level-2-Core/idl-definitions.html
# we are only really interested in nodes of type Element (1) # we are only really interested in nodes of type Element (1)
if child.nodeType == 1: if child.nodeType == Node.ELEMENT_NODE:
findElementsWithId(child, elems) findElementsWithId(child, elems)
return elems return elems
@ -604,7 +605,7 @@ def findReferencedElements(node, ids=None):
if node.hasChildNodes(): if node.hasChildNodes():
for child in node.childNodes: for child in node.childNodes:
if child.nodeType == 1: if child.nodeType == Node.ELEMENT_NODE:
findReferencedElements(child, ids) findReferencedElements(child, ids)
return ids return ids
@ -645,7 +646,7 @@ def removeUnusedDefs(doc, defElem, elemsToRemove=None):
keepTags = ['font', 'style', 'metadata', 'script', 'title', 'desc'] keepTags = ['font', 'style', 'metadata', 'script', 'title', 'desc']
for elem in defElem.childNodes: for elem in defElem.childNodes:
# only look at it if an element and not referenced anywhere else # only look at it if an element and not referenced anywhere else
if elem.nodeType == 1 and (elem.getAttribute('id') == '' or if elem.nodeType == Node.ELEMENT_NODE and (elem.getAttribute('id') == '' or
elem.getAttribute('id') not in referencedIDs): elem.getAttribute('id') not in referencedIDs):
# we only inspect the children of a group in a defs if the group # we only inspect the children of a group in a defs if the group
# is not referenced anywhere else # is not referenced anywhere else
@ -879,7 +880,7 @@ def removeUnreferencedIDs(referencedIDs, identifiedElements):
def removeNamespacedAttributes(node, namespaces): def removeNamespacedAttributes(node, namespaces):
global _num_attributes_removed global _num_attributes_removed
num = 0 num = 0
if node.nodeType == 1: if node.nodeType == Node.ELEMENT_NODE:
# remove all namespace'd attributes from this element # remove all namespace'd attributes from this element
attrList = node.attributes attrList = node.attributes
attrsToRemove = [] attrsToRemove = []
@ -901,7 +902,7 @@ def removeNamespacedAttributes(node, namespaces):
def removeNamespacedElements(node, namespaces): def removeNamespacedElements(node, namespaces):
global _num_elements_removed global _num_elements_removed
num = 0 num = 0
if node.nodeType == 1: if node.nodeType == Node.ELEMENT_NODE:
# remove all namespace'd child nodes from this element # remove all namespace'd child nodes from this element
childList = node.childNodes childList = node.childNodes
childrenToRemove = [] childrenToRemove = []
@ -959,12 +960,12 @@ def removeNestedGroups(node):
groupsToRemove = [] groupsToRemove = []
# Only consider <g> elements for promotion if this element isn't a <switch>. # Only consider <g> elements for promotion if this element isn't a <switch>.
# (partial fix for bug 594930, required by the SVG spec however) # (partial fix for bug 594930, required by the SVG spec however)
if not (node.nodeType == 1 and node.nodeName == 'switch'): if not (node.nodeType == Node.ELEMENT_NODE and node.nodeName == 'switch'):
for child in node.childNodes: for child in node.childNodes:
if child.nodeName == 'g' and child.namespaceURI == NS['SVG'] and len(child.attributes) == 0: if child.nodeName == 'g' and child.namespaceURI == NS['SVG'] and len(child.attributes) == 0:
# only collapse group if it does not have a title or desc as a direct descendant, # only collapse group if it does not have a title or desc as a direct descendant,
for grandchild in child.childNodes: for grandchild in child.childNodes:
if grandchild.nodeType == 1 and grandchild.namespaceURI == NS['SVG'] and \ if grandchild.nodeType == Node.ELEMENT_NODE and grandchild.namespaceURI == NS['SVG'] and \
grandchild.nodeName in ['title', 'desc']: grandchild.nodeName in ['title', 'desc']:
break break
else: else:
@ -979,7 +980,7 @@ def removeNestedGroups(node):
# now recurse for children # now recurse for children
for child in node.childNodes: for child in node.childNodes:
if child.nodeType == 1: if child.nodeType == Node.ELEMENT_NODE:
num += removeNestedGroups(child) num += removeNestedGroups(child)
return num return num
@ -997,14 +998,14 @@ def moveCommonAttributesToParentGroup(elem, referencedElements):
childElements = [] childElements = []
# recurse first into the children (depth-first) # recurse first into the children (depth-first)
for child in elem.childNodes: for child in elem.childNodes:
if child.nodeType == 1: if child.nodeType == Node.ELEMENT_NODE:
# only add and recurse if the child is not referenced elsewhere # only add and recurse if the child is not referenced elsewhere
if not child.getAttribute('id') in referencedElements: if not child.getAttribute('id') in referencedElements:
childElements.append(child) childElements.append(child)
num += moveCommonAttributesToParentGroup(child, referencedElements) num += moveCommonAttributesToParentGroup(child, referencedElements)
# else if the parent has non-whitespace text children, do not # else if the parent has non-whitespace text children, do not
# try to move common attributes # try to move common attributes
elif child.nodeType == 3 and child.nodeValue.strip(): elif child.nodeType == Node.TEXT_NODE and child.nodeValue.strip():
return num return num
# only process the children if there are more than one element # only process the children if there are more than one element
@ -1102,7 +1103,7 @@ def createGroupsForCommonAttributes(elem):
while curChild >= 0: while curChild >= 0:
childNode = elem.childNodes.item(curChild) childNode = elem.childNodes.item(curChild)
if childNode.nodeType == 1 and childNode.getAttribute(curAttr) != '' and childNode.nodeName in [ if childNode.nodeType == Node.ELEMENT_NODE and childNode.getAttribute(curAttr) != '' and childNode.nodeName in [
# only attempt to group elements that the content model allows to be children of a <g> # only attempt to group elements that the content model allows to be children of a <g>
# SVG 1.1 (see https://www.w3.org/TR/SVG/struct.html#GElement) # SVG 1.1 (see https://www.w3.org/TR/SVG/struct.html#GElement)
@ -1130,7 +1131,7 @@ def createGroupsForCommonAttributes(elem):
# attribute value, preserving any nodes in-between. # attribute value, preserving any nodes in-between.
while runStart > 0: while runStart > 0:
nextNode = elem.childNodes.item(runStart - 1) nextNode = elem.childNodes.item(runStart - 1)
if nextNode.nodeType == 1: if nextNode.nodeType == Node.ELEMENT_NODE:
if nextNode.getAttribute(curAttr) != value: if nextNode.getAttribute(curAttr) != value:
break break
else: else:
@ -1142,7 +1143,7 @@ def createGroupsForCommonAttributes(elem):
if runElements >= 3: if runElements >= 3:
# Include whitespace/comment/etc. nodes in the run. # Include whitespace/comment/etc. nodes in the run.
while runEnd < elem.childNodes.length - 1: while runEnd < elem.childNodes.length - 1:
if elem.childNodes.item(runEnd + 1).nodeType == 1: if elem.childNodes.item(runEnd + 1).nodeType == Node.ELEMENT_NODE:
break break
else: else:
runEnd += 1 runEnd += 1
@ -1186,7 +1187,7 @@ def createGroupsForCommonAttributes(elem):
# each child gets the same treatment, recursively # each child gets the same treatment, recursively
for childNode in elem.childNodes: for childNode in elem.childNodes:
if childNode.nodeType == 1: if childNode.nodeType == Node.ELEMENT_NODE:
num += createGroupsForCommonAttributes(childNode) num += createGroupsForCommonAttributes(childNode)
return num return num
@ -1202,7 +1203,7 @@ def removeUnusedAttributesOnParent(elem):
childElements = [] childElements = []
# recurse first into the children (depth-first) # recurse first into the children (depth-first)
for child in elem.childNodes: for child in elem.childNodes:
if child.nodeType == 1: if child.nodeType == Node.ELEMENT_NODE:
childElements.append(child) childElements.append(child)
num += removeUnusedAttributesOnParent(child) num += removeUnusedAttributesOnParent(child)
@ -1302,11 +1303,11 @@ def collapseSinglyReferencedGradients(doc):
# (Cyn: I've seen documents with #id references but no element with that ID!) # (Cyn: I've seen documents with #id references but no element with that ID!)
if count == 1 and rid in identifiedElements: if count == 1 and rid in identifiedElements:
elem = identifiedElements[rid] elem = identifiedElements[rid]
if elem is not None and elem.nodeType == 1 and elem.nodeName in ['linearGradient', 'radialGradient'] \ if elem is not None and elem.nodeType == Node.ELEMENT_NODE and elem.nodeName in ['linearGradient', 'radialGradient'] \
and elem.namespaceURI == NS['SVG']: and elem.namespaceURI == NS['SVG']:
# found a gradient that is referenced by only 1 other element # found a gradient that is referenced by only 1 other element
refElem = nodes[0] refElem = nodes[0]
if refElem.nodeType == 1 and refElem.nodeName in ['linearGradient', 'radialGradient'] \ if refElem.nodeType == Node.ELEMENT_NODE and refElem.nodeName in ['linearGradient', 'radialGradient'] \
and refElem.namespaceURI == NS['SVG']: and refElem.namespaceURI == NS['SVG']:
# elem is a gradient referenced by only one other gradient (refElem) # elem is a gradient referenced by only one other gradient (refElem)
@ -1448,7 +1449,7 @@ def removeDuplicateGradients(doc):
def _getStyle(node): def _getStyle(node):
u"""Returns the style attribute of a node as a dictionary.""" u"""Returns the style attribute of a node as a dictionary."""
if node.nodeType == 1 and len(node.getAttribute('style')) > 0: if node.nodeType == Node.ELEMENT_NODE and len(node.getAttribute('style')) > 0:
styleMap = {} styleMap = {}
rawStyles = node.getAttribute('style').split(';') rawStyles = node.getAttribute('style').split(';')
for style in rawStyles: for style in rawStyles:
@ -1614,7 +1615,7 @@ def styleInheritedFromParent(node, style):
parentNode = node.parentNode parentNode = node.parentNode
# return None if we reached the Document element # return None if we reached the Document element
if parentNode.nodeType == 9: if parentNode.nodeType == Node.DOCUMENT_NODE:
return None return None
# check styles first (they take precedence over presentation attributes) # check styles first (they take precedence over presentation attributes)
@ -1647,7 +1648,7 @@ def styleInheritedByChild(node, style, nodeIsChild=False):
any style sheets are ignored! any style sheets are ignored!
""" """
# Comment, text and CDATA nodes don't have attributes and aren't containers so they can't inherit attributes # Comment, text and CDATA nodes don't have attributes and aren't containers so they can't inherit attributes
if node.nodeType != 1: if node.nodeType != Node.ELEMENT_NODE:
return False return False
if nodeIsChild: if nodeIsChild:
@ -1702,7 +1703,7 @@ def mayContainTextNodes(node):
result = True # Default value result = True # Default value
# Comment, text and CDATA nodes don't have attributes and aren't containers # Comment, text and CDATA nodes don't have attributes and aren't containers
if node.nodeType != 1: if node.nodeType != Node.ELEMENT_NODE:
result = False result = False
# Non-SVG elements? Unknown elements! # Non-SVG elements? Unknown elements!
elif node.namespaceURI != NS['SVG']: elif node.namespaceURI != NS['SVG']:
@ -1920,7 +1921,7 @@ def removeDefaultAttributeValues(node, options, tainted=set()):
For such attributes, we don't delete attributes with default values.""" For such attributes, we don't delete attributes with default values."""
num = 0 num = 0
if node.nodeType != 1: if node.nodeType != Node.ELEMENT_NODE:
return 0 return 0
# Conditionally remove all default attributes defined in 'default_attributes' (a list of 'DefaultAttribute's) # Conditionally remove all default attributes defined in 'default_attributes' (a list of 'DefaultAttribute's)
@ -1997,7 +1998,7 @@ def convertColors(element):
""" """
numBytes = 0 numBytes = 0
if element.nodeType != 1: if element.nodeType != Node.ELEMENT_NODE:
return 0 return 0
# set up list of color attributes for each element type # set up list of color attributes for each element type
@ -2772,7 +2773,7 @@ def reducePrecision(element):
_setStyle(element, styles) _setStyle(element, styles)
for child in element.childNodes: for child in element.childNodes:
if child.nodeType == 1: if child.nodeType == Node.ELEMENT_NODE:
num += reducePrecision(child) num += reducePrecision(child)
return num return num
@ -2989,7 +2990,7 @@ def optimizeTransforms(element, options):
num += len(val) - len(newVal) num += len(val) - len(newVal)
for child in element.childNodes: for child in element.childNodes:
if child.nodeType == 1: if child.nodeType == Node.ELEMENT_NODE:
num += optimizeTransforms(child, options) num += optimizeTransforms(child, options)
return num return num
@ -3133,7 +3134,7 @@ def properlySizeDoc(docElement, options):
def remapNamespacePrefix(node, oldprefix, newprefix): def remapNamespacePrefix(node, oldprefix, newprefix):
if node is None or node.nodeType != 1: if node is None or node.nodeType != Node.ELEMENT_NODE:
return return
if node.prefix == oldprefix: if node.prefix == oldprefix:
@ -3281,14 +3282,14 @@ def serializeXML(element, options, ind=0, preserveWhitespace=False):
onNewLine = False onNewLine = False
for child in element.childNodes: for child in element.childNodes:
# element node # element node
if child.nodeType == 1: if child.nodeType == Node.ELEMENT_NODE:
if preserveWhitespace: if preserveWhitespace:
outParts.append(serializeXML(child, options, 0, preserveWhitespace)) outParts.append(serializeXML(child, options, 0, preserveWhitespace))
else: else:
outParts.extend([newline, serializeXML(child, options, indent + 1, preserveWhitespace)]) outParts.extend([newline, serializeXML(child, options, indent + 1, preserveWhitespace)])
onNewLine = True onNewLine = True
# text node # text node
elif child.nodeType == 3: elif child.nodeType == Node.TEXT_NODE:
# trim it only in the case of not being a child of an element # trim it only in the case of not being a child of an element
# where whitespace might be important # where whitespace might be important
if preserveWhitespace: if preserveWhitespace:
@ -3296,10 +3297,10 @@ def serializeXML(element, options, ind=0, preserveWhitespace=False):
else: else:
outParts.append(makeWellFormed(child.nodeValue.strip())) outParts.append(makeWellFormed(child.nodeValue.strip()))
# CDATA node # CDATA node
elif child.nodeType == 4: elif child.nodeType == Node.CDATA_SECTION_NODE:
outParts.extend(['<![CDATA[', child.nodeValue, ']]>']) outParts.extend(['<![CDATA[', child.nodeValue, ']]>'])
# Comment node # Comment node
elif child.nodeType == 8: elif child.nodeType == Node.COMMENT_NODE:
outParts.extend(['<!--', child.nodeValue, '-->']) outParts.extend(['<!--', child.nodeValue, '-->'])
# TODO: entities, processing instructions, what else? # TODO: entities, processing instructions, what else?
else: # ignore the rest else: # ignore the rest
@ -3468,9 +3469,9 @@ def scourString(in_string, options=None):
removeElem = not elem.hasChildNodes() removeElem = not elem.hasChildNodes()
if removeElem is False: if removeElem is False:
for child in elem.childNodes: for child in elem.childNodes:
if child.nodeType in [1, 4, 8]: if child.nodeType in [Node.ELEMENT_NODE, Node.CDATA_SECTION_NODE, Node.COMMENT_NODE]:
break break
elif child.nodeType == 3 and not child.nodeValue.isspace(): elif child.nodeType == Node.TEXT_NODE and not child.nodeValue.isspace():
break break
else: else:
removeElem = True removeElem = True
@ -3594,7 +3595,7 @@ def scourString(in_string, options=None):
total_output = "" total_output = ""
for child in doc.childNodes: for child in doc.childNodes:
if child.nodeType == 1: if child.nodeType == Node.ELEMENT_NODE:
total_output += "".join(lines) total_output += "".join(lines)
else: # doctypes, entities, comments else: # doctypes, entities, comments
total_output += child.toxml() + '\n' total_output += child.toxml() + '\n'