Make boolean attributes more useable
This commit is contained in:
parent
a671ad57e2
commit
4cb7457606
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
2
go.mod
@ -1,3 +1,5 @@
|
||||
module gitlab.codemonkeysoftware.net/b/hatmill
|
||||
|
||||
go 1.14
|
||||
|
||||
require github.com/leanovate/gopter v0.2.4
|
||||
|
12
hatmill.go
12
hatmill.go
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user