Skip to content

Commit

Permalink
fix(fmt): incorrect conversion from single to double quotes, fixes #380
Browse files Browse the repository at this point in the history
  • Loading branch information
a-h committed Jan 2, 2024
1 parent abee9d0 commit 5579e47
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.2.508
0.2.513
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,18 +78,20 @@ Run Go tests.
# Create test profile directories.
mkdir -p coverage/fmt
mkdir -p coverage/generate
mkdir -p coverage/version
mkdir -p coverage/unit
# Build the test binary.
go build -cover -o ./coverage/templ-cover ./cmd/templ
# Run the covered generate command.
GOCOVERDIR=coverage/fmt ./coverage/templ-cover fmt .
GOCOVERDIR=coverage/generate ./coverage/templ-cover generate -include-version=false
GOCOVERDIR=coverage/version ./coverage/templ-cover version
# Run the unit tests.
go test -cover ./... -args -test.gocoverdir="$PWD/coverage/unit"
# Display the combined percentage.
go tool covdata percent -i=./coverage/fmt,./coverage/generate,./coverage/unit
go tool covdata percent -i=./coverage/fmt,./coverage/generate,./coverage/version,./coverage/unit
# Generate a text coverage profile for tooling to use.
go tool covdata textfmt -i=./coverage/fmt,./coverage/generate,./coverage/unit -o coverage.out
go tool covdata textfmt -i=./coverage/fmt,./coverage/generate,./coverage/version,./coverage/unit -o coverage.out
# Print total
go tool cover -func coverage.out | grep total
```
Expand Down
3 changes: 3 additions & 0 deletions generator/test-attribute-escaping/expected.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
<div>
<a href="about:invalid#TemplFailedSanitizationURL">text</a>
</div>
<div>
<button hx-post="/click" hx-trigger="click" hx-vals='{"val":"Value"}'>Click</button>
</div>
7 changes: 7 additions & 0 deletions generator/test-attribute-escaping/template.templ
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,11 @@ templ BasicTemplate(url string) {
<div>
<a href={ templ.URL(url) }>text</a>
</div>
<div>
<button
hx-post="/click"
hx-trigger="click"
hx-vals='{"val":"Value"}'
>Click</button>
</div>
}
11 changes: 10 additions & 1 deletion generator/test-attribute-escaping/template_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions parser/v2/elementparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ var (
if result.B.OK {
valueParser = attributeConstantValueSingleQuoteParser
closeParser = parse.String(`'`)
attr.SingleQuote = true
}

// Attribute value.
Expand All @@ -140,6 +141,10 @@ var (
}

attr.Value = html.UnescapeString(attr.Value)
// Only use single quotes if actually required, due to double quote in the value (prefer double quotes).
if attr.SingleQuote && !strings.Contains(attr.Value, "\"") {
attr.SingleQuote = false
}

// " - closing quote.
if _, ok, err = closeParser.Parse(pi); err != nil || !ok {
Expand Down
17 changes: 14 additions & 3 deletions parser/v2/elementparser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,23 @@ if test {
},
},
{
name: "single quote constant attribute",
name: "single quote not required constant attribute",
input: ` href='no double quote in value'`,
parser: StripType(constantAttributeParser),
expected: ConstantAttribute{
Name: "href",
Value: `no double quote in value`,
SingleQuote: false,
},
},
{
name: "single quote required constant attribute",
input: ` href='"test"'`,
parser: StripType(constantAttributeParser),
expected: ConstantAttribute{
Name: "href",
Value: `"test"`,
Name: "href",
Value: `"test"`,
SingleQuote: true,
},
},
{
Expand Down
5 changes: 4 additions & 1 deletion parser/v2/templelementparser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ func TestTemplElementExpressionParser(t *testing.T) {
Children: []Node{
Whitespace{Value: "\n\t\t\t"},
Element{Name: "a", Attributes: []Attribute{
ConstantAttribute{"href", "someurl"},
ConstantAttribute{
Name: "href",
Value: "someurl",
},
},
TrailingSpace: SpaceVertical,
},
Expand Down
11 changes: 8 additions & 3 deletions parser/v2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -690,12 +690,17 @@ func (bca BoolConstantAttribute) Write(w io.Writer, indent int) error {

// href=""
type ConstantAttribute struct {
Name string
Value string
Name string
Value string
SingleQuote bool
}

func (ca ConstantAttribute) String() string {
return ca.Name + `="` + ca.Value + `"`
quote := `"`
if ca.SingleQuote {
quote = `'`
}
return ca.Name + `=` + quote + ca.Value + quote
}

func (ca ConstantAttribute) Write(w io.Writer, indent int) error {
Expand Down
22 changes: 22 additions & 0 deletions parser/v2/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,28 @@ package test
templ nested() {
<div>{ "the" }<div>{ "other" }</div></div>
}
`,
},
{
name: "constant attributes prerfer double quotes, but use single quotes if required",
input: ` // first line removed to make indentation clear in Go code
package test
templ nested() {
<div class="double">double</div>
<div class='single-not-required'>single-not-required</div>
<div data-value='{"data":"value"}'>single-required</div>
}
`,
expected: `// first line removed to make indentation clear in Go code
package test
templ nested() {
<div class="double">double</div>
<div class="single-not-required">single-not-required</div>
<div data-value='{"data":"value"}'>single-required</div>
}
`,
},
{
Expand Down

0 comments on commit 5579e47

Please sign in to comment.