Coverage for grm\plugin\dom.py: 0%

167 statements  

« prev     ^ index     » next       coverage.py v7.2.3, created at 2023-04-10 14:44 +0900

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)