Make boolean attributes more useable

This commit is contained in:
Brandon Dyck 2020-05-25 15:18:17 -06:00
parent a671ad57e2
commit 4cb7457606
9 changed files with 109 additions and 32 deletions

View File

@ -10,6 +10,8 @@
- `hatmill.Attrib.Value` is now an `fmt.Stringer`.
- Attribute code generation mostly uses interfaces instead of being so ad-hoc.
- Empty `hatmill.Attrib`s are not rendered at all in HTML.
- Generated boolean attribute helper function now have a boolean parameter rather than depending on the presence of the call.
### Removed

View File

@ -20,11 +20,11 @@ func TestCoordsList(t *testing.T) {
{name: "zero", f: 0, s: "0"},
{name: "integral", f: 45, s: "45"},
{name: "positive fractional, small positive exponent", f: 12.55, s: "12.55"},
{name: "positive fractional, large positive exponent", f: 1.55E+12, s: "1.55E+12"},
{name: "positive fractional, large negative exponent", f: 1.55E-12, s: "1.55E-12"},
{name: "positive fractional, large positive exponent", f: 1.55e+12, s: "1.55E+12"},
{name: "positive fractional, large negative exponent", f: 1.55e-12, s: "1.55E-12"},
{name: "negative fractional, small positive exponent", f: -12.55, s: "-12.55"},
{name: "negative fractional, large positive exponent", f: -1.55E+12, s: "-1.55E+12"},
{name: "negative fractional, large negative exponent", f: -1.55E-12, s: "-1.55E-12"},
{name: "negative fractional, large positive exponent", f: -1.55e+12, s: "-1.55E+12"},
{name: "negative fractional, large negative exponent", f: -1.55e-12, s: "-1.55E-12"},
} {
t.Run(testcase.name, func(t *testing.T) {
expectEqualStrings(t, attribute.CoordsList{testcase.f}.String(), testcase.s)

View File

@ -38,7 +38,10 @@ func Alt(value string) hatmill.Attrib {
}
// Async creates a "async" attribute
func Async() hatmill.Attrib {
func Async(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "async",
}
@ -61,14 +64,20 @@ func Autocomplete(value string) hatmill.Attrib {
}
// Autofocus creates a "autofocus" attribute
func Autofocus() hatmill.Attrib {
func Autofocus(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "autofocus",
}
}
// Autoplay creates a "autoplay" attribute
func Autoplay() hatmill.Attrib {
func Autoplay(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "autoplay",
}
@ -83,7 +92,10 @@ func Charset(value string) hatmill.Attrib {
}
// Checked creates a "checked" attribute
func Checked() hatmill.Attrib {
func Checked(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "checked",
}
@ -146,7 +158,10 @@ func Contextmenu(value string) hatmill.Attrib {
}
// Controls creates a "controls" attribute
func Controls() hatmill.Attrib {
func Controls(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "controls",
}
@ -177,14 +192,20 @@ func Decoding(value string) hatmill.Attrib {
}
// Default creates a "default" attribute
func Default() hatmill.Attrib {
func Default(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "default",
}
}
// Defer creates a "defer" attribute
func Defer() hatmill.Attrib {
func Defer(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "defer",
}
@ -207,7 +228,10 @@ func Dirname(value string) hatmill.Attrib {
}
// Disabled creates a "disabled" attribute
func Disabled() hatmill.Attrib {
func Disabled(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "disabled",
}
@ -286,7 +310,10 @@ func Height(value int) hatmill.Attrib {
}
// Hidden creates a "hidden" attribute
func Hidden() hatmill.Attrib {
func Hidden(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "hidden",
}
@ -333,7 +360,10 @@ func Id(value string) hatmill.Attrib {
}
// Ismap creates a "ismap" attribute
func Ismap() hatmill.Attrib {
func Ismap(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "ismap",
}
@ -380,7 +410,10 @@ func List(value string) hatmill.Attrib {
}
// Loop creates a "loop" attribute
func Loop() hatmill.Attrib {
func Loop(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "loop",
}
@ -443,14 +476,20 @@ func Minlength(value int) hatmill.Attrib {
}
// Multiple creates a "multiple" attribute
func Multiple() hatmill.Attrib {
func Multiple(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "multiple",
}
}
// Muted creates a "muted" attribute
func Muted() hatmill.Attrib {
func Muted(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "muted",
}
@ -465,14 +504,20 @@ func Name(value string) hatmill.Attrib {
}
// Novalidate creates a "novalidate" attribute
func Novalidate() hatmill.Attrib {
func Novalidate(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "novalidate",
}
}
// Open creates a "open" attribute
func Open() hatmill.Attrib {
func Open(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "open",
}
@ -527,7 +572,10 @@ func Preload(value string) hatmill.Attrib {
}
// Readonly creates a "readonly" attribute
func Readonly() hatmill.Attrib {
func Readonly(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "readonly",
}
@ -550,14 +598,20 @@ func Rel(value ...string) hatmill.Attrib {
}
// Required creates a "required" attribute
func Required() hatmill.Attrib {
func Required(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "required",
}
}
// Reversed creates a "reversed" attribute
func Reversed() hatmill.Attrib {
func Reversed(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "reversed",
}
@ -596,7 +650,10 @@ func Scope(value string) hatmill.Attrib {
}
// Selected creates a "selected" attribute
func Selected() hatmill.Attrib {
func Selected(b bool) hatmill.Attrib {
if !b {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "selected",
}

View File

@ -1,12 +1,13 @@
package attribute_test
import (
"gitlab.codemonkeysoftware.net/b/hatmill/attribute"
"testing"
"gitlab.codemonkeysoftware.net/b/hatmill/attribute"
)
func TestBool(t *testing.T) {
attrib := attribute.Disabled()
attrib := attribute.Disabled(true)
if attrib.Value != nil {
t.Fatalf("expected attribute value to be nil, but got %#v", attrib.Value)
}

View File

@ -44,11 +44,11 @@ func TestFloat(t *testing.T) {
{name: "zero", f: 0, s: "0"},
{name: "integral", f: 45, s: "45"},
{name: "positive fractional, small positive exponent", f: 12.55, s: "12.55"},
{name: "positive fractional, large positive exponent", f: 1.55E+12, s: "1.55E+12"},
{name: "positive fractional, large negative exponent", f: 1.55E-12, s: "1.55E-12"},
{name: "positive fractional, large positive exponent", f: 1.55e+12, s: "1.55E+12"},
{name: "positive fractional, large negative exponent", f: 1.55e-12, s: "1.55E-12"},
{name: "negative fractional, small positive exponent", f: -12.55, s: "-12.55"},
{name: "negative fractional, large positive exponent", f: -1.55E+12, s: "-1.55E+12"},
{name: "negative fractional, large negative exponent", f: -1.55E-12, s: "-1.55E-12"},
{name: "negative fractional, large positive exponent", f: -1.55e+12, s: "-1.55E+12"},
{name: "negative fractional, large negative exponent", f: -1.55e-12, s: "-1.55E-12"},
} {
t.Run(testcase.name, func(t *testing.T) {
expectEqualStrings(t, testcase.f.String(), testcase.s)

2
go.mod
View File

@ -1,3 +1,5 @@
module gitlab.codemonkeysoftware.net/b/hatmill
go 1.14
require github.com/leanovate/gopter v0.2.4

View File

@ -36,11 +36,18 @@ type Attrib struct {
Value fmt.Stringer
}
func (a Attrib) Empty() bool {
return a == Attrib{}
}
// WriteTo writes a to w as an HTML attribute in the form key="value", or
// simply key if value is empty. Special characters in value are replaced with
// HTML entities. It returns the number of bytes written and any
// error encountered.
func (a Attrib) WriteTo(w io.Writer) (n int64, err error) {
if a.Empty() {
return 0, nil
}
err = writeStringsTo(w, &n, a.Key)
if err != nil {
return
@ -73,6 +80,11 @@ func (e VoidElement) WriteTo(w io.Writer) (n int64, err error) {
}
for _, attrib := range e.Attribs {
if attrib.Empty() {
// attrib.WriteTo already does nothing in this case, but
// let's not clutter our tags with extra spaces.
continue
}
err = writeStringsTo(w, &n, " ")
if err != nil {
return

View File

@ -242,9 +242,9 @@ func Example() {
he.Body()(
he.Img(ha.Src("./photo.jpg"), ha.Contenteditable(true)),
hatmill.Text(userInput),
he.Div(ha.Disabled(), ha.CustomData("coolness", "awesome"))(),
he.Div(ha.Disabled(true), ha.CustomData("coolness", "awesome"))(),
he.Textarea(ha.Rows(25))(),
he.Meter(ha.Min(-1.3), ha.Max(5.5E12))(),
he.Meter(ha.Min(-1.3), ha.Max(5.5e12))(),
),
)
hatmill.WriteDocument(os.Stdout, document)

View File

@ -40,7 +40,10 @@ func simpleTemplate(paramType, toType string) AttribTemplate {
func boolTemplate(identifier, name string) string {
return fmt.Sprintf(
`func %s() hatmill.Attrib {
`func %s(showAttrib bool) hatmill.Attrib {
if !showAttrib {
return hatmill.Attrib{}
}
return hatmill.Attrib{
Key: "%s",
}