diff --git a/src/pkg/exp/template/html/escape.go b/src/pkg/exp/template/html/escape.go
index c6156da122..f629930df7 100644
--- a/src/pkg/exp/template/html/escape.go
+++ b/src/pkg/exp/template/html/escape.go
@@ -100,12 +100,12 @@ type escaper struct {
derived map[string]*template.Template
// called[templateName] is a set of called mangled template names.
called map[string]bool
- // actionNodeEdits and templateNodeEdits are the accumulated edits to
- // apply during commit. Such edits are not applied immediately in case
- // a template set executes a given template in different escaping
- // contexts.
+ // xxxNodeEdits are the accumulated edits to apply during commit.
+ // Such edits are not applied immediately in case a template set
+ // executes a given template in different escaping contexts.
actionNodeEdits map[*parse.ActionNode][]string
templateNodeEdits map[*parse.TemplateNode]string
+ textNodeEdits map[*parse.TextNode][]byte
}
// newEscaper creates a blank escaper for the given set.
@@ -117,6 +117,7 @@ func newEscaper(s *template.Set) *escaper {
map[string]bool{},
map[*parse.ActionNode][]string{},
map[*parse.TemplateNode]string{},
+ map[*parse.TextNode][]byte{},
}
}
@@ -141,7 +142,7 @@ func (e *escaper) escape(c context, n parse.Node) context {
case *parse.TemplateNode:
return e.escapeTemplate(c, n)
case *parse.TextNode:
- return e.escapeText(c, n.Text)
+ return e.escapeText(c, n)
case *parse.WithNode:
return e.escapeBranch(c, &n.BranchNode, "with")
}
@@ -386,6 +387,9 @@ func (e *escaper) escapeListConditionally(c context, n *parse.ListNode, filter f
for k, v := range e1.templateNodeEdits {
e.editTemplateNode(k, v)
}
+ for k, v := range e1.textNodeEdits {
+ e.editTextNode(k, v)
+ }
}
return c, ok
}
@@ -493,38 +497,57 @@ var delimEnds = [...]string{
}
// escapeText escapes a text template node.
-func (e *escaper) escapeText(c context, s []byte) context {
+func (e *escaper) escapeText(c context, n *parse.TextNode) context {
+ s, written := n.Text, 0
+ var b bytes.Buffer
for len(s) > 0 {
- if c.delim == delimNone {
- c, s = transitionFunc[c.state](c, s)
- continue
- }
-
- i := bytes.IndexAny(s, delimEnds[c.delim])
- if i == -1 {
- // Remain inside the attribute.
- // Decode the value so non-HTML rules can easily handle
- //