| Viewing file:  dom.py (8.63 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
from __future__ import absolute_import, division, unicode_literals
 
 from collections import MutableMapping
 from xml.dom import minidom, Node
 import weakref
 
 from . import base
 from .. import constants
 from ..constants import namespaces
 from .._utils import moduleFactoryFactory
 
 
 def getDomBuilder(DomImplementation):
 Dom = DomImplementation
 
 class AttrList(MutableMapping):
 def __init__(self, element):
 self.element = element
 
 def __iter__(self):
 return iter(self.element.attributes.keys())
 
 def __setitem__(self, name, value):
 if isinstance(name, tuple):
 raise NotImplementedError
 else:
 attr = self.element.ownerDocument.createAttribute(name)
 attr.value = value
 self.element.attributes[name] = attr
 
 def __len__(self):
 return len(self.element.attributes)
 
 def items(self):
 return list(self.element.attributes.items())
 
 def values(self):
 return list(self.element.attributes.values())
 
 def __getitem__(self, name):
 if isinstance(name, tuple):
 raise NotImplementedError
 else:
 return self.element.attributes[name].value
 
 def __delitem__(self, name):
 if isinstance(name, tuple):
 raise NotImplementedError
 else:
 del self.element.attributes[name]
 
 class NodeBuilder(base.Node):
 def __init__(self, element):
 base.Node.__init__(self, element.nodeName)
 self.element = element
 
 namespace = property(lambda self: hasattr(self.element, "namespaceURI") and
 self.element.namespaceURI or None)
 
 def appendChild(self, node):
 node.parent = self
 self.element.appendChild(node.element)
 
 def insertText(self, data, insertBefore=None):
 text = self.element.ownerDocument.createTextNode(data)
 if insertBefore:
 self.element.insertBefore(text, insertBefore.element)
 else:
 self.element.appendChild(text)
 
 def insertBefore(self, node, refNode):
 self.element.insertBefore(node.element, refNode.element)
 node.parent = self
 
 def removeChild(self, node):
 if node.element.parentNode == self.element:
 self.element.removeChild(node.element)
 node.parent = None
 
 def reparentChildren(self, newParent):
 while self.element.hasChildNodes():
 child = self.element.firstChild
 self.element.removeChild(child)
 newParent.element.appendChild(child)
 self.childNodes = []
 
 def getAttributes(self):
 return AttrList(self.element)
 
 def setAttributes(self, attributes):
 if attributes:
 for name, value in list(attributes.items()):
 if isinstance(name, tuple):
 if name[0] is not None:
 qualifiedName = (name[0] + ":" + name[1])
 else:
 qualifiedName = name[1]
 self.element.setAttributeNS(name[2], qualifiedName,
 value)
 else:
 self.element.setAttribute(
 name, value)
 attributes = property(getAttributes, setAttributes)
 
 def cloneNode(self):
 return NodeBuilder(self.element.cloneNode(False))
 
 def hasContent(self):
 return self.element.hasChildNodes()
 
 def getNameTuple(self):
 if self.namespace is None:
 return namespaces["html"], self.name
 else:
 return self.namespace, self.name
 
 nameTuple = property(getNameTuple)
 
 class TreeBuilder(base.TreeBuilder):  # pylint:disable=unused-variable
 def documentClass(self):
 self.dom = Dom.getDOMImplementation().createDocument(None, None, None)
 return weakref.proxy(self)
 
 def insertDoctype(self, token):
 name = token["name"]
 publicId = token["publicId"]
 systemId = token["systemId"]
 
 domimpl = Dom.getDOMImplementation()
 doctype = domimpl.createDocumentType(name, publicId, systemId)
 self.document.appendChild(NodeBuilder(doctype))
 if Dom == minidom:
 doctype.ownerDocument = self.dom
 
 def elementClass(self, name, namespace=None):
 if namespace is None and self.defaultNamespace is None:
 node = self.dom.createElement(name)
 else:
 node = self.dom.createElementNS(namespace, name)
 
 return NodeBuilder(node)
 
 def commentClass(self, data):
 return NodeBuilder(self.dom.createComment(data))
 
 def fragmentClass(self):
 return NodeBuilder(self.dom.createDocumentFragment())
 
 def appendChild(self, node):
 self.dom.appendChild(node.element)
 
 def testSerializer(self, element):
 return testSerializer(element)
 
 def getDocument(self):
 return self.dom
 
 def getFragment(self):
 return base.TreeBuilder.getFragment(self).element
 
 def insertText(self, data, parent=None):
 data = data
 if parent != self:
 base.TreeBuilder.insertText(self, data, parent)
 else:
 # HACK: allow text nodes as children of the document node
 if hasattr(self.dom, '_child_node_types'):
 # pylint:disable=protected-access
 if Node.TEXT_NODE not in self.dom._child_node_types:
 self.dom._child_node_types = list(self.dom._child_node_types)
 self.dom._child_node_types.append(Node.TEXT_NODE)
 self.dom.appendChild(self.dom.createTextNode(data))
 
 implementation = DomImplementation
 name = None
 
 def testSerializer(element):
 element.normalize()
 rv = []
 
 def serializeElement(element, indent=0):
 if element.nodeType == Node.DOCUMENT_TYPE_NODE:
 if element.name:
 if element.publicId or element.systemId:
 publicId = element.publicId or ""
 systemId = element.systemId or ""
 rv.append("""|%s<!DOCTYPE %s "%s" "%s">""" %
 (' ' * indent, element.name, publicId, systemId))
 else:
 rv.append("|%s<!DOCTYPE %s>" % (' ' * indent, element.name))
 else:
 rv.append("|%s<!DOCTYPE >" % (' ' * indent,))
 elif element.nodeType == Node.DOCUMENT_NODE:
 rv.append("#document")
 elif element.nodeType == Node.DOCUMENT_FRAGMENT_NODE:
 rv.append("#document-fragment")
 elif element.nodeType == Node.COMMENT_NODE:
 rv.append("|%s<!-- %s -->" % (' ' * indent, element.nodeValue))
 elif element.nodeType == Node.TEXT_NODE:
 rv.append("|%s\"%s\"" % (' ' * indent, element.nodeValue))
 else:
 if (hasattr(element, "namespaceURI") and
 element.namespaceURI is not None):
 name = "%s %s" % (constants.prefixes[element.namespaceURI],
 element.nodeName)
 else:
 name = element.nodeName
 rv.append("|%s<%s>" % (' ' * indent, name))
 if element.hasAttributes():
 attributes = []
 for i in range(len(element.attributes)):
 attr = element.attributes.item(i)
 name = attr.nodeName
 value = attr.value
 ns = attr.namespaceURI
 if ns:
 name = "%s %s" % (constants.prefixes[ns], attr.localName)
 else:
 name = attr.nodeName
 attributes.append((name, value))
 
 for name, value in sorted(attributes):
 rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value))
 indent += 2
 for child in element.childNodes:
 serializeElement(child, indent)
 serializeElement(element, 0)
 
 return "\n".join(rv)
 
 return locals()
 
 
 # The actual means to get a module!
 getDomModule = moduleFactoryFactory(getDomBuilder)
 
 |