comparison env/lib/python3.9/site-packages/bleach/_vendor/html5lib/treebuilders/dom.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4f3585e2f14b
1 from __future__ import absolute_import, division, unicode_literals
2
3
4 try:
5 from collections.abc import MutableMapping
6 except ImportError: # Python 2.7
7 from collections import MutableMapping
8 from xml.dom import minidom, Node
9 import weakref
10
11 from . import base
12 from .. import constants
13 from ..constants import namespaces
14 from .._utils import moduleFactoryFactory
15
16
17 def getDomBuilder(DomImplementation):
18 Dom = DomImplementation
19
20 class AttrList(MutableMapping):
21 def __init__(self, element):
22 self.element = element
23
24 def __iter__(self):
25 return iter(self.element.attributes.keys())
26
27 def __setitem__(self, name, value):
28 if isinstance(name, tuple):
29 raise NotImplementedError
30 else:
31 attr = self.element.ownerDocument.createAttribute(name)
32 attr.value = value
33 self.element.attributes[name] = attr
34
35 def __len__(self):
36 return len(self.element.attributes)
37
38 def items(self):
39 return list(self.element.attributes.items())
40
41 def values(self):
42 return list(self.element.attributes.values())
43
44 def __getitem__(self, name):
45 if isinstance(name, tuple):
46 raise NotImplementedError
47 else:
48 return self.element.attributes[name].value
49
50 def __delitem__(self, name):
51 if isinstance(name, tuple):
52 raise NotImplementedError
53 else:
54 del self.element.attributes[name]
55
56 class NodeBuilder(base.Node):
57 def __init__(self, element):
58 base.Node.__init__(self, element.nodeName)
59 self.element = element
60
61 namespace = property(lambda self: hasattr(self.element, "namespaceURI") and
62 self.element.namespaceURI or None)
63
64 def appendChild(self, node):
65 node.parent = self
66 self.element.appendChild(node.element)
67
68 def insertText(self, data, insertBefore=None):
69 text = self.element.ownerDocument.createTextNode(data)
70 if insertBefore:
71 self.element.insertBefore(text, insertBefore.element)
72 else:
73 self.element.appendChild(text)
74
75 def insertBefore(self, node, refNode):
76 self.element.insertBefore(node.element, refNode.element)
77 node.parent = self
78
79 def removeChild(self, node):
80 if node.element.parentNode == self.element:
81 self.element.removeChild(node.element)
82 node.parent = None
83
84 def reparentChildren(self, newParent):
85 while self.element.hasChildNodes():
86 child = self.element.firstChild
87 self.element.removeChild(child)
88 newParent.element.appendChild(child)
89 self.childNodes = []
90
91 def getAttributes(self):
92 return AttrList(self.element)
93
94 def setAttributes(self, attributes):
95 if attributes:
96 for name, value in list(attributes.items()):
97 if isinstance(name, tuple):
98 if name[0] is not None:
99 qualifiedName = (name[0] + ":" + name[1])
100 else:
101 qualifiedName = name[1]
102 self.element.setAttributeNS(name[2], qualifiedName,
103 value)
104 else:
105 self.element.setAttribute(
106 name, value)
107 attributes = property(getAttributes, setAttributes)
108
109 def cloneNode(self):
110 return NodeBuilder(self.element.cloneNode(False))
111
112 def hasContent(self):
113 return self.element.hasChildNodes()
114
115 def getNameTuple(self):
116 if self.namespace is None:
117 return namespaces["html"], self.name
118 else:
119 return self.namespace, self.name
120
121 nameTuple = property(getNameTuple)
122
123 class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable
124 def documentClass(self):
125 self.dom = Dom.getDOMImplementation().createDocument(None, None, None)
126 return weakref.proxy(self)
127
128 def insertDoctype(self, token):
129 name = token["name"]
130 publicId = token["publicId"]
131 systemId = token["systemId"]
132
133 domimpl = Dom.getDOMImplementation()
134 doctype = domimpl.createDocumentType(name, publicId, systemId)
135 self.document.appendChild(NodeBuilder(doctype))
136 if Dom == minidom:
137 doctype.ownerDocument = self.dom
138
139 def elementClass(self, name, namespace=None):
140 if namespace is None and self.defaultNamespace is None:
141 node = self.dom.createElement(name)
142 else:
143 node = self.dom.createElementNS(namespace, name)
144
145 return NodeBuilder(node)
146
147 def commentClass(self, data):
148 return NodeBuilder(self.dom.createComment(data))
149
150 def fragmentClass(self):
151 return NodeBuilder(self.dom.createDocumentFragment())
152
153 def appendChild(self, node):
154 self.dom.appendChild(node.element)
155
156 def testSerializer(self, element):
157 return testSerializer(element)
158
159 def getDocument(self):
160 return self.dom
161
162 def getFragment(self):
163 return base.TreeBuilder.getFragment(self).element
164
165 def insertText(self, data, parent=None):
166 data = data
167 if parent != self:
168 base.TreeBuilder.insertText(self, data, parent)
169 else:
170 # HACK: allow text nodes as children of the document node
171 if hasattr(self.dom, '_child_node_types'):
172 # pylint:disable=protected-access
173 if Node.TEXT_NODE not in self.dom._child_node_types:
174 self.dom._child_node_types = list(self.dom._child_node_types)
175 self.dom._child_node_types.append(Node.TEXT_NODE)
176 self.dom.appendChild(self.dom.createTextNode(data))
177
178 implementation = DomImplementation
179 name = None
180
181 def testSerializer(element):
182 element.normalize()
183 rv = []
184
185 def serializeElement(element, indent=0):
186 if element.nodeType == Node.DOCUMENT_TYPE_NODE:
187 if element.name:
188 if element.publicId or element.systemId:
189 publicId = element.publicId or ""
190 systemId = element.systemId or ""
191 rv.append("""|%s<!DOCTYPE %s "%s" "%s">""" %
192 (' ' * indent, element.name, publicId, systemId))
193 else:
194 rv.append("|%s<!DOCTYPE %s>" % (' ' * indent, element.name))
195 else:
196 rv.append("|%s<!DOCTYPE >" % (' ' * indent,))
197 elif element.nodeType == Node.DOCUMENT_NODE:
198 rv.append("#document")
199 elif element.nodeType == Node.DOCUMENT_FRAGMENT_NODE:
200 rv.append("#document-fragment")
201 elif element.nodeType == Node.COMMENT_NODE:
202 rv.append("|%s<!-- %s -->" % (' ' * indent, element.nodeValue))
203 elif element.nodeType == Node.TEXT_NODE:
204 rv.append("|%s\"%s\"" % (' ' * indent, element.nodeValue))
205 else:
206 if (hasattr(element, "namespaceURI") and
207 element.namespaceURI is not None):
208 name = "%s %s" % (constants.prefixes[element.namespaceURI],
209 element.nodeName)
210 else:
211 name = element.nodeName
212 rv.append("|%s<%s>" % (' ' * indent, name))
213 if element.hasAttributes():
214 attributes = []
215 for i in range(len(element.attributes)):
216 attr = element.attributes.item(i)
217 name = attr.nodeName
218 value = attr.value
219 ns = attr.namespaceURI
220 if ns:
221 name = "%s %s" % (constants.prefixes[ns], attr.localName)
222 else:
223 name = attr.nodeName
224 attributes.append((name, value))
225
226 for name, value in sorted(attributes):
227 rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value))
228 indent += 2
229 for child in element.childNodes:
230 serializeElement(child, indent)
231 serializeElement(element, 0)
232
233 return "\n".join(rv)
234
235 return locals()
236
237
238 # The actual means to get a module!
239 getDomModule = moduleFactoryFactory(getDomBuilder)