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`.
|
- `hatmill.Attrib.Value` is now an `fmt.Stringer`.
|
||||||
- Attribute code generation mostly uses interfaces instead of being so ad-hoc.
|
- 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
|
### Removed
|
||||||
|
|
||||||
|
@ -20,11 +20,11 @@ func TestCoordsList(t *testing.T) {
|
|||||||
{name: "zero", f: 0, s: "0"},
|
{name: "zero", f: 0, s: "0"},
|
||||||
{name: "integral", f: 45, s: "45"},
|
{name: "integral", f: 45, s: "45"},
|
||||||
{name: "positive fractional, small positive exponent", f: 12.55, s: "12.55"},
|
{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 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 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, 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 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 negative exponent", f: -1.55e-12, s: "-1.55E-12"},
|
||||||
} {
|
} {
|
||||||
t.Run(testcase.name, func(t *testing.T) {
|
t.Run(testcase.name, func(t *testing.T) {
|
||||||
expectEqualStrings(t, attribute.CoordsList{testcase.f}.String(), testcase.s)
|
expectEqualStrings(t, attribute.CoordsList{testcase.f}.String(), testcase.s)
|
||||||
|
@ -38,7 +38,10 @@ func Alt(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Async creates a "async" attribute
|
// Async creates a "async" attribute
|
||||||
func Async() hatmill.Attrib {
|
func Async(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "async",
|
Key: "async",
|
||||||
}
|
}
|
||||||
@ -61,14 +64,20 @@ func Autocomplete(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Autofocus creates a "autofocus" attribute
|
// Autofocus creates a "autofocus" attribute
|
||||||
func Autofocus() hatmill.Attrib {
|
func Autofocus(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "autofocus",
|
Key: "autofocus",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Autoplay creates a "autoplay" attribute
|
// Autoplay creates a "autoplay" attribute
|
||||||
func Autoplay() hatmill.Attrib {
|
func Autoplay(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "autoplay",
|
Key: "autoplay",
|
||||||
}
|
}
|
||||||
@ -83,7 +92,10 @@ func Charset(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Checked creates a "checked" attribute
|
// Checked creates a "checked" attribute
|
||||||
func Checked() hatmill.Attrib {
|
func Checked(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "checked",
|
Key: "checked",
|
||||||
}
|
}
|
||||||
@ -146,7 +158,10 @@ func Contextmenu(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Controls creates a "controls" attribute
|
// Controls creates a "controls" attribute
|
||||||
func Controls() hatmill.Attrib {
|
func Controls(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "controls",
|
Key: "controls",
|
||||||
}
|
}
|
||||||
@ -177,14 +192,20 @@ func Decoding(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Default creates a "default" attribute
|
// Default creates a "default" attribute
|
||||||
func Default() hatmill.Attrib {
|
func Default(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "default",
|
Key: "default",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defer creates a "defer" attribute
|
// Defer creates a "defer" attribute
|
||||||
func Defer() hatmill.Attrib {
|
func Defer(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "defer",
|
Key: "defer",
|
||||||
}
|
}
|
||||||
@ -207,7 +228,10 @@ func Dirname(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Disabled creates a "disabled" attribute
|
// Disabled creates a "disabled" attribute
|
||||||
func Disabled() hatmill.Attrib {
|
func Disabled(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "disabled",
|
Key: "disabled",
|
||||||
}
|
}
|
||||||
@ -286,7 +310,10 @@ func Height(value int) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hidden creates a "hidden" attribute
|
// Hidden creates a "hidden" attribute
|
||||||
func Hidden() hatmill.Attrib {
|
func Hidden(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "hidden",
|
Key: "hidden",
|
||||||
}
|
}
|
||||||
@ -333,7 +360,10 @@ func Id(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ismap creates a "ismap" attribute
|
// Ismap creates a "ismap" attribute
|
||||||
func Ismap() hatmill.Attrib {
|
func Ismap(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "ismap",
|
Key: "ismap",
|
||||||
}
|
}
|
||||||
@ -380,7 +410,10 @@ func List(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Loop creates a "loop" attribute
|
// Loop creates a "loop" attribute
|
||||||
func Loop() hatmill.Attrib {
|
func Loop(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "loop",
|
Key: "loop",
|
||||||
}
|
}
|
||||||
@ -443,14 +476,20 @@ func Minlength(value int) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Multiple creates a "multiple" attribute
|
// Multiple creates a "multiple" attribute
|
||||||
func Multiple() hatmill.Attrib {
|
func Multiple(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "multiple",
|
Key: "multiple",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Muted creates a "muted" attribute
|
// Muted creates a "muted" attribute
|
||||||
func Muted() hatmill.Attrib {
|
func Muted(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "muted",
|
Key: "muted",
|
||||||
}
|
}
|
||||||
@ -465,14 +504,20 @@ func Name(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Novalidate creates a "novalidate" attribute
|
// Novalidate creates a "novalidate" attribute
|
||||||
func Novalidate() hatmill.Attrib {
|
func Novalidate(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "novalidate",
|
Key: "novalidate",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open creates a "open" attribute
|
// Open creates a "open" attribute
|
||||||
func Open() hatmill.Attrib {
|
func Open(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "open",
|
Key: "open",
|
||||||
}
|
}
|
||||||
@ -527,7 +572,10 @@ func Preload(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Readonly creates a "readonly" attribute
|
// Readonly creates a "readonly" attribute
|
||||||
func Readonly() hatmill.Attrib {
|
func Readonly(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "readonly",
|
Key: "readonly",
|
||||||
}
|
}
|
||||||
@ -550,14 +598,20 @@ func Rel(value ...string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Required creates a "required" attribute
|
// Required creates a "required" attribute
|
||||||
func Required() hatmill.Attrib {
|
func Required(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "required",
|
Key: "required",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reversed creates a "reversed" attribute
|
// Reversed creates a "reversed" attribute
|
||||||
func Reversed() hatmill.Attrib {
|
func Reversed(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "reversed",
|
Key: "reversed",
|
||||||
}
|
}
|
||||||
@ -596,7 +650,10 @@ func Scope(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Selected creates a "selected" attribute
|
// Selected creates a "selected" attribute
|
||||||
func Selected() hatmill.Attrib {
|
func Selected(b bool) hatmill.Attrib {
|
||||||
|
if !b {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "selected",
|
Key: "selected",
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package attribute_test
|
package attribute_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gitlab.codemonkeysoftware.net/b/hatmill/attribute"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"gitlab.codemonkeysoftware.net/b/hatmill/attribute"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBool(t *testing.T) {
|
func TestBool(t *testing.T) {
|
||||||
attrib := attribute.Disabled()
|
attrib := attribute.Disabled(true)
|
||||||
if attrib.Value != nil {
|
if attrib.Value != nil {
|
||||||
t.Fatalf("expected attribute value to be nil, but got %#v", attrib.Value)
|
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: "zero", f: 0, s: "0"},
|
||||||
{name: "integral", f: 45, s: "45"},
|
{name: "integral", f: 45, s: "45"},
|
||||||
{name: "positive fractional, small positive exponent", f: 12.55, s: "12.55"},
|
{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 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 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, 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 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 negative exponent", f: -1.55e-12, s: "-1.55E-12"},
|
||||||
} {
|
} {
|
||||||
t.Run(testcase.name, func(t *testing.T) {
|
t.Run(testcase.name, func(t *testing.T) {
|
||||||
expectEqualStrings(t, testcase.f.String(), testcase.s)
|
expectEqualStrings(t, testcase.f.String(), testcase.s)
|
||||||
|
2
go.mod
2
go.mod
@ -1,3 +1,5 @@
|
|||||||
module gitlab.codemonkeysoftware.net/b/hatmill
|
module gitlab.codemonkeysoftware.net/b/hatmill
|
||||||
|
|
||||||
|
go 1.14
|
||||||
|
|
||||||
require github.com/leanovate/gopter v0.2.4
|
require github.com/leanovate/gopter v0.2.4
|
||||||
|
12
hatmill.go
12
hatmill.go
@ -36,11 +36,18 @@ type Attrib struct {
|
|||||||
Value fmt.Stringer
|
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
|
// 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
|
// simply key if value is empty. Special characters in value are replaced with
|
||||||
// HTML entities. It returns the number of bytes written and any
|
// HTML entities. It returns the number of bytes written and any
|
||||||
// error encountered.
|
// error encountered.
|
||||||
func (a Attrib) WriteTo(w io.Writer) (n int64, err error) {
|
func (a Attrib) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
|
if a.Empty() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
err = writeStringsTo(w, &n, a.Key)
|
err = writeStringsTo(w, &n, a.Key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -73,6 +80,11 @@ func (e VoidElement) WriteTo(w io.Writer) (n int64, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, attrib := range e.Attribs {
|
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, " ")
|
err = writeStringsTo(w, &n, " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -242,9 +242,9 @@ func Example() {
|
|||||||
he.Body()(
|
he.Body()(
|
||||||
he.Img(ha.Src("./photo.jpg"), ha.Contenteditable(true)),
|
he.Img(ha.Src("./photo.jpg"), ha.Contenteditable(true)),
|
||||||
hatmill.Text(userInput),
|
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.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)
|
hatmill.WriteDocument(os.Stdout, document)
|
||||||
|
@ -40,7 +40,10 @@ func simpleTemplate(paramType, toType string) AttribTemplate {
|
|||||||
|
|
||||||
func boolTemplate(identifier, name string) string {
|
func boolTemplate(identifier, name string) string {
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
`func %s() hatmill.Attrib {
|
`func %s(showAttrib bool) hatmill.Attrib {
|
||||||
|
if !showAttrib {
|
||||||
|
return hatmill.Attrib{}
|
||||||
|
}
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "%s",
|
Key: "%s",
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user