Commit c6594026 authored by Guido van Rossum's avatar Guido van Rossum

Insert proper xmlns attributes.

Running the test suite with this version ("./runtest.sh -c") now shows
two failures:

- test2: the checked-in test output is missing the xmlns="..."
  attributes because the Printer module doesn't emit these for
  prefix-less xmlns attributes (in cases where node.namespaceURI is
  set but node.prefix is None).

- test8: this version emits a redundant xmlns:m attribute on the
  expanded macro element.  AFAICT this is OK according to the XMLNS
  standard.  The redundant attribute is emitted because macros are
  compiled without context (since they may be used in a different
  context).
parent f7880ca5
...@@ -86,8 +86,7 @@ ...@@ -86,8 +86,7 @@
Compile a DOM tree for efficient TAL expansion. Compile a DOM tree for efficient TAL expansion.
XXX TO DO: XXX TO DO:
- xmlns attributes - get macro use/define substitution right (currently ignores prefix)
- get macro use/define substitution right
""" """
import string import string
...@@ -110,6 +109,8 @@ class TALCompiler(DOMVisitor): ...@@ -110,6 +109,8 @@ class TALCompiler(DOMVisitor):
self.macros = {} self.macros = {}
self.program = [] self.program = []
self.stack = [] self.stack = []
self.namespaceDict = {}
self.namespaceStack = [self.namespaceDict]
DOMVisitor.__call__(self) DOMVisitor.__call__(self)
assert not self.stack assert not self.stack
return self.program, self.macros return self.program, self.macros
...@@ -123,22 +124,57 @@ class TALCompiler(DOMVisitor): ...@@ -123,22 +124,57 @@ class TALCompiler(DOMVisitor):
self.program = self.stack.pop() self.program = self.stack.pop()
return program return program
def pushNS(self):
self.namespaceStack.append(self.namespaceDict)
def popNS(self):
self.namespaceDict = self.namespaceStack.pop()
def newNS(self, prefix, namespaceURI):
if self.namespaceDict is self.namespaceStack[-1]:
self.namespaceDict = self.namespaceDict.copy()
if self.namespaceDict.get(prefix) != namespaceURI:
self.namespaceDict[prefix] = namespaceURI
return 1
else:
return 0
def getFullAttrList(self, node):
list = []
if node.namespaceURI:
if self.newNS(node.prefix, node.namespaceURI):
if node.prefix:
list.append(("xmlns:" + node.prefix, node.namespaceURI))
else:
list.append(("xmlns", node.namespaceURI))
for attr in node.attributes.values():
if attr.namespaceURI:
if self.newNS(attr.prefix, attr.namespaceURI):
list.append(("xmlns:" + attr.prefix, attr.namespaceURI))
list.extend(getAttributeList(node))
return list
def emit(self, *instruction): def emit(self, *instruction):
self.program.append(instruction) self.program.append(instruction)
def emitStartTag(self, node): def emitStartTag(self, node):
self.emit("startTag", node.nodeName, getAttributeList(node)) self.emit("startTag", node.nodeName, self.getFullAttrList(node))
def emitStartEndTag(self, node): def emitStartEndTag(self, node):
self.emit("startEndTag", node.nodeName, getAttributeList(node)) self.emit("startEndTag", node.nodeName, self.getFullAttrList(node))
def emitEndTag(self, node): def emitEndTag(self, node):
self.emit("endTag", node.nodeName) self.emit("endTag", node.nodeName)
def visitElement(self, node): def visitElement(self, node):
self.pushNS()
if not node.hasAttributes(): if not node.hasAttributes():
self.emitElement(node) self.emitElement(node)
return else:
self.expandElement(node)
self.popNS()
def expandElement(self, node):
macroName = node.getAttributeNS(ZOPE_METAL_NS, "use-macro") macroName = node.getAttributeNS(ZOPE_METAL_NS, "use-macro")
if macroName: if macroName:
slotDict = slotIndexer(node) slotDict = slotIndexer(node)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment