Skip to content

Commit

Permalink
HTML: update template support
Browse files Browse the repository at this point in the history
  • Loading branch information
tdewolff committed Oct 30, 2023
1 parent c2a5213 commit 6a5fe33
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 37 deletions.
12 changes: 11 additions & 1 deletion html/lex.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func (l *Lexer) AttrVal() []byte {
return l.attrVal
}

// AttrHasTemplate returns the true if the attribute value contains a template.
// HasTemplate returns the true if the token value contains a template.
func (l *Lexer) HasTemplate() bool {
return l.hasTmpl
}
Expand Down Expand Up @@ -379,6 +379,11 @@ func (l *Lexer) shiftStartTag() (TokenType, []byte) {
func (l *Lexer) shiftAttribute() []byte {
nameStart := l.r.Pos()
var c byte
if 0 < len(l.tmplBegin) && l.at(l.tmplBegin...) {
l.r.Move(len(l.tmplBegin))
l.moveTemplate()
l.hasTmpl = true
}
for { // attribute name state
if c = l.r.Peek(0); c == ' ' || c == '=' || c == '>' || c == '/' && l.r.Peek(1) == '>' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == 0 && l.r.Err() != nil {
break
Expand Down Expand Up @@ -438,6 +443,11 @@ func (l *Lexer) shiftAttribute() []byte {
l.r.Rewind(nameEnd)
l.attrVal = nil
}
if 0 < len(l.tmplBegin) && l.at(l.tmplBegin...) {
l.r.Move(len(l.tmplBegin))
l.moveTemplate()
l.hasTmpl = true
}
l.text = parse.ToLower(l.r.Lexeme()[nameStart:nameEnd])
return l.r.Shift()
}
Expand Down
48 changes: 12 additions & 36 deletions html/lex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,54 +182,30 @@ func TestAttributes(t *testing.T) {

func TestTemplates(t *testing.T) {
var tests = []struct {
html string
expected []TokenType
}{
{"<p>{{.}}</p>", TTs{StartTagToken, StartTagCloseToken, TemplateToken, EndTagToken}},
{"<p> {{.}} </p>", TTs{StartTagToken, StartTagCloseToken, TextToken, TemplateToken, TextToken, EndTagToken}},
{"<input type='{{.}}'/>", TTs{StartTagToken, AttributeToken, StartTagVoidToken}},
{"<input type={{.}} />", TTs{StartTagToken, AttributeToken, StartTagVoidToken}},
}
for _, tt := range tests {
t.Run(tt.html, func(t *testing.T) {
l := NewTemplateLexer(parse.NewInputString(tt.html), GoTemplate)
i := 0
tokens := []TokenType{}
for {
token, _ := l.Next()
if token == ErrorToken {
test.T(t, l.Err(), io.EOF)
break
}
tokens = append(tokens, token)
i++
}
test.T(t, tokens, tt.expected, "token types must match")
})
}
}

func TestTemplateAttributess(t *testing.T) {
var tests = []struct {
html string
hasTmpl bool
html string
tmpl []bool
}{
{"<input type='{value}'/>", false},
{"<input type='{{.}}'/>", true},
{"<input type={{.}} />", true},
{"<p>{{.}}</p>", []bool{true}},
{"<p> {{.}} </p>", []bool{true}},
{"<input type='{{.}}'/>", []bool{true}},
{"<input type={{.}} />", []bool{true}},
{"<input {{if eq .Type 0}}selected{{end}}>", []bool{true}},
{"<input {{if eq .Type 0}} selected {{end}}>", []bool{true, false, true}},
}
for _, tt := range tests {
t.Run(tt.html, func(t *testing.T) {
l := NewTemplateLexer(parse.NewInputString(tt.html), GoTemplate)
tmpl := []bool{}
for {
token, _ := l.Next()
if token == ErrorToken {
test.T(t, l.Err(), io.EOF)
break
} else if token == AttributeToken {
test.T(t, l.AttrHasTemplate(), tt.hasTmpl)
} else if token == TextToken || token == AttributeToken {
tmpl = append(tmpl, l.HasTemplate())
}
}
test.T(t, tmpl, tt.tmpl, "HasTemplate must match")
})
}
}
Expand Down

0 comments on commit 6a5fe33

Please sign in to comment.