| Index: third_party/WebKit/Tools/Scripts/webkitpy/thirdparty/wpt/wpt/tools/html5lib/html5lib/treebuilders/etree.py
|
| diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/thirdparty/wpt/wpt/tools/html5lib/html5lib/treebuilders/etree.py b/third_party/WebKit/Tools/Scripts/webkitpy/thirdparty/wpt/wpt/tools/html5lib/html5lib/treebuilders/etree.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..2c8ed19f8fe83c9fc866a9b48a06cd4e0fd46889
|
| --- /dev/null
|
| +++ b/third_party/WebKit/Tools/Scripts/webkitpy/thirdparty/wpt/wpt/tools/html5lib/html5lib/treebuilders/etree.py
|
| @@ -0,0 +1,337 @@
|
| +from __future__ import absolute_import, division, unicode_literals
|
| +from six import text_type
|
| +
|
| +import re
|
| +
|
| +from . import _base
|
| +from .. import ihatexml
|
| +from .. import constants
|
| +from ..constants import namespaces
|
| +from ..utils import moduleFactoryFactory
|
| +
|
| +tag_regexp = re.compile("{([^}]*)}(.*)")
|
| +
|
| +
|
| +def getETreeBuilder(ElementTreeImplementation, fullTree=False):
|
| + ElementTree = ElementTreeImplementation
|
| + ElementTreeCommentType = ElementTree.Comment("asd").tag
|
| +
|
| + class Element(_base.Node):
|
| + def __init__(self, name, namespace=None):
|
| + self._name = name
|
| + self._namespace = namespace
|
| + self._element = ElementTree.Element(self._getETreeTag(name,
|
| + namespace))
|
| + if namespace is None:
|
| + self.nameTuple = namespaces["html"], self._name
|
| + else:
|
| + self.nameTuple = self._namespace, self._name
|
| + self.parent = None
|
| + self._childNodes = []
|
| + self._flags = []
|
| +
|
| + def _getETreeTag(self, name, namespace):
|
| + if namespace is None:
|
| + etree_tag = name
|
| + else:
|
| + etree_tag = "{%s}%s" % (namespace, name)
|
| + return etree_tag
|
| +
|
| + def _setName(self, name):
|
| + self._name = name
|
| + self._element.tag = self._getETreeTag(self._name, self._namespace)
|
| +
|
| + def _getName(self):
|
| + return self._name
|
| +
|
| + name = property(_getName, _setName)
|
| +
|
| + def _setNamespace(self, namespace):
|
| + self._namespace = namespace
|
| + self._element.tag = self._getETreeTag(self._name, self._namespace)
|
| +
|
| + def _getNamespace(self):
|
| + return self._namespace
|
| +
|
| + namespace = property(_getNamespace, _setNamespace)
|
| +
|
| + def _getAttributes(self):
|
| + return self._element.attrib
|
| +
|
| + def _setAttributes(self, attributes):
|
| + # Delete existing attributes first
|
| + # XXX - there may be a better way to do this...
|
| + for key in list(self._element.attrib.keys()):
|
| + del self._element.attrib[key]
|
| + for key, value in attributes.items():
|
| + if isinstance(key, tuple):
|
| + name = "{%s}%s" % (key[2], key[1])
|
| + else:
|
| + name = key
|
| + self._element.set(name, value)
|
| +
|
| + attributes = property(_getAttributes, _setAttributes)
|
| +
|
| + def _getChildNodes(self):
|
| + return self._childNodes
|
| +
|
| + def _setChildNodes(self, value):
|
| + del self._element[:]
|
| + self._childNodes = []
|
| + for element in value:
|
| + self.insertChild(element)
|
| +
|
| + childNodes = property(_getChildNodes, _setChildNodes)
|
| +
|
| + def hasContent(self):
|
| + """Return true if the node has children or text"""
|
| + return bool(self._element.text or len(self._element))
|
| +
|
| + def appendChild(self, node):
|
| + self._childNodes.append(node)
|
| + self._element.append(node._element)
|
| + node.parent = self
|
| +
|
| + def insertBefore(self, node, refNode):
|
| + index = list(self._element).index(refNode._element)
|
| + self._element.insert(index, node._element)
|
| + node.parent = self
|
| +
|
| + def removeChild(self, node):
|
| + self._element.remove(node._element)
|
| + node.parent = None
|
| +
|
| + def insertText(self, data, insertBefore=None):
|
| + if not(len(self._element)):
|
| + if not self._element.text:
|
| + self._element.text = ""
|
| + self._element.text += data
|
| + elif insertBefore is None:
|
| + # Insert the text as the tail of the last child element
|
| + if not self._element[-1].tail:
|
| + self._element[-1].tail = ""
|
| + self._element[-1].tail += data
|
| + else:
|
| + # Insert the text before the specified node
|
| + children = list(self._element)
|
| + index = children.index(insertBefore._element)
|
| + if index > 0:
|
| + if not self._element[index - 1].tail:
|
| + self._element[index - 1].tail = ""
|
| + self._element[index - 1].tail += data
|
| + else:
|
| + if not self._element.text:
|
| + self._element.text = ""
|
| + self._element.text += data
|
| +
|
| + def cloneNode(self):
|
| + element = type(self)(self.name, self.namespace)
|
| + for name, value in self.attributes.items():
|
| + element.attributes[name] = value
|
| + return element
|
| +
|
| + def reparentChildren(self, newParent):
|
| + if newParent.childNodes:
|
| + newParent.childNodes[-1]._element.tail += self._element.text
|
| + else:
|
| + if not newParent._element.text:
|
| + newParent._element.text = ""
|
| + if self._element.text is not None:
|
| + newParent._element.text += self._element.text
|
| + self._element.text = ""
|
| + _base.Node.reparentChildren(self, newParent)
|
| +
|
| + class Comment(Element):
|
| + def __init__(self, data):
|
| + # Use the superclass constructor to set all properties on the
|
| + # wrapper element
|
| + self._element = ElementTree.Comment(data)
|
| + self.parent = None
|
| + self._childNodes = []
|
| + self._flags = []
|
| +
|
| + def _getData(self):
|
| + return self._element.text
|
| +
|
| + def _setData(self, value):
|
| + self._element.text = value
|
| +
|
| + data = property(_getData, _setData)
|
| +
|
| + class DocumentType(Element):
|
| + def __init__(self, name, publicId, systemId):
|
| + Element.__init__(self, "<!DOCTYPE>")
|
| + self._element.text = name
|
| + self.publicId = publicId
|
| + self.systemId = systemId
|
| +
|
| + def _getPublicId(self):
|
| + return self._element.get("publicId", "")
|
| +
|
| + def _setPublicId(self, value):
|
| + if value is not None:
|
| + self._element.set("publicId", value)
|
| +
|
| + publicId = property(_getPublicId, _setPublicId)
|
| +
|
| + def _getSystemId(self):
|
| + return self._element.get("systemId", "")
|
| +
|
| + def _setSystemId(self, value):
|
| + if value is not None:
|
| + self._element.set("systemId", value)
|
| +
|
| + systemId = property(_getSystemId, _setSystemId)
|
| +
|
| + class Document(Element):
|
| + def __init__(self):
|
| + Element.__init__(self, "DOCUMENT_ROOT")
|
| +
|
| + class DocumentFragment(Element):
|
| + def __init__(self):
|
| + Element.__init__(self, "DOCUMENT_FRAGMENT")
|
| +
|
| + def testSerializer(element):
|
| + rv = []
|
| +
|
| + def serializeElement(element, indent=0):
|
| + if not(hasattr(element, "tag")):
|
| + element = element.getroot()
|
| + if element.tag == "<!DOCTYPE>":
|
| + if element.get("publicId") or element.get("systemId"):
|
| + publicId = element.get("publicId") or ""
|
| + systemId = element.get("systemId") or ""
|
| + rv.append("""<!DOCTYPE %s "%s" "%s">""" %
|
| + (element.text, publicId, systemId))
|
| + else:
|
| + rv.append("<!DOCTYPE %s>" % (element.text,))
|
| + elif element.tag == "DOCUMENT_ROOT":
|
| + rv.append("#document")
|
| + if element.text is not None:
|
| + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text))
|
| + if element.tail is not None:
|
| + raise TypeError("Document node cannot have tail")
|
| + if hasattr(element, "attrib") and len(element.attrib):
|
| + raise TypeError("Document node cannot have attributes")
|
| + elif element.tag == ElementTreeCommentType:
|
| + rv.append("|%s<!-- %s -->" % (' ' * indent, element.text))
|
| + else:
|
| + assert isinstance(element.tag, text_type), \
|
| + "Expected unicode, got %s, %s" % (type(element.tag), element.tag)
|
| + nsmatch = tag_regexp.match(element.tag)
|
| +
|
| + if nsmatch is None:
|
| + name = element.tag
|
| + else:
|
| + ns, name = nsmatch.groups()
|
| + prefix = constants.prefixes[ns]
|
| + name = "%s %s" % (prefix, name)
|
| + rv.append("|%s<%s>" % (' ' * indent, name))
|
| +
|
| + if hasattr(element, "attrib"):
|
| + attributes = []
|
| + for name, value in element.attrib.items():
|
| + nsmatch = tag_regexp.match(name)
|
| + if nsmatch is not None:
|
| + ns, name = nsmatch.groups()
|
| + prefix = constants.prefixes[ns]
|
| + attr_string = "%s %s" % (prefix, name)
|
| + else:
|
| + attr_string = name
|
| + attributes.append((attr_string, value))
|
| +
|
| + for name, value in sorted(attributes):
|
| + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value))
|
| + if element.text:
|
| + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text))
|
| + indent += 2
|
| + for child in element:
|
| + serializeElement(child, indent)
|
| + if element.tail:
|
| + rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail))
|
| + serializeElement(element, 0)
|
| +
|
| + return "\n".join(rv)
|
| +
|
| + def tostring(element):
|
| + """Serialize an element and its child nodes to a string"""
|
| + rv = []
|
| + filter = ihatexml.InfosetFilter()
|
| +
|
| + def serializeElement(element):
|
| + if isinstance(element, ElementTree.ElementTree):
|
| + element = element.getroot()
|
| +
|
| + if element.tag == "<!DOCTYPE>":
|
| + if element.get("publicId") or element.get("systemId"):
|
| + publicId = element.get("publicId") or ""
|
| + systemId = element.get("systemId") or ""
|
| + rv.append("""<!DOCTYPE %s PUBLIC "%s" "%s">""" %
|
| + (element.text, publicId, systemId))
|
| + else:
|
| + rv.append("<!DOCTYPE %s>" % (element.text,))
|
| + elif element.tag == "DOCUMENT_ROOT":
|
| + if element.text is not None:
|
| + rv.append(element.text)
|
| + if element.tail is not None:
|
| + raise TypeError("Document node cannot have tail")
|
| + if hasattr(element, "attrib") and len(element.attrib):
|
| + raise TypeError("Document node cannot have attributes")
|
| +
|
| + for child in element:
|
| + serializeElement(child)
|
| +
|
| + elif element.tag == ElementTreeCommentType:
|
| + rv.append("<!--%s-->" % (element.text,))
|
| + else:
|
| + # This is assumed to be an ordinary element
|
| + if not element.attrib:
|
| + rv.append("<%s>" % (filter.fromXmlName(element.tag),))
|
| + else:
|
| + attr = " ".join(["%s=\"%s\"" % (
|
| + filter.fromXmlName(name), value)
|
| + for name, value in element.attrib.items()])
|
| + rv.append("<%s %s>" % (element.tag, attr))
|
| + if element.text:
|
| + rv.append(element.text)
|
| +
|
| + for child in element:
|
| + serializeElement(child)
|
| +
|
| + rv.append("</%s>" % (element.tag,))
|
| +
|
| + if element.tail:
|
| + rv.append(element.tail)
|
| +
|
| + serializeElement(element)
|
| +
|
| + return "".join(rv)
|
| +
|
| + class TreeBuilder(_base.TreeBuilder):
|
| + documentClass = Document
|
| + doctypeClass = DocumentType
|
| + elementClass = Element
|
| + commentClass = Comment
|
| + fragmentClass = DocumentFragment
|
| + implementation = ElementTreeImplementation
|
| +
|
| + def testSerializer(self, element):
|
| + return testSerializer(element)
|
| +
|
| + def getDocument(self):
|
| + if fullTree:
|
| + return self.document._element
|
| + else:
|
| + if self.defaultNamespace is not None:
|
| + return self.document._element.find(
|
| + "{%s}html" % self.defaultNamespace)
|
| + else:
|
| + return self.document._element.find("html")
|
| +
|
| + def getFragment(self):
|
| + return _base.TreeBuilder.getFragment(self)._element
|
| +
|
| + return locals()
|
| +
|
| +
|
| +getETreeModule = moduleFactoryFactory(getETreeBuilder)
|
|
|