// stateBeforeValue occurs after the equals sign but before the value.
// It occurs between the ^'s in ` name =^ ^value`.
stateBeforeValue
- // stateComment occurs inside an <!-- HTML comment -->.
- stateComment
+ // stateHTMLCmt occurs inside an <!-- HTML comment -->.
+ stateHTMLCmt
// stateRCDATA occurs inside an RCDATA element (<textarea> or <title>)
// as described at http://dev.w3.org/html5/spec/syntax.html#elements-0
stateRCDATA
stateAttrName: "stateAttrName",
stateAfterName: "stateAfterName",
stateBeforeValue: "stateBeforeValue",
- stateComment: "stateComment",
+ stateHTMLCmt: "stateHTMLCmt",
stateRCDATA: "stateRCDATA",
stateAttr: "stateAttr",
stateURL: "stateURL",
return fmt.Sprintf("illegal state %d", int(s))
}
+// isComment is true for any state that contains content meant for template
+// authors & maintainers, not for end-users or machines.
+func isComment(s state) bool {
+ switch s {
+ case stateHTMLCmt, stateJSBlockCmt, stateJSLineCmt, stateCSSBlockCmt, stateCSSLineCmt:
+ return true
+ }
+ return false
+}
+
// delim is the delimiter that will end the current HTML attribute.
type delim uint8
s = append(s, "exp_template_html_jsstrescaper")
case stateJSRegexp:
s = append(s, "exp_template_html_jsregexpescaper")
- case stateComment, stateJSBlockCmt, stateJSLineCmt, stateCSSBlockCmt, stateCSSLineCmt:
- return context{
- state: stateError,
- err: errorf(ErrInsideComment, n.Line, "%s appears inside a comment", n),
- }
case stateCSS:
s = append(s, "exp_template_html_cssvaluefilter")
case stateText:
c.state = stateAttrName
s = append(s, "exp_template_html_htmlnamefilter")
default:
+ if isComment(c.state) {
+ return context{
+ state: stateError,
+ err: errorf(ErrInsideComment, n.Line, "%s appears inside a comment", n),
+ }
+ }
panic("unexpected state " + c.state.String())
}
switch c.delim {
},
{
`<!-- foo`,
- context{state: stateComment},
+ context{state: stateHTMLCmt},
},
{
`<!-->`,
- context{state: stateComment},
+ context{state: stateHTMLCmt},
},
{
`<!--->`,
- context{state: stateComment},
+ context{state: stateHTMLCmt},
},
{
`<!-- foo -->`,
},
{
`<script>foo</script><!--`,
- context{state: stateComment},
+ context{state: stateHTMLCmt},
},
{
`<script>document.write("<p>foo</p>");`,
stateAttrName: tAttrName,
stateAfterName: tAfterName,
stateBeforeValue: tBeforeValue,
- stateComment: tComment,
+ stateHTMLCmt: tHTMLCmt,
stateRCDATA: tSpecialTagEnd,
stateAttr: tAttr,
stateURL: tURL,
if i == -1 || i+1 == len(s) {
return c, nil
} else if i+4 <= len(s) && bytes.Equal(commentStart, s[i:i+4]) {
- return context{state: stateComment}, s[i+4:]
+ return context{state: stateHTMLCmt}, s[i+4:]
}
i++
if s[i] == '/' {
return c, s[i:]
}
-// tComment is the context transition function for stateComment.
-func tComment(c context, s []byte) (context, []byte) {
+// tHTMLCmt is the context transition function for stateHTMLCmt.
+func tHTMLCmt(c context, s []byte) (context, []byte) {
i := bytes.Index(s, commentEnd)
if i != -1 {
return context{}, s[i+3:]