-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgax.go
107 lines (91 loc) · 2.98 KB
/
gax.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
Simple system for writing HTML as Go code. Better-performing replacement for
`html/template` and `text/template`; see benchmarks in readme.
Vaguely inspired by JS library https://github.com/mitranim/prax.
Features / benefits:
* No weird special language to learn.
* Use actual Go code.
* Use normal Go conditionals.
* Use normal Go loops.
* Use normal Go functions.
* Benefit from static typing.
* Benefit from Go code analysis.
* Benefit from Go performance.
* Tiny and dependency-free.
The API is bloated with "just in case" public exports, but 99% of what you want
is `E`, `F`, `Bui`, and `Bui.E`. See the `Bui` example below.
*/
package gax
/*
Shortcut for prepending HTML doctype. Use `Bui(Doctype)` to create a
document-level HTML builder, or `Str(Doctype)` to prepend this in `F`.
*/
const Doctype = `<!doctype html>`
/*
Short for "renderer". On children implementing this interface, the `Render`
method is called for side effects, instead of stringifying the child.
*/
type Ren interface{ Render(*Bui) }
/*
Indicates pre-escaped markup. Children of this type are written as-is without
additional HTML/XML escaping. For bytes, use `Bui`.
*/
type Str string
// Implement `Ren`. Appends itself without HTML/XML escaping.
func (self Str) Render(bui *Bui) { bui.NonEscString(string(self)) }
/*
Set of known HTML boolean attributes. Can be modified via `Bool.Add` and
`Bool.Del`. The specification postulates the concept, but where's the standard
list? Taken from non-authoritative sources. Reference:
https://www.w3.org/TR/html52/infrastructure.html#boolean-attribute
*/
var Bool = newStringSet(
`allowfullscreen`, `allowpaymentrequest`, `async`, `autofocus`, `autoplay`,
`checked`, `controls`, `default`, `disabled`, `formnovalidate`, `hidden`,
`ismap`, `itemscope`, `loop`, `multiple`, `muted`, `nomodule`, `novalidate`,
`open`, `playsinline`, `readonly`, `required`, `reversed`, `selected`,
`truespeed`,
)
/*
Set of known HTML void elements, also known as self-closing tags. Can be
modified via `Void.Add` and `Void.Del`. Reference:
https://www.w3.org/TR/html52/
https://www.w3.org/TR/html52/syntax.html#writing-html-documents-elements
*/
var Void = newStringSet(
`area`, `base`, `br`, `col`, `embed`, `hr`, `img`, `input`, `link`, `meta`,
`param`, `source`, `track`, `wbr`,
)
/*
Short for "vacate", "vacuum", "vacuous". Takes a "child" intended for `E` or
`F`. If the child is empty, returns `nil`, otherwise returns the child as-is.
Empty is defined as containing only nils. Just like `E` and `F`, this
recursively walks `[]any`.
*/
func Vac(val any) any {
inout := val
switch val := val.(type) {
case []any:
for _, val := range val {
if Vac(val) != nil {
return inout
}
}
return nil
default:
if !isNil(val) {
return inout
}
return nil
}
}
/*
Shortcut for `target="_blank" rel="noopener noreferrer"`, which must always be
used together, which is easy to forget.
*/
func LinkBlank() Attrs {
return Attrs{
Attr{`target`, `_blank`},
Attr{`rel`, `noopener noreferrer`},
}
}