mirror of https://github.com/python/cpython.git
give minidom.py behaviour that complies with the DOM Level 1 REC, which says that when a node newChild is added to the tree, "if the newChild is already in the tree, it is first removed." pulldom.py is patched to use the public minidom interface instead of setting .parentNode itself. Possibly this reduces pulldom's efficiency; someone else will have to pronounce on that.
This commit is contained in:
parent
34c20cf705
commit
04a45e9bb1
|
@ -40,6 +40,7 @@ class Node(_Node):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.childNodes = []
|
self.childNodes = []
|
||||||
|
self.parentNode = None
|
||||||
if Node._debug:
|
if Node._debug:
|
||||||
index = repr(id(self)) + repr(self.__class__)
|
index = repr(id(self)) + repr(self.__class__)
|
||||||
Node.allnodes[index] = repr(self.__dict__)
|
Node.allnodes[index] = repr(self.__dict__)
|
||||||
|
@ -98,6 +99,8 @@ def _get_lastChild(self):
|
||||||
return self.childNodes[-1]
|
return self.childNodes[-1]
|
||||||
|
|
||||||
def insertBefore(self, newChild, refChild):
|
def insertBefore(self, newChild, refChild):
|
||||||
|
if newChild.parentNode is not None:
|
||||||
|
newChild.parentNode.removeChild(newChild)
|
||||||
if refChild is None:
|
if refChild is None:
|
||||||
self.appendChild(newChild)
|
self.appendChild(newChild)
|
||||||
else:
|
else:
|
||||||
|
@ -116,6 +119,8 @@ def insertBefore(self, newChild, refChild):
|
||||||
return newChild
|
return newChild
|
||||||
|
|
||||||
def appendChild(self, node):
|
def appendChild(self, node):
|
||||||
|
if node.parentNode is not None:
|
||||||
|
node.parentNode.removeChild(node)
|
||||||
if self.childNodes:
|
if self.childNodes:
|
||||||
last = self.lastChild
|
last = self.lastChild
|
||||||
node.previousSibling = last
|
node.previousSibling = last
|
||||||
|
@ -129,6 +134,8 @@ def appendChild(self, node):
|
||||||
return node
|
return node
|
||||||
|
|
||||||
def replaceChild(self, newChild, oldChild):
|
def replaceChild(self, newChild, oldChild):
|
||||||
|
if newChild.parentNode is not None:
|
||||||
|
newChild.parentNode.removeChild(newChild)
|
||||||
if newChild is oldChild:
|
if newChild is oldChild:
|
||||||
return
|
return
|
||||||
index = self.childNodes.index(oldChild)
|
index = self.childNodes.index(oldChild)
|
||||||
|
@ -144,6 +151,12 @@ def replaceChild(self, newChild, oldChild):
|
||||||
|
|
||||||
def removeChild(self, oldChild):
|
def removeChild(self, oldChild):
|
||||||
self.childNodes.remove(oldChild)
|
self.childNodes.remove(oldChild)
|
||||||
|
if oldChild.nextSibling is not None:
|
||||||
|
oldChild.nextSibling.previousSibling = oldChild.previousSibling
|
||||||
|
if oldChild.previousSibling is not None:
|
||||||
|
oldChild.previousSibling.nextSibling = oldChild.nextSibling
|
||||||
|
oldChild.nextSibling = oldChild.previousSibling = None
|
||||||
|
|
||||||
if self._makeParentNodes:
|
if self._makeParentNodes:
|
||||||
oldChild.parentNode = None
|
oldChild.parentNode = None
|
||||||
return oldChild
|
return oldChild
|
||||||
|
@ -606,11 +619,23 @@ class Document(Node):
|
||||||
implementation = DOMImplementation()
|
implementation = DOMImplementation()
|
||||||
|
|
||||||
def appendChild(self, node):
|
def appendChild(self, node):
|
||||||
|
if node.parentNode is not None:
|
||||||
|
node.parentNode.removeChild(node)
|
||||||
|
|
||||||
if node.nodeType == Node.ELEMENT_NODE \
|
if node.nodeType == Node.ELEMENT_NODE \
|
||||||
and self._get_documentElement():
|
and self._get_documentElement():
|
||||||
raise TypeError, "two document elements disallowed"
|
raise TypeError, "two document elements disallowed"
|
||||||
return Node.appendChild(self, node)
|
return Node.appendChild(self, node)
|
||||||
|
|
||||||
|
def removeChild(self, oldChild):
|
||||||
|
self.childNodes.remove(oldChild)
|
||||||
|
oldChild.nextSibling = oldChild.previousSibling = None
|
||||||
|
oldChild.parentNode = None
|
||||||
|
if self.documentElement is oldChild:
|
||||||
|
self.documentElement = None
|
||||||
|
|
||||||
|
return oldChild
|
||||||
|
|
||||||
def _get_documentElement(self):
|
def _get_documentElement(self):
|
||||||
for node in self.childNodes:
|
for node in self.childNodes:
|
||||||
if node.nodeType == Node.ELEMENT_NODE:
|
if node.nodeType == Node.ELEMENT_NODE:
|
||||||
|
|
|
@ -55,7 +55,9 @@ def startElementNS(self, name, tagName , attrs):
|
||||||
attr.value = value
|
attr.value = value
|
||||||
node.setAttributeNode(attr)
|
node.setAttributeNode(attr)
|
||||||
|
|
||||||
node.parentNode = self.curNode
|
## print self.curNode, self.curNode.childNodes, node, node.parentNode
|
||||||
|
self.curNode.appendChild(node)
|
||||||
|
# node.parentNode = self.curNode
|
||||||
self.curNode = node
|
self.curNode = node
|
||||||
|
|
||||||
self.lastEvent[1] = [(START_ELEMENT, node), None]
|
self.lastEvent[1] = [(START_ELEMENT, node), None]
|
||||||
|
@ -77,7 +79,8 @@ def startElement(self, name, attrs):
|
||||||
attr.value = value
|
attr.value = value
|
||||||
node.setAttributeNode(attr)
|
node.setAttributeNode(attr)
|
||||||
|
|
||||||
node.parentNode = self.curNode
|
#node.parentNode = self.curNode
|
||||||
|
self.curNode.appendChild(node)
|
||||||
self.curNode = node
|
self.curNode = node
|
||||||
|
|
||||||
self.lastEvent[1] = [(START_ELEMENT, node), None]
|
self.lastEvent[1] = [(START_ELEMENT, node), None]
|
||||||
|
@ -93,8 +96,9 @@ def endElement(self, name):
|
||||||
|
|
||||||
def comment(self, s):
|
def comment(self, s):
|
||||||
node = self.document.createComment(s)
|
node = self.document.createComment(s)
|
||||||
parent = self.curNode
|
self.curNode.appendChild(node)
|
||||||
node.parentNode = parent
|
# parent = self.curNode
|
||||||
|
# node.parentNode = parent
|
||||||
self.lastEvent[1] = [(COMMENT, node), None]
|
self.lastEvent[1] = [(COMMENT, node), None]
|
||||||
self.lastEvent = self.lastEvent[1]
|
self.lastEvent = self.lastEvent[1]
|
||||||
#self.events.append((COMMENT, node))
|
#self.events.append((COMMENT, node))
|
||||||
|
@ -102,24 +106,27 @@ def comment(self, s):
|
||||||
def processingInstruction(self, target, data):
|
def processingInstruction(self, target, data):
|
||||||
node = self.document.createProcessingInstruction(target, data)
|
node = self.document.createProcessingInstruction(target, data)
|
||||||
|
|
||||||
parent = self.curNode
|
self.curNode.appendChild(node)
|
||||||
node.parentNode = parent
|
# parent = self.curNode
|
||||||
|
# node.parentNode = parent
|
||||||
self.lastEvent[1] = [(PROCESSING_INSTRUCTION, node), None]
|
self.lastEvent[1] = [(PROCESSING_INSTRUCTION, node), None]
|
||||||
self.lastEvent = self.lastEvent[1]
|
self.lastEvent = self.lastEvent[1]
|
||||||
#self.events.append((PROCESSING_INSTRUCTION, node))
|
#self.events.append((PROCESSING_INSTRUCTION, node))
|
||||||
|
|
||||||
def ignorableWhitespace(self, chars):
|
def ignorableWhitespace(self, chars):
|
||||||
node = self.document.createTextNode(chars)
|
node = self.document.createTextNode(chars)
|
||||||
parent = self.curNode
|
self.curNode.appendChild(node)
|
||||||
node.parentNode = parent
|
# parent = self.curNode
|
||||||
|
# node.parentNode = parent
|
||||||
self.lastEvent[1] = [(IGNORABLE_WHITESPACE, node), None]
|
self.lastEvent[1] = [(IGNORABLE_WHITESPACE, node), None]
|
||||||
self.lastEvent = self.lastEvent[1]
|
self.lastEvent = self.lastEvent[1]
|
||||||
#self.events.append((IGNORABLE_WHITESPACE, node))
|
#self.events.append((IGNORABLE_WHITESPACE, node))
|
||||||
|
|
||||||
def characters(self, chars):
|
def characters(self, chars):
|
||||||
node = self.document.createTextNode(chars)
|
node = self.document.createTextNode(chars)
|
||||||
parent = self.curNode
|
self.curNode.appendChild(node)
|
||||||
node.parentNode = parent
|
# parent = self.curNode
|
||||||
|
# node.parentNode = parent
|
||||||
self.lastEvent[1] = [(CHARACTERS, node), None]
|
self.lastEvent[1] = [(CHARACTERS, node), None]
|
||||||
self.lastEvent = self.lastEvent[1]
|
self.lastEvent = self.lastEvent[1]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue