summaryrefslogtreecommitdiff
path: root/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders
diff options
context:
space:
mode:
Diffstat (limited to 'venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders')
-rw-r--r--venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__init__.py88
-rw-r--r--venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/base.py417
-rw-r--r--venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/dom.py236
-rw-r--r--venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree.py340
-rw-r--r--venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py366
5 files changed, 1447 insertions, 0 deletions
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__init__.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__init__.py
new file mode 100644
index 0000000..2ce5c87
--- /dev/null
+++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__init__.py
@@ -0,0 +1,88 @@
1"""A collection of modules for building different kinds of trees from HTML
2documents.
3
4To create a treebuilder for a new type of tree, you need to do
5implement several things:
6
71. A set of classes for various types of elements: Document, Doctype, Comment,
8 Element. These must implement the interface of ``base.treebuilders.Node``
9 (although comment nodes have a different signature for their constructor,
10 see ``treebuilders.etree.Comment``) Textual content may also be implemented
11 as another node type, or not, as your tree implementation requires.
12
132. A treebuilder object (called ``TreeBuilder`` by convention) that inherits
14 from ``treebuilders.base.TreeBuilder``. This has 4 required attributes:
15
16 * ``documentClass`` - the class to use for the bottommost node of a document
17 * ``elementClass`` - the class to use for HTML Elements
18 * ``commentClass`` - the class to use for comments
19 * ``doctypeClass`` - the class to use for doctypes
20
21 It also has one required method:
22
23 * ``getDocument`` - Returns the root node of the complete document tree
24
253. If you wish to run the unit tests, you must also create a ``testSerializer``
26 method on your treebuilder which accepts a node and returns a string
27 containing Node and its children serialized according to the format used in
28 the unittests
29
30"""
31
32from __future__ import absolute_import, division, unicode_literals
33
34from .._utils import default_etree
35
36treeBuilderCache = {}
37
38
39def getTreeBuilder(treeType, implementation=None, **kwargs):
40 """Get a TreeBuilder class for various types of trees with built-in support
41
42 :arg treeType: the name of the tree type required (case-insensitive). Supported
43 values are:
44
45 * "dom" - A generic builder for DOM implementations, defaulting to a
46 xml.dom.minidom based implementation.
47 * "etree" - A generic builder for tree implementations exposing an
48 ElementTree-like interface, defaulting to xml.etree.cElementTree if
49 available and xml.etree.ElementTree if not.
50 * "lxml" - A etree-based builder for lxml.etree, handling limitations
51 of lxml's implementation.
52
53 :arg implementation: (Currently applies to the "etree" and "dom" tree
54 types). A module implementing the tree type e.g. xml.etree.ElementTree
55 or xml.etree.cElementTree.
56
57 :arg kwargs: Any additional options to pass to the TreeBuilder when
58 creating it.
59
60 Example:
61
62 >>> from html5lib.treebuilders import getTreeBuilder
63 >>> builder = getTreeBuilder('etree')
64
65 """
66
67 treeType = treeType.lower()
68 if treeType not in treeBuilderCache:
69 if treeType == "dom":
70 from . import dom
71 # Come up with a sane default (pref. from the stdlib)
72 if implementation is None:
73 from xml.dom import minidom
74 implementation = minidom
75 # NEVER cache here, caching is done in the dom submodule
76 return dom.getDomModule(implementation, **kwargs).TreeBuilder
77 elif treeType == "lxml":
78 from . import etree_lxml
79 treeBuilderCache[treeType] = etree_lxml.TreeBuilder
80 elif treeType == "etree":
81 from . import etree
82 if implementation is None:
83 implementation = default_etree
84 # NEVER cache here, caching is done in the etree submodule
85 return etree.getETreeModule(implementation, **kwargs).TreeBuilder
86 else:
87 raise ValueError("""Unrecognised treebuilder "%s" """ % treeType)
88 return treeBuilderCache.get(treeType)
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/base.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/base.py
new file mode 100644
index 0000000..ed32fcb
--- /dev/null
+++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/base.py
@@ -0,0 +1,417 @@
1from __future__ import absolute_import, division, unicode_literals
2from pip._vendor.six import text_type
3
4from ..constants import scopingElements, tableInsertModeElements, namespaces
5
6# The scope markers are inserted when entering object elements,
7# marquees, table cells, and table captions, and are used to prevent formatting
8# from "leaking" into tables, object elements, and marquees.
9Marker = None
10
11listElementsMap = {
12 None: (frozenset(scopingElements), False),
13 "button": (frozenset(scopingElements | set([(namespaces["html"], "button")])), False),
14 "list": (frozenset(scopingElements | set([(namespaces["html"], "ol"),
15 (namespaces["html"], "ul")])), False),
16 "table": (frozenset([(namespaces["html"], "html"),
17 (namespaces["html"], "table")]), False),
18 "select": (frozenset([(namespaces["html"], "optgroup"),
19 (namespaces["html"], "option")]), True)
20}
21
22
23class Node(object):
24 """Represents an item in the tree"""
25 def __init__(self, name):
26 """Creates a Node
27
28 :arg name: The tag name associated with the node
29
30 """
31 # The tag name assocaited with the node
32 self.name = name
33 # The parent of the current node (or None for the document node)
34 self.parent = None
35 # The value of the current node (applies to text nodes and comments)
36 self.value = None
37 # A dict holding name -> value pairs for attributes of the node
38 self.attributes = {}
39 # A list of child nodes of the current node. This must include all
40 # elements but not necessarily other node types.
41 self.childNodes = []
42 # A list of miscellaneous flags that can be set on the node.
43 self._flags = []
44
45 def __str__(self):
46 attributesStr = " ".join(["%s=\"%s\"" % (name, value)
47 for name, value in
48 self.attributes.items()])
49 if attributesStr:
50 return "<%s %s>" % (self.name, attributesStr)
51 else:
52 return "<%s>" % (self.name)
53
54 def __repr__(self):
55 return "<%s>" % (self.name)
56
57 def appendChild(self, node):
58 """Insert node as a child of the current node
59
60 :arg node: the node to insert
61
62 """
63 raise NotImplementedError
64
65 def insertText(self, data, insertBefore=None):
66 """Insert data as text in the current node, positioned before the
67 start of node insertBefore or to the end of the node's text.
68
69 :arg data: the data to insert
70
71 :arg insertBefore: True if you want to insert the text before the node
72 and False if you want to insert it after the node
73
74 """
75 raise NotImplementedError
76
77 def insertBefore(self, node, refNode):
78 """Insert node as a child of the current node, before refNode in the
79 list of child nodes. Raises ValueError if refNode is not a child of
80 the current node
81
82 :arg node: the node to insert
83
84 :arg refNode: the child node to insert the node before
85
86 """
87 raise NotImplementedError
88
89 def removeChild(self, node):
90 """Remove node from the children of the current node
91
92 :arg node: the child node to remove
93
94 """
95 raise NotImplementedError
96
97 def reparentChildren(self, newParent):
98 """Move all the children of the current node to newParent.
99 This is needed so that trees that don't store text as nodes move the
100 text in the correct way
101
102 :arg newParent: the node to move all this node's children to
103
104 """
105 # XXX - should this method be made more general?
106 for child in self.childNodes:
107 newParent.appendChild(child)
108 self.childNodes = []
109
110 def cloneNode(self):
111 """Return a shallow copy of the current node i.e. a node with the same
112 name and attributes but with no parent or child nodes
113 """
114 raise NotImplementedError
115
116 def hasContent(self):
117 """Return true if the node has children or text, false otherwise
118 """
119 raise NotImplementedError
120
121
122class ActiveFormattingElements(list):
123 def append(self, node):
124 equalCount = 0
125 if node != Marker:
126 for element in self[::-1]:
127 if element == Marker:
128 break
129 if self.nodesEqual(element, node):
130 equalCount += 1
131 if equalCount == 3:
132 self.remove(element)
133 break
134 list.append(self, node)
135
136 def nodesEqual(self, node1, node2):
137 if not node1.nameTuple == node2.nameTuple:
138 return False
139
140 if not node1.attributes == node2.attributes:
141 return False
142
143 return True
144
145
146class TreeBuilder(object):
147 """Base treebuilder implementation
148
149 * documentClass - the class to use for the bottommost node of a document
150 * elementClass - the class to use for HTML Elements
151 * commentClass - the class to use for comments
152 * doctypeClass - the class to use for doctypes
153
154 """
155 # pylint:disable=not-callable
156
157 # Document class
158 documentClass = None
159
160 # The class to use for creating a node
161 elementClass = None
162
163 # The class to use for creating comments
164 commentClass = None
165
166 # The class to use for creating doctypes
167 doctypeClass = None
168
169 # Fragment class
170 fragmentClass = None
171
172 def __init__(self, namespaceHTMLElements):
173 """Create a TreeBuilder
174
175 :arg namespaceHTMLElements: whether or not to namespace HTML elements
176
177 """
178 if namespaceHTMLElements:
179 self.defaultNamespace = "http://www.w3.org/1999/xhtml"
180 else:
181 self.defaultNamespace = None
182 self.reset()
183
184 def reset(self):
185 self.openElements = []
186 self.activeFormattingElements = ActiveFormattingElements()
187
188 # XXX - rename these to headElement, formElement
189 self.headPointer = None
190 self.formPointer = None
191
192 self.insertFromTable = False
193
194 self.document = self.documentClass()
195
196 def elementInScope(self, target, variant=None):
197
198 # If we pass a node in we match that. if we pass a string
199 # match any node with that name
200 exactNode = hasattr(target, "nameTuple")
201 if not exactNode:
202 if isinstance(target, text_type):
203 target = (namespaces["html"], target)
204 assert isinstance(target, tuple)
205
206 listElements, invert = listElementsMap[variant]
207
208 for node in reversed(self.openElements):
209 if exactNode and node == target:
210 return True
211 elif not exactNode and node.nameTuple == target:
212 return True
213 elif (invert ^ (node.nameTuple in listElements)):
214 return False
215
216 assert False # We should never reach this point
217
218 def reconstructActiveFormattingElements(self):
219 # Within this algorithm the order of steps described in the
220 # specification is not quite the same as the order of steps in the
221 # code. It should still do the same though.
222
223 # Step 1: stop the algorithm when there's nothing to do.
224 if not self.activeFormattingElements:
225 return
226
227 # Step 2 and step 3: we start with the last element. So i is -1.
228 i = len(self.activeFormattingElements) - 1
229 entry = self.activeFormattingElements[i]
230 if entry == Marker or entry in self.openElements:
231 return
232
233 # Step 6
234 while entry != Marker and entry not in self.openElements:
235 if i == 0:
236 # This will be reset to 0 below
237 i = -1
238 break
239 i -= 1
240 # Step 5: let entry be one earlier in the list.
241 entry = self.activeFormattingElements[i]
242
243 while True:
244 # Step 7
245 i += 1
246
247 # Step 8
248 entry = self.activeFormattingElements[i]
249 clone = entry.cloneNode() # Mainly to get a new copy of the attributes
250
251 # Step 9
252 element = self.insertElement({"type": "StartTag",
253 "name": clone.name,
254 "namespace": clone.namespace,
255 "data": clone.attributes})
256
257 # Step 10
258 self.activeFormattingElements[i] = element
259
260 # Step 11
261 if element == self.activeFormattingElements[-1]:
262 break
263
264 def clearActiveFormattingElements(self):
265 entry = self.activeFormattingElements.pop()
266 while self.activeFormattingElements and entry != Marker:
267 entry = self.activeFormattingElements.pop()
268
269 def elementInActiveFormattingElements(self, name):
270 """Check if an element exists between the end of the active
271 formatting elements and the last marker. If it does, return it, else
272 return false"""
273
274 for item in self.activeFormattingElements[::-1]:
275 # Check for Marker first because if it's a Marker it doesn't have a
276 # name attribute.
277 if item == Marker:
278 break
279 elif item.name == name:
280 return item
281 return False
282
283 def insertRoot(self, token):
284 element = self.createElement(token)
285 self.openElements.append(element)
286 self.document.appendChild(element)
287
288 def insertDoctype(self, token):
289 name = token["name"]
290 publicId = token["publicId"]
291 systemId = token["systemId"]
292
293 doctype = self.doctypeClass(name, publicId, systemId)
294 self.document.appendChild(doctype)
295
296 def insertComment(self, token, parent=None):
297 if parent is None:
298 parent = self.openElements[-1]
299 parent.appendChild(self.commentClass(token["data"]))
300
301 def createElement(self, token):
302 """Create an element but don't insert it anywhere"""
303 name = token["name"]
304 namespace = token.get("namespace", self.defaultNamespace)
305 element = self.elementClass(name, namespace)
306 element.attributes = token["data"]
307 return element
308
309 def _getInsertFromTable(self):
310 return self._insertFromTable
311
312 def _setInsertFromTable(self, value):
313 """Switch the function used to insert an element from the
314 normal one to the misnested table one and back again"""
315 self._insertFromTable = value
316 if value:
317 self.insertElement = self.insertElementTable
318 else:
319 self.insertElement = self.insertElementNormal
320
321 insertFromTable = property(_getInsertFromTable, _setInsertFromTable)
322
323 def insertElementNormal(self, token):
324 name = token["name"]
325 assert isinstance(name, text_type), "Element %s not unicode" % name
326 namespace = token.get("namespace", self.defaultNamespace)
327 element = self.elementClass(name, namespace)
328 element.attributes = token["data"]
329 self.openElements[-1].appendChild(element)
330 self.openElements.append(element)
331 return element
332
333 def insertElementTable(self, token):
334 """Create an element and insert it into the tree"""
335 element = self.createElement(token)
336 if self.openElements[-1].name not in tableInsertModeElements:
337 return self.insertElementNormal(token)
338 else:
339 # We should be in the InTable mode. This means we want to do
340 # special magic element rearranging
341 parent, insertBefore = self.getTableMisnestedNodePosition()
342 if insertBefore is None:
343 parent.appendChild(element)
344 else:
345 parent.insertBefore(element, insertBefore)
346 self.openElements.append(element)
347 return element
348
349 def insertText(self, data, parent=None):
350 """Insert text data."""
351 if parent is None:
352 parent = self.openElements[-1]
353
354 if (not self.insertFromTable or (self.insertFromTable and
355 self.openElements[-1].name
356 not in tableInsertModeElements)):
357 parent.insertText(data)
358 else:
359 # We should be in the InTable mode. This means we want to do
360 # special magic element rearranging
361 parent, insertBefore = self.getTableMisnestedNodePosition()
362 parent.insertText(data, insertBefore)
363
364 def getTableMisnestedNodePosition(self):
365 """Get the foster parent element, and sibling to insert before
366 (or None) when inserting a misnested table node"""
367 # The foster parent element is the one which comes before the most
368 # recently opened table element
369 # XXX - this is really inelegant
370 lastTable = None
371 fosterParent = None
372 insertBefore = None
373 for elm in self.openElements[::-1]:
374 if elm.name == "table":
375 lastTable = elm
376 break
377 if lastTable:
378 # XXX - we should really check that this parent is actually a
379 # node here
380 if lastTable.parent:
381 fosterParent = lastTable.parent
382 insertBefore = lastTable
383 else:
384 fosterParent = self.openElements[
385 self.openElements.index(lastTable) - 1]
386 else:
387 fosterParent = self.openElements[0]
388 return fosterParent, insertBefore
389
390 def generateImpliedEndTags(self, exclude=None):
391 name = self.openElements[-1].name
392 # XXX td, th and tr are not actually needed
393 if (name in frozenset(("dd", "dt", "li", "option", "optgroup", "p", "rp", "rt")) and
394 name != exclude):
395 self.openElements.pop()
396 # XXX This is not entirely what the specification says. We should
397 # investigate it more closely.
398 self.generateImpliedEndTags(exclude)
399
400 def getDocument(self):
401 """Return the final tree"""
402 return self.document
403
404 def getFragment(self):
405 """Return the final fragment"""
406 # assert self.innerHTML
407 fragment = self.fragmentClass()
408 self.openElements[0].reparentChildren(fragment)
409 return fragment
410
411 def testSerializer(self, node):
412 """Serialize the subtree of node in the format required by unit tests
413
414 :arg node: the node from which to start serializing
415
416 """
417 raise NotImplementedError
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/dom.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/dom.py
new file mode 100644
index 0000000..8117b2d
--- /dev/null
+++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/dom.py
@@ -0,0 +1,236 @@
1from __future__ import absolute_import, division, unicode_literals
2
3
4from collections import MutableMapping
5from xml.dom import minidom, Node
6import weakref
7
8from . import base
9from .. import constants
10from ..constants import namespaces
11from .._utils import moduleFactoryFactory
12
13
14def getDomBuilder(DomImplementation):
15 Dom = DomImplementation
16
17 class AttrList(MutableMapping):
18 def __init__(self, element):
19 self.element = element
20
21 def __iter__(self):
22 return iter(self.element.attributes.keys())
23
24 def __setitem__(self, name, value):
25 if isinstance(name, tuple):
26 raise NotImplementedError
27 else:
28 attr = self.element.ownerDocument.createAttribute(name)
29 attr.value = value
30 self.element.attributes[name] = attr
31
32 def __len__(self):
33 return len(self.element.attributes)
34
35 def items(self):
36 return list(self.element.attributes.items())
37
38 def values(self):
39 return list(self.element.attributes.values())
40
41 def __getitem__(self, name):
42 if isinstance(name, tuple):
43 raise NotImplementedError
44 else:
45 return self.element.attributes[name].value
46
47 def __delitem__(self, name):
48 if isinstance(name, tuple):
49 raise NotImplementedError
50 else:
51 del self.element.attributes[name]
52
53 class NodeBuilder(base.Node):
54 def __init__(self, element):
55 base.Node.__init__(self, element.nodeName)
56 self.element = element
57
58 namespace = property(lambda self: hasattr(self.element, "namespaceURI") and
59 self.element.namespaceURI or None)
60
61 def appendChild(self, node):
62 node.parent = self
63 self.element.appendChild(node.element)
64
65 def insertText(self, data, insertBefore=None):
66 text = self.element.ownerDocument.createTextNode(data)
67 if insertBefore:
68 self.element.insertBefore(text, insertBefore.element)
69 else:
70 self.element.appendChild(text)
71
72 def insertBefore(self, node, refNode):
73 self.element.insertBefore(node.element, refNode.element)
74 node.parent = self
75
76 def removeChild(self, node):
77 if node.element.parentNode == self.element:
78 self.element.removeChild(node.element)
79 node.parent = None
80
81 def reparentChildren(self, newParent):
82 while self.element.hasChildNodes():
83 child = self.element.firstChild
84 self.element.removeChild(child)
85 newParent.element.appendChild(child)
86 self.childNodes = []
87
88 def getAttributes(self):
89 return AttrList(self.element)
90
91 def setAttributes(self, attributes):
92 if attributes:
93 for name, value in list(attributes.items()):
94 if isinstance(name, tuple):
95 if name[0] is not None:
96 qualifiedName = (name[0] + ":" + name[1])
97 else:
98 qualifiedName = name[1]
99 self.element.setAttributeNS(name[2], qualifiedName,
100 value)
101 else:
102 self.element.setAttribute(
103 name, value)
104 attributes = property(getAttributes, setAttributes)
105
106 def cloneNode(self):
107 return NodeBuilder(self.element.cloneNode(False))
108
109 def hasContent(self):
110 return self.element.hasChildNodes()
111
112 def getNameTuple(self):
113 if self.namespace is None:
114 return namespaces["html"], self.name
115 else:
116 return self.namespace, self.name
117
118 nameTuple = property(getNameTuple)
119
120 class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable
121 def documentClass(self):
122 self.dom = Dom.getDOMImplementation().createDocument(None, None, None)
123 return weakref.proxy(self)
124
125 def insertDoctype(self, token):
126 name = token["name"]
127 publicId = token["publicId"]
128 systemId = token["systemId"]
129
130 domimpl = Dom.getDOMImplementation()
131 doctype = domimpl.createDocumentType(name, publicId, systemId)
132 self.document.appendChild(NodeBuilder(doctype))
133 if Dom == minidom:
134 doctype.ownerDocument = self.dom
135
136 def elementClass(self, name, namespace=None):
137 if namespace is None and self.defaultNamespace is None:
138 node = self.dom.createElement(name)
139 else:
140 node = self.dom.createElementNS(namespace, name)
141
142 return NodeBuilder(node)
143
144 def commentClass(self, data):
145 return NodeBuilder(self.dom.createComment(data))
146
147 def fragmentClass(self):
148 return NodeBuilder(self.dom.createDocumentFragment())
149
150 def appendChild(self, node):
151 self.dom.appendChild(node.element)
152
153 def testSerializer(self, element):
154 return testSerializer(element)
155
156 def getDocument(self):
157 return self.dom
158
159 def getFragment(self):
160 return base.TreeBuilder.getFragment(self).element
161
162 def insertText(self, data, parent=None):
163 data = data
164 if parent != self:
165 base.TreeBuilder.insertText(self, data, parent)
166 else:
167 # HACK: allow text nodes as children of the document node
168 if hasattr(self.dom, '_child_node_types'):
169 # pylint:disable=protected-access
170 if Node.TEXT_NODE not in self.dom._child_node_types:
171 self.dom._child_node_types = list(self.dom._child_node_types)
172 self.dom._child_node_types.append(Node.TEXT_NODE)
173 self.dom.appendChild(self.dom.createTextNode(data))
174
175 implementation = DomImplementation
176 name = None
177
178 def testSerializer(element):
179 element.normalize()
180 rv = []
181
182 def serializeElement(element, indent=0):
183 if element.nodeType == Node.DOCUMENT_TYPE_NODE:
184 if element.name:
185 if element.publicId or element.systemId:
186 publicId = element.publicId or ""
187 systemId = element.systemId or ""
188 rv.append("""|%s<!DOCTYPE %s "%s" "%s">""" %
189 (' ' * indent, element.name, publicId, systemId))
190 else:
191 rv.append("|%s<!DOCTYPE %s>" % (' ' * indent, element.name))
192 else:
193 rv.append("|%s<!DOCTYPE >" % (' ' * indent,))
194 elif element.nodeType == Node.DOCUMENT_NODE:
195 rv.append("#document")
196 elif element.nodeType == Node.DOCUMENT_FRAGMENT_NODE:
197 rv.append("#document-fragment")
198 elif element.nodeType == Node.COMMENT_NODE:
199 rv.append("|%s<!-- %s -->" % (' ' * indent, element.nodeValue))
200 elif element.nodeType == Node.TEXT_NODE:
201 rv.append("|%s\"%s\"" % (' ' * indent, element.nodeValue))
202 else:
203 if (hasattr(element, "namespaceURI") and
204 element.namespaceURI is not None):
205 name = "%s %s" % (constants.prefixes[element.namespaceURI],
206 element.nodeName)
207 else:
208 name = element.nodeName
209 rv.append("|%s<%s>" % (' ' * indent, name))
210 if element.hasAttributes():
211 attributes = []
212 for i in range(len(element.attributes)):
213 attr = element.attributes.item(i)
214 name = attr.nodeName
215 value = attr.value
216 ns = attr.namespaceURI
217 if ns:
218 name = "%s %s" % (constants.prefixes[ns], attr.localName)
219 else:
220 name = attr.nodeName
221 attributes.append((name, value))
222
223 for name, value in sorted(attributes):
224 rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value))
225 indent += 2
226 for child in element.childNodes:
227 serializeElement(child, indent)
228 serializeElement(element, 0)
229
230 return "\n".join(rv)
231
232 return locals()
233
234
235# The actual means to get a module!
236getDomModule = moduleFactoryFactory(getDomBuilder)
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree.py
new file mode 100644
index 0000000..9a4aa95
--- /dev/null
+++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree.py
@@ -0,0 +1,340 @@
1from __future__ import absolute_import, division, unicode_literals
2# pylint:disable=protected-access
3
4from pip._vendor.six import text_type
5
6import re
7
8from . import base
9from .. import _ihatexml
10from .. import constants
11from ..constants import namespaces
12from .._utils import moduleFactoryFactory
13
14tag_regexp = re.compile("{([^}]*)}(.*)")
15
16
17def getETreeBuilder(ElementTreeImplementation, fullTree=False):
18 ElementTree = ElementTreeImplementation
19 ElementTreeCommentType = ElementTree.Comment("asd").tag
20
21 class Element(base.Node):
22 def __init__(self, name, namespace=None):
23 self._name = name
24 self._namespace = namespace
25 self._element = ElementTree.Element(self._getETreeTag(name,
26 namespace))
27 if namespace is None:
28 self.nameTuple = namespaces["html"], self._name
29 else:
30 self.nameTuple = self._namespace, self._name
31 self.parent = None
32 self._childNodes = []
33 self._flags = []
34
35 def _getETreeTag(self, name, namespace):
36 if namespace is None:
37 etree_tag = name
38 else:
39 etree_tag = "{%s}%s" % (namespace, name)
40 return etree_tag
41
42 def _setName(self, name):
43 self._name = name
44 self._element.tag = self._getETreeTag(self._name, self._namespace)
45
46 def _getName(self):
47 return self._name
48
49 name = property(_getName, _setName)
50
51 def _setNamespace(self, namespace):
52 self._namespace = namespace
53 self._element.tag = self._getETreeTag(self._name, self._namespace)
54
55 def _getNamespace(self):
56 return self._namespace
57
58 namespace = property(_getNamespace, _setNamespace)
59
60 def _getAttributes(self):
61 return self._element.attrib
62
63 def _setAttributes(self, attributes):
64 # Delete existing attributes first
65 # XXX - there may be a better way to do this...
66 for key in list(self._element.attrib.keys()):
67 del self._element.attrib[key]
68 for key, value in attributes.items():
69 if isinstance(key, tuple):
70 name = "{%s}%s" % (key[2], key[1])
71 else:
72 name = key
73 self._element.set(name, value)
74
75 attributes = property(_getAttributes, _setAttributes)
76
77 def _getChildNodes(self):
78 return self._childNodes
79
80 def _setChildNodes(self, value):
81 del self._element[:]
82 self._childNodes = []
83 for element in value:
84 self.insertChild(element)
85
86 childNodes = property(_getChildNodes, _setChildNodes)
87
88 def hasContent(self):
89 """Return true if the node has children or text"""
90 return bool(self._element.text or len(self._element))
91
92 def appendChild(self, node):
93 self._childNodes.append(node)
94 self._element.append(node._element)
95 node.parent = self
96
97 def insertBefore(self, node, refNode):
98 index = list(self._element).index(refNode._element)
99 self._element.insert(index, node._element)
100 node.parent = self
101
102 def removeChild(self, node):
103 self._childNodes.remove(node)
104 self._element.remove(node._element)
105 node.parent = None
106
107 def insertText(self, data, insertBefore=None):
108 if not(len(self._element)):
109 if not self._element.text:
110 self._element.text = ""
111 self._element.text += data
112 elif insertBefore is None:
113 # Insert the text as the tail of the last child element
114 if not self._element[-1].tail:
115 self._element[-1].tail = ""
116 self._element[-1].tail += data
117 else:
118 # Insert the text before the specified node
119 children = list(self._element)
120 index = children.index(insertBefore._element)
121 if index > 0:
122 if not self._element[index - 1].tail:
123 self._element[index - 1].tail = ""
124 self._element[index - 1].tail += data
125 else:
126 if not self._element.text:
127 self._element.text = ""
128 self._element.text += data
129
130 def cloneNode(self):
131 element = type(self)(self.name, self.namespace)
132 for name, value in self.attributes.items():
133 element.attributes[name] = value
134 return element
135
136 def reparentChildren(self, newParent):
137 if newParent.childNodes:
138 newParent.childNodes[-1]._element.tail += self._element.text
139 else:
140 if not newParent._element.text:
141 newParent._element.text = ""
142 if self._element.text is not None:
143 newParent._element.text += self._element.text
144 self._element.text = ""
145 base.Node.reparentChildren(self, newParent)
146
147 class Comment(Element):
148 def __init__(self, data):
149 # Use the superclass constructor to set all properties on the
150 # wrapper element
151 self._element = ElementTree.Comment(data)
152 self.parent = None
153 self._childNodes = []
154 self._flags = []
155
156 def _getData(self):
157 return self._element.text
158
159 def _setData(self, value):
160 self._element.text = value
161
162 data = property(_getData, _setData)
163
164 class DocumentType(Element):
165 def __init__(self, name, publicId, systemId):
166 Element.__init__(self, "<!DOCTYPE>")
167 self._element.text = name
168 self.publicId = publicId
169 self.systemId = systemId
170
171 def _getPublicId(self):
172 return self._element.get("publicId", "")
173
174 def _setPublicId(self, value):
175 if value is not None:
176 self._element.set("publicId", value)
177
178 publicId = property(_getPublicId, _setPublicId)
179
180 def _getSystemId(self):
181 return self._element.get("systemId", "")
182
183 def _setSystemId(self, value):
184 if value is not None:
185 self._element.set("systemId", value)
186
187 systemId = property(_getSystemId, _setSystemId)
188
189 class Document(Element):
190 def __init__(self):
191 Element.__init__(self, "DOCUMENT_ROOT")
192
193 class DocumentFragment(Element):
194 def __init__(self):
195 Element.__init__(self, "DOCUMENT_FRAGMENT")
196
197 def testSerializer(element):
198 rv = []
199
200 def serializeElement(element, indent=0):
201 if not(hasattr(element, "tag")):
202 element = element.getroot()
203 if element.tag == "<!DOCTYPE>":
204 if element.get("publicId") or element.get("systemId"):
205 publicId = element.get("publicId") or ""
206 systemId = element.get("systemId") or ""
207 rv.append("""<!DOCTYPE %s "%s" "%s">""" %
208 (element.text, publicId, systemId))
209 else:
210 rv.append("<!DOCTYPE %s>" % (element.text,))
211 elif element.tag == "DOCUMENT_ROOT":
212 rv.append("#document")
213 if element.text is not None:
214 rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text))
215 if element.tail is not None:
216 raise TypeError("Document node cannot have tail")
217 if hasattr(element, "attrib") and len(element.attrib):
218 raise TypeError("Document node cannot have attributes")
219 elif element.tag == ElementTreeCommentType:
220 rv.append("|%s<!-- %s -->" % (' ' * indent, element.text))
221 else:
222 assert isinstance(element.tag, text_type), \
223 "Expected unicode, got %s, %s" % (type(element.tag), element.tag)
224 nsmatch = tag_regexp.match(element.tag)
225
226 if nsmatch is None:
227 name = element.tag
228 else:
229 ns, name = nsmatch.groups()
230 prefix = constants.prefixes[ns]
231 name = "%s %s" % (prefix, name)
232 rv.append("|%s<%s>" % (' ' * indent, name))
233
234 if hasattr(element, "attrib"):
235 attributes = []
236 for name, value in element.attrib.items():
237 nsmatch = tag_regexp.match(name)
238 if nsmatch is not None:
239 ns, name = nsmatch.groups()
240 prefix = constants.prefixes[ns]
241 attr_string = "%s %s" % (prefix, name)
242 else:
243 attr_string = name
244 attributes.append((attr_string, value))
245
246 for name, value in sorted(attributes):
247 rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value))
248 if element.text:
249 rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text))
250 indent += 2
251 for child in element:
252 serializeElement(child, indent)
253 if element.tail:
254 rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail))
255 serializeElement(element, 0)
256
257 return "\n".join(rv)
258
259 def tostring(element): # pylint:disable=unused-variable
260 """Serialize an element and its child nodes to a string"""
261 rv = []
262 filter = _ihatexml.InfosetFilter()
263
264 def serializeElement(element):
265 if isinstance(element, ElementTree.ElementTree):
266 element = element.getroot()
267
268 if element.tag == "<!DOCTYPE>":
269 if element.get("publicId") or element.get("systemId"):
270 publicId = element.get("publicId") or ""
271 systemId = element.get("systemId") or ""
272 rv.append("""<!DOCTYPE %s PUBLIC "%s" "%s">""" %
273 (element.text, publicId, systemId))
274 else:
275 rv.append("<!DOCTYPE %s>" % (element.text,))
276 elif element.tag == "DOCUMENT_ROOT":
277 if element.text is not None:
278 rv.append(element.text)
279 if element.tail is not None:
280 raise TypeError("Document node cannot have tail")
281 if hasattr(element, "attrib") and len(element.attrib):
282 raise TypeError("Document node cannot have attributes")
283
284 for child in element:
285 serializeElement(child)
286
287 elif element.tag == ElementTreeCommentType:
288 rv.append("<!--%s-->" % (element.text,))
289 else:
290 # This is assumed to be an ordinary element
291 if not element.attrib:
292 rv.append("<%s>" % (filter.fromXmlName(element.tag),))
293 else:
294 attr = " ".join(["%s=\"%s\"" % (
295 filter.fromXmlName(name), value)
296 for name, value in element.attrib.items()])
297 rv.append("<%s %s>" % (element.tag, attr))
298 if element.text:
299 rv.append(element.text)
300
301 for child in element:
302 serializeElement(child)
303
304 rv.append("</%s>" % (element.tag,))
305
306 if element.tail:
307 rv.append(element.tail)
308
309 serializeElement(element)
310
311 return "".join(rv)
312
313 class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable
314 documentClass = Document
315 doctypeClass = DocumentType
316 elementClass = Element
317 commentClass = Comment
318 fragmentClass = DocumentFragment
319 implementation = ElementTreeImplementation
320
321 def testSerializer(self, element):
322 return testSerializer(element)
323
324 def getDocument(self):
325 if fullTree:
326 return self.document._element
327 else:
328 if self.defaultNamespace is not None:
329 return self.document._element.find(
330 "{%s}html" % self.defaultNamespace)
331 else:
332 return self.document._element.find("html")
333
334 def getFragment(self):
335 return base.TreeBuilder.getFragment(self)._element
336
337 return locals()
338
339
340getETreeModule = moduleFactoryFactory(getETreeBuilder)
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py
new file mode 100644
index 0000000..66a9ba3
--- /dev/null
+++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py
@@ -0,0 +1,366 @@
1"""Module for supporting the lxml.etree library. The idea here is to use as much
2of the native library as possible, without using fragile hacks like custom element
3names that break between releases. The downside of this is that we cannot represent
4all possible trees; specifically the following are known to cause problems:
5
6Text or comments as siblings of the root element
7Docypes with no name
8
9When any of these things occur, we emit a DataLossWarning
10"""
11
12from __future__ import absolute_import, division, unicode_literals
13# pylint:disable=protected-access
14
15import warnings
16import re
17import sys
18
19from . import base
20from ..constants import DataLossWarning
21from .. import constants
22from . import etree as etree_builders
23from .. import _ihatexml
24
25import lxml.etree as etree
26
27
28fullTree = True
29tag_regexp = re.compile("{([^}]*)}(.*)")
30
31comment_type = etree.Comment("asd").tag
32
33
34class DocumentType(object):
35 def __init__(self, name, publicId, systemId):
36 self.name = name
37 self.publicId = publicId
38 self.systemId = systemId
39
40
41class Document(object):
42 def __init__(self):
43 self._elementTree = None
44 self._childNodes = []
45
46 def appendChild(self, element):
47 self._elementTree.getroot().addnext(element._element)
48
49 def _getChildNodes(self):
50 return self._childNodes
51
52 childNodes = property(_getChildNodes)
53
54
55def testSerializer(element):
56 rv = []
57 infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True)
58
59 def serializeElement(element, indent=0):
60 if not hasattr(element, "tag"):
61 if hasattr(element, "getroot"):
62 # Full tree case
63 rv.append("#document")
64 if element.docinfo.internalDTD:
65 if not (element.docinfo.public_id or
66 element.docinfo.system_url):
67 dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name
68 else:
69 dtd_str = """<!DOCTYPE %s "%s" "%s">""" % (
70 element.docinfo.root_name,
71 element.docinfo.public_id,
72 element.docinfo.system_url)
73 rv.append("|%s%s" % (' ' * (indent + 2), dtd_str))
74 next_element = element.getroot()
75 while next_element.getprevious() is not None:
76 next_element = next_element.getprevious()
77 while next_element is not None:
78 serializeElement(next_element, indent + 2)
79 next_element = next_element.getnext()
80 elif isinstance(element, str) or isinstance(element, bytes):
81 # Text in a fragment
82 assert isinstance(element, str) or sys.version_info[0] == 2
83 rv.append("|%s\"%s\"" % (' ' * indent, element))
84 else:
85 # Fragment case
86 rv.append("#document-fragment")
87 for next_element in element:
88 serializeElement(next_element, indent + 2)
89 elif element.tag == comment_type:
90 rv.append("|%s<!-- %s -->" % (' ' * indent, element.text))
91 if hasattr(element, "tail") and element.tail:
92 rv.append("|%s\"%s\"" % (' ' * indent, element.tail))
93 else:
94 assert isinstance(element, etree._Element)
95 nsmatch = etree_builders.tag_regexp.match(element.tag)
96 if nsmatch is not None:
97 ns = nsmatch.group(1)
98 tag = nsmatch.group(2)
99 prefix = constants.prefixes[ns]
100 rv.append("|%s<%s %s>" % (' ' * indent, prefix,
101 infosetFilter.fromXmlName(tag)))
102 else:
103 rv.append("|%s<%s>" % (' ' * indent,
104 infosetFilter.fromXmlName(element.tag)))
105
106 if hasattr(element, "attrib"):
107 attributes = []
108 for name, value in element.attrib.items():
109 nsmatch = tag_regexp.match(name)
110 if nsmatch is not None:
111 ns, name = nsmatch.groups()
112 name = infosetFilter.fromXmlName(name)
113 prefix = constants.prefixes[ns]
114 attr_string = "%s %s" % (prefix, name)
115 else:
116 attr_string = infosetFilter.fromXmlName(name)
117 attributes.append((attr_string, value))
118
119 for name, value in sorted(attributes):
120 rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value))
121
122 if element.text:
123 rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text))
124 indent += 2
125 for child in element:
126 serializeElement(child, indent)
127 if hasattr(element, "tail") and element.tail:
128 rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail))
129 serializeElement(element, 0)
130
131 return "\n".join(rv)
132
133
134def tostring(element):
135 """Serialize an element and its child nodes to a string"""
136 rv = []
137
138 def serializeElement(element):
139 if not hasattr(element, "tag"):
140 if element.docinfo.internalDTD:
141 if element.docinfo.doctype:
142 dtd_str = element.docinfo.doctype
143 else:
144 dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name
145 rv.append(dtd_str)
146 serializeElement(element.getroot())
147
148 elif element.tag == comment_type:
149 rv.append("<!--%s-->" % (element.text,))
150
151 else:
152 # This is assumed to be an ordinary element
153 if not element.attrib:
154 rv.append("<%s>" % (element.tag,))
155 else:
156 attr = " ".join(["%s=\"%s\"" % (name, value)
157 for name, value in element.attrib.items()])
158 rv.append("<%s %s>" % (element.tag, attr))
159 if element.text:
160 rv.append(element.text)
161
162 for child in element:
163 serializeElement(child)
164
165 rv.append("</%s>" % (element.tag,))
166
167 if hasattr(element, "tail") and element.tail:
168 rv.append(element.tail)
169
170 serializeElement(element)
171
172 return "".join(rv)
173
174
175class TreeBuilder(base.TreeBuilder):
176 documentClass = Document
177 doctypeClass = DocumentType
178 elementClass = None
179 commentClass = None
180 fragmentClass = Document
181 implementation = etree
182
183 def __init__(self, namespaceHTMLElements, fullTree=False):
184 builder = etree_builders.getETreeModule(etree, fullTree=fullTree)
185 infosetFilter = self.infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True)
186 self.namespaceHTMLElements = namespaceHTMLElements
187
188 class Attributes(dict):
189 def __init__(self, element, value=None):
190 if value is None:
191 value = {}
192 self._element = element
193 dict.__init__(self, value) # pylint:disable=non-parent-init-called
194 for key, value in self.items():
195 if isinstance(key, tuple):
196 name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1]))
197 else:
198 name = infosetFilter.coerceAttribute(key)
199 self._element._element.attrib[name] = value
200
201 def __setitem__(self, key, value):
202 dict.__setitem__(self, key, value)
203 if isinstance(key, tuple):
204 name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1]))
205 else:
206 name = infosetFilter.coerceAttribute(key)
207 self._element._element.attrib[name] = value
208
209 class Element(builder.Element):
210 def __init__(self, name, namespace):
211 name = infosetFilter.coerceElement(name)
212 builder.Element.__init__(self, name, namespace=namespace)
213 self._attributes = Attributes(self)
214
215 def _setName(self, name):
216 self._name = infosetFilter.coerceElement(name)
217 self._element.tag = self._getETreeTag(
218 self._name, self._namespace)
219
220 def _getName(self):
221 return infosetFilter.fromXmlName(self._name)
222
223 name = property(_getName, _setName)
224
225 def _getAttributes(self):
226 return self._attributes
227
228 def _setAttributes(self, attributes):
229 self._attributes = Attributes(self, attributes)
230
231 attributes = property(_getAttributes, _setAttributes)
232
233 def insertText(self, data, insertBefore=None):
234 data = infosetFilter.coerceCharacters(data)
235 builder.Element.insertText(self, data, insertBefore)
236
237 def appendChild(self, child):
238 builder.Element.appendChild(self, child)
239
240 class Comment(builder.Comment):
241 def __init__(self, data):
242 data = infosetFilter.coerceComment(data)
243 builder.Comment.__init__(self, data)
244
245 def _setData(self, data):
246 data = infosetFilter.coerceComment(data)
247 self._element.text = data
248
249 def _getData(self):
250 return self._element.text
251
252 data = property(_getData, _setData)
253
254 self.elementClass = Element
255 self.commentClass = Comment
256 # self.fragmentClass = builder.DocumentFragment
257 base.TreeBuilder.__init__(self, namespaceHTMLElements)
258
259 def reset(self):
260 base.TreeBuilder.reset(self)
261 self.insertComment = self.insertCommentInitial
262 self.initial_comments = []
263 self.doctype = None
264
265 def testSerializer(self, element):
266 return testSerializer(element)
267
268 def getDocument(self):
269 if fullTree:
270 return self.document._elementTree
271 else:
272 return self.document._elementTree.getroot()
273
274 def getFragment(self):
275 fragment = []
276 element = self.openElements[0]._element
277 if element.text:
278 fragment.append(element.text)
279 fragment.extend(list(element))
280 if element.tail:
281 fragment.append(element.tail)
282 return fragment
283
284 def insertDoctype(self, token):
285 name = token["name"]
286 publicId = token["publicId"]
287 systemId = token["systemId"]
288
289 if not name:
290 warnings.warn("lxml cannot represent empty doctype", DataLossWarning)
291 self.doctype = None
292 else:
293 coercedName = self.infosetFilter.coerceElement(name)
294 if coercedName != name:
295 warnings.warn("lxml cannot represent non-xml doctype", DataLossWarning)
296
297 doctype = self.doctypeClass(coercedName, publicId, systemId)
298 self.doctype = doctype
299
300 def insertCommentInitial(self, data, parent=None):
301 assert parent is None or parent is self.document
302 assert self.document._elementTree is None
303 self.initial_comments.append(data)
304
305 def insertCommentMain(self, data, parent=None):
306 if (parent == self.document and
307 self.document._elementTree.getroot()[-1].tag == comment_type):
308 warnings.warn("lxml cannot represent adjacent comments beyond the root elements", DataLossWarning)
309 super(TreeBuilder, self).insertComment(data, parent)
310
311 def insertRoot(self, token):
312 # Because of the way libxml2 works, it doesn't seem to be possible to
313 # alter information like the doctype after the tree has been parsed.
314 # Therefore we need to use the built-in parser to create our initial
315 # tree, after which we can add elements like normal
316 docStr = ""
317 if self.doctype:
318 assert self.doctype.name
319 docStr += "<!DOCTYPE %s" % self.doctype.name
320 if (self.doctype.publicId is not None or
321 self.doctype.systemId is not None):
322 docStr += (' PUBLIC "%s" ' %
323 (self.infosetFilter.coercePubid(self.doctype.publicId or "")))
324 if self.doctype.systemId:
325 sysid = self.doctype.systemId
326 if sysid.find("'") >= 0 and sysid.find('"') >= 0:
327 warnings.warn("DOCTYPE system cannot contain single and double quotes", DataLossWarning)
328 sysid = sysid.replace("'", 'U00027')
329 if sysid.find("'") >= 0:
330 docStr += '"%s"' % sysid
331 else:
332 docStr += "'%s'" % sysid
333 else:
334 docStr += "''"
335 docStr += ">"
336 if self.doctype.name != token["name"]:
337 warnings.warn("lxml cannot represent doctype with a different name to the root element", DataLossWarning)
338 docStr += "<THIS_SHOULD_NEVER_APPEAR_PUBLICLY/>"
339 root = etree.fromstring(docStr)
340
341 # Append the initial comments:
342 for comment_token in self.initial_comments:
343 comment = self.commentClass(comment_token["data"])
344 root.addprevious(comment._element)
345
346 # Create the root document and add the ElementTree to it
347 self.document = self.documentClass()
348 self.document._elementTree = root.getroottree()
349
350 # Give the root element the right name
351 name = token["name"]
352 namespace = token.get("namespace", self.defaultNamespace)
353 if namespace is None:
354 etree_tag = name
355 else:
356 etree_tag = "{%s}%s" % (namespace, name)
357 root.tag = etree_tag
358
359 # Add the root element to the internal child/open data structures
360 root_element = self.elementClass(name, namespace)
361 root_element._element = root
362 self.document._childNodes.append(root_element)
363 self.openElements.append(root_element)
364
365 # Reset to the default insert comment function
366 self.insertComment = self.insertCommentMain