Commit da6b94fd authored by Evan Simpson's avatar Evan Simpson

Add action cancellation.

parent 06018f21
...@@ -92,6 +92,8 @@ import string ...@@ -92,6 +92,8 @@ import string
from TALDefs import NAME_RE, TALError, TALESError from TALDefs import NAME_RE, TALError, TALESError
CancelAction = []
class DummyEngine: class DummyEngine:
def __init__(self, macros=None): def __init__(self, macros=None):
...@@ -120,10 +122,12 @@ class DummyEngine: ...@@ -120,10 +122,12 @@ class DummyEngine:
if self.locals is self.stack[-1]: if self.locals is self.stack[-1]:
# Unmerge this scope's locals from previous scope of first set # Unmerge this scope's locals from previous scope of first set
self.locals = self.locals.copy() self.locals = self.locals.copy()
self.locals[name] = value if value is not CancelAction:
self.locals[name] = value
def setGlobal(self, name, value): def setGlobal(self, name, value):
self.globals[name] = value if value is not CancelAction:
self.globals[name] = value
def evaluate(self, expression): def evaluate(self, expression):
expression = self.uncompile(expression) expression = self.uncompile(expression)
...@@ -221,6 +225,9 @@ class DummyEngine: ...@@ -221,6 +225,9 @@ class DummyEngine:
def getTALESError(self): def getTALESError(self):
return TALESError return TALESError
def getCancelAction(self):
return CancelAction
class Iterator: class Iterator:
def __init__(self, name, seq, engine): def __init__(self, name, seq, engine):
......
...@@ -347,7 +347,7 @@ class TALGenerator: ...@@ -347,7 +347,7 @@ class TALGenerator:
del repldict[key] del repldict[key]
newlist.append(item) newlist.append(item)
for key, value in repldict.items(): # Add dynamic-only attributes for key, value in repldict.items(): # Add dynamic-only attributes
item = (key, "", "replace", value) item = (key, None, "insert", value)
newlist.append(item) newlist.append(item)
return newlist return newlist
......
...@@ -96,7 +96,7 @@ try: ...@@ -96,7 +96,7 @@ try:
except ImportError: except ImportError:
from StringIO import StringIO from StringIO import StringIO
from TALDefs import quote, TAL_VERSION, METALError from TALDefs import quote, TAL_VERSION, TALError, METALError
from TALDefs import isCurrentVersion, getProgramVersion, getProgramMode from TALDefs import isCurrentVersion, getProgramVersion, getProgramMode
from TALGenerator import TALGenerator from TALGenerator import TALGenerator
...@@ -157,6 +157,7 @@ class TALInterpreter: ...@@ -157,6 +157,7 @@ class TALInterpreter:
self.macros = macros self.macros = macros
self.engine = engine self.engine = engine
self.TALESError = engine.getTALESError() self.TALESError = engine.getTALESError()
self.CancelAction = engine.getCancelAction()
self.stream = stream or sys.stdout self.stream = stream or sys.stdout
self.debug = debug self.debug = debug
self.wrap = wrap self.wrap = wrap
...@@ -245,6 +246,7 @@ class TALInterpreter: ...@@ -245,6 +246,7 @@ class TALInterpreter:
def do_startTag(self, name, attrList): def do_startTag(self, name, attrList):
self.startTagCommon(name, attrList, ">") self.startTagCommon(name, attrList, ">")
actionIndex = ["replace", "insert", "metal", "tal", "xmlns"].index
def startTagCommon(self, name, attrList, end): def startTagCommon(self, name, attrList, end):
if not attrList: if not attrList:
self.stream_write("<%s%s" % (name, end)) self.stream_write("<%s%s" % (name, end))
...@@ -254,21 +256,32 @@ class TALInterpreter: ...@@ -254,21 +256,32 @@ class TALInterpreter:
for item in attrList: for item in attrList:
name, value = item[:2] name, value = item[:2]
if len(item) > 2: if len(item) > 2:
action = item[2] try:
if not self.showtal and action in ("tal", "metal", "xmlns"): action = self.actionIndex(item[2])
except ValueError:
raise TALError, ('Error in TAL program', self.position)
if not self.showtal and action > 1:
continue continue
if action == "replace" and len(item) > 3 and self.tal: if action <= 1 and self.tal:
if self.html and string.lower(name) in BOOLEAN_HTML_ATTRS: if self.html and string.lower(name) in BOOLEAN_HTML_ATTRS:
ok = self.engine.evaluateBoolean(item[3]) evalue = self.engine.evaluateBoolean(item[3])
if not ok: if evalue is self.CancelAction:
if action == 1: # Cancelled insert
continue
elif not evalue:
continue continue
else: else:
value = None value = None
else: else:
value = self.engine.evaluateText(item[3]) evalue = self.engine.evaluateText(item[3])
if value is None: if evalue is self.CancelAction:
continue if action == 1: # Cancelled insert
elif (action == "metal" and self.currentMacro and continue
else:
value = item[1]
if value is None:
continue
elif (action == 2 and self.currentMacro and
name[-13:] == ":define-macro" and self.metal): name[-13:] == ":define-macro" and self.metal):
name = name[:-13] + ":use-macro" name = name[:-13] + ":use-macro"
value = self.currentMacro value = self.currentMacro
...@@ -314,6 +327,9 @@ class TALInterpreter: ...@@ -314,6 +327,9 @@ class TALInterpreter:
text = self.engine.evaluateText(expr) text = self.engine.evaluateText(expr)
if text is None: if text is None:
return return
if text is self.CancelAction:
self.interpret(block)
return
text = cgi.escape(text) text = cgi.escape(text)
self.stream_write(text) self.stream_write(text)
...@@ -324,6 +340,9 @@ class TALInterpreter: ...@@ -324,6 +340,9 @@ class TALInterpreter:
structure = self.engine.evaluateStructure(expr) structure = self.engine.evaluateStructure(expr)
if structure is None: if structure is None:
return return
if structure is self.CancelAction:
self.interpret(block)
return
text = str(structure) text = str(structure)
if not repldict and not self.strictinsert: if not repldict and not self.strictinsert:
# Take a shortcut, no error checking # Take a shortcut, no error checking
...@@ -378,6 +397,9 @@ class TALInterpreter: ...@@ -378,6 +397,9 @@ class TALInterpreter:
self.interpret(block) self.interpret(block)
return return
macro = self.engine.evaluateMacro(macroExpr) macro = self.engine.evaluateMacro(macroExpr)
if macro is self.CancelAction:
self.interpret(block)
return
if not isCurrentVersion(macro): if not isCurrentVersion(macro):
raise METALError("macro %s has incompatible version %s" % raise METALError("macro %s has incompatible version %s" %
(`macroName`, `getProgramVersion(macro)`), (`macroName`, `getProgramVersion(macro)`),
......
...@@ -332,7 +332,7 @@ class TALGeneratorTestCases(TestCaseBase): ...@@ -332,7 +332,7 @@ class TALGeneratorTestCases(TestCaseBase):
('name', 'bar'), ('name', 'bar'),
('tal:attributes', ('tal:attributes',
'href string:http://www.zope.org; x string:y', 'tal'), 'href string:http://www.zope.org; x string:y', 'tal'),
('x', '', 'replace', '$string:y$')]), ('x', None, 'insert', '$string:y$')]),
('rawtext', 'link</a>'), ('rawtext', 'link</a>'),
]) ])
self._run_check("<p tal:replace='structure string:<img>' " self._run_check("<p tal:replace='structure string:<img>' "
......
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