~repos /gromer

#golang#htmx#ssr

git clone https://pyrossh.dev/repos/gromer.git

gromer is a framework and cli to build multipage web apps in golang using htmx and alpinejs.


dc8f948e pyros2097

5 years ago
improve attrs and selectors
Files changed (4) hide show
  1. attributes.go +21 -85
  2. html.go +5 -5
  3. node.go +0 -3
  4. selectors.go +27 -167
attributes.go CHANGED
@@ -4,123 +4,59 @@ import (
4
4
  "github.com/pyros2097/wapp/js"
5
5
  )
6
6
 
7
- type baseAttribute struct {
8
- UI
9
- }
10
-
11
- func (c baseAttribute) Kind() Kind {
12
- return Attribute
13
- }
14
-
15
- func (c baseAttribute) JSValue() js.Value {
16
- return nil
17
- }
18
-
19
- func (c baseAttribute) Mounted() bool {
20
- return false
21
- }
22
-
23
- func (c baseAttribute) name() string {
24
- return "css"
25
- }
26
-
27
- func (c baseAttribute) self() UI {
28
- return c
29
- }
30
-
31
- func (c baseAttribute) setSelf(UI) {
32
- }
33
-
34
- func (c baseAttribute) attributes() map[string]string {
35
- return nil
36
- }
37
-
38
- func (c baseAttribute) eventHandlers() map[string]js.EventHandler {
39
- return nil
40
- }
41
-
42
- func (c baseAttribute) parent() UI {
43
- return nil
44
- }
45
-
46
- func (c baseAttribute) setParent(UI) {
47
- }
48
-
49
- func (c baseAttribute) children() []UI {
50
- return nil
51
- }
52
-
53
- func (c baseAttribute) mount() error {
54
- panic("cant mount attributes")
55
- }
56
-
57
- func (c baseAttribute) dismount() {
58
- }
59
-
60
- func (c baseAttribute) update(UI) error {
61
- panic("cant update attributes")
62
- }
63
-
64
7
  type CssAttribute struct {
65
- baseAttribute
66
8
  classes string
67
9
  }
68
10
 
69
- func Css(d string) UI {
11
+ func Css(d string) CssAttribute {
70
12
  return CssAttribute{classes: d}
71
13
  }
72
14
 
73
15
  type OnClickAttribute struct {
74
- baseAttribute
75
16
  cb func()
76
17
  }
77
18
 
78
- func OnClick(cb func()) UI {
19
+ func OnClick(cb func()) OnClickAttribute {
79
20
  return OnClickAttribute{cb: cb}
80
21
  }
81
22
 
82
23
  type OnChangeAttribute struct {
83
- baseAttribute
84
24
  cb js.EventHandlerFunc
85
25
  }
86
26
 
87
- func OnChange(cb js.EventHandlerFunc) UI {
27
+ func OnChange(cb js.EventHandlerFunc) OnChangeAttribute {
88
28
  return OnChangeAttribute{cb: cb}
89
29
  }
90
30
 
91
31
  type OnInputAttribute struct {
92
- baseAttribute
93
32
  cb js.EventHandlerFunc
94
33
  }
95
34
 
96
- func OnInput(cb js.EventHandlerFunc) UI {
35
+ func OnInput(cb js.EventHandlerFunc) OnInputAttribute {
97
36
  return OnInputAttribute{cb: cb}
98
37
  }
99
38
 
100
- func mergeAttributes(parent *elem, uis ...UI) {
39
+ func mergeAttributes(parent *elem, uis ...interface{}) {
101
40
  elems := make([]UI, 0, len(uis))
102
41
  for _, v := range uis {
103
- if v.Kind() == Attribute {
104
- switch c := v.(type) {
42
+ switch c := v.(type) {
105
- case CssAttribute:
43
+ case CssAttribute:
106
- if vv, ok := parent.attrs["classes"]; ok {
44
+ if vv, ok := parent.attrs["classes"]; ok {
107
- parent.setAttr("class", vv+" "+c.classes)
45
+ parent.setAttr("class", vv+" "+c.classes)
108
- } else {
46
+ } else {
109
- parent.setAttr("class", c.classes)
47
+ parent.setAttr("class", c.classes)
110
- }
111
- case OnClickAttribute:
112
- parent.setEventHandler("click", func(e js.Event) {
113
- c.cb()
114
- })
115
- case OnChangeAttribute:
116
- parent.setEventHandler("change", c.cb)
117
- case OnInputAttribute:
118
- parent.setEventHandler("input", c.cb)
119
48
  }
49
+ case OnClickAttribute:
50
+ parent.setEventHandler("click", func(e js.Event) {
51
+ c.cb()
52
+ })
53
+ case OnChangeAttribute:
54
+ parent.setEventHandler("change", c.cb)
55
+ case OnInputAttribute:
56
+ parent.setEventHandler("input", c.cb)
120
- } else {
57
+ case UI:
121
- elems = append(elems, v)
58
+ elems = append(elems, c)
122
59
  }
123
-
124
60
  }
125
61
  parent.setBody(elems...)
126
62
  }
html.go CHANGED
@@ -48,16 +48,16 @@ func Script(str string) *elem {
48
48
  }
49
49
  }
50
50
 
51
- func Div(uis ...UI) *elem {
51
+ func Div(uis ...interface{}) *elem {
52
52
  e := &elem{tag: "div"}
53
53
  mergeAttributes(e, uis...)
54
54
  return e
55
55
  }
56
56
 
57
- func Row(uis ...UI) UI {
57
+ func Row(uis ...interface{}) UI {
58
- return Div(append([]UI{Css("flex flex-row justify-center align-items-center")}, uis...)...)
58
+ return Div(append([]interface{}{Css("flex flex-row justify-center align-items-center")}, uis...)...)
59
59
  }
60
60
 
61
- func Col(uis ...UI) UI {
61
+ func Col(uis ...interface{}) UI {
62
- return Div(append([]UI{Css("flex flex-col justify-center align-items-center")}, uis...)...)
62
+ return Div(append([]interface{}{Css("flex flex-col justify-center align-items-center")}, uis...)...)
63
63
  }
node.go CHANGED
@@ -75,9 +75,6 @@ const (
75
75
  // elements within a given list.
76
76
  Selector
77
77
 
78
- // Attribute represents css
79
- Attribute
80
-
81
78
  // RawHTML represents an HTML element obtained from a raw HTML code snippet.
82
79
  RawHTML
83
80
 
selectors.go CHANGED
@@ -1,49 +1,31 @@
1
1
  package app
2
2
 
3
3
  import (
4
- "net/url"
5
4
  "reflect"
6
5
  "sort"
7
-
8
- "github.com/pyros2097/wapp/errors"
9
- "github.com/pyros2097/wapp/js"
10
6
  )
11
7
 
12
- // RangeLoop represents a control structure that iterates within a slice, an
13
- // array or a map.
14
- type RangeLoop interface {
15
- UI
16
-
17
- // Slice sets the loop content by repeating the given function for the
18
- // number of elements in the source.
19
- //
20
- // It panics if the range source is not a slice or an array.
21
- Slice(f func(int) UI) RangeLoop
22
-
23
- // Map sets the loop content by repeating the given function for the number
24
- // of elements in the source. Elements are ordered by keys.
25
- //
26
- // It panics if the range source is not a map or if map keys are not strings.
27
- Map(f func(string) UI) RangeLoop
28
- }
29
-
30
8
  // Range returns a range loop that iterates within the given source. Source must
31
9
  // be a slice, an array or a map with strings as keys.
32
10
  func Range(src interface{}) RangeLoop {
33
- return rangeLoop{source: src}
11
+ return RangeLoop{source: src}
34
12
  }
35
13
 
14
+ // RangeLoop represents a control structure that iterates within a slice, an
15
+ // array or a map.
36
- type rangeLoop struct {
16
+ type RangeLoop struct {
37
17
  body []UI
38
18
  source interface{}
39
19
  }
40
20
 
21
+ // Slice sets the loop content by repeating the given function for the
22
+ // number of elements in the source.
23
+ //
24
+ // It panics if the range source is not a slice or an array.
41
- func (r rangeLoop) Slice(f func(int) UI) RangeLoop {
25
+ func (r RangeLoop) Slice(f func(int) UI) RangeLoop {
42
26
  src := reflect.ValueOf(r.source)
43
27
  if src.Kind() != reflect.Slice && src.Kind() != reflect.Array {
44
- panic(errors.New("range loop source is not a slice or array").
28
+ panic("range loop source is not a slice or array: " + src.Type().String())
45
- Tag("src-type", src.Type),
46
- )
47
29
  }
48
30
 
49
31
  body := make([]UI, 0, src.Len())
@@ -55,19 +37,18 @@ func (r rangeLoop) Slice(f func(int) UI) RangeLoop {
55
37
  return r
56
38
  }
57
39
 
40
+ // Map sets the loop content by repeating the given function for the number
41
+ // of elements in the source. Elements are ordered by keys.
42
+ //
43
+ // It panics if the range source is not a map or if map keys are not strings.
58
- func (r rangeLoop) Map(f func(string) UI) RangeLoop {
44
+ func (r RangeLoop) Map(f func(string) UI) RangeLoop {
59
45
  src := reflect.ValueOf(r.source)
60
46
  if src.Kind() != reflect.Map {
61
- panic(errors.New("range loop source is not a map").
47
+ panic("range loop source is not a map: " + src.Type().String())
62
- Tag("src-type", src.Type),
63
- )
64
48
  }
65
49
 
66
50
  if keyType := src.Type().Key(); keyType.Kind() != reflect.String {
67
- panic(errors.New("range loop source keys are not strings").
51
+ panic("range loop source keys are not strings: " + src.Type().String() + keyType.String())
68
- Tag("src-type", src.Type).
69
- Tag("key-type", keyType),
70
- )
71
52
  }
72
53
 
73
54
  body := make([]UI, 0, src.Len())
@@ -86,80 +67,6 @@ func (r rangeLoop) Map(f func(string) UI) RangeLoop {
86
67
  return r
87
68
  }
88
69
 
89
- func (r rangeLoop) Kind() Kind {
90
- return Selector
91
- }
92
-
93
- func (r rangeLoop) JSValue() js.Value {
94
- return nil
95
- }
96
-
97
- func (r rangeLoop) Mounted() bool {
98
- return false
99
- }
100
-
101
- func (r rangeLoop) name() string {
102
- return "range"
103
- }
104
-
105
- func (r rangeLoop) self() UI {
106
- return r
107
- }
108
-
109
- func (r rangeLoop) setSelf(UI) {
110
- }
111
-
112
- func (r rangeLoop) attributes() map[string]string {
113
- return nil
114
- }
115
-
116
- func (r rangeLoop) eventHandlers() map[string]js.EventHandler {
117
- return nil
118
- }
119
-
120
- func (r rangeLoop) parent() UI {
121
- return nil
122
- }
123
-
124
- func (r rangeLoop) setParent(UI) {
125
- }
126
-
127
- func (r rangeLoop) children() []UI {
128
- return r.body
129
- }
130
-
131
- func (r rangeLoop) mount() error {
132
- return errors.New("range loop is not mountable").
133
- Tag("name", r.name()).
134
- Tag("kind", r.Kind())
135
- }
136
-
137
- func (r rangeLoop) dismount() {
138
- }
139
-
140
- func (r rangeLoop) update(UI) error {
141
- return errors.New("range loop cannot be updated").
142
- Tag("name", r.name()).
143
- Tag("kind", r.Kind())
144
- }
145
-
146
- func (r rangeLoop) onNav(*url.URL) {
147
- }
148
-
149
- // Condition represents a control structure that displays nodes depending on a
150
- // given expression.
151
- type Condition interface {
152
- UI
153
-
154
- // ElseIf sets the condition with the given nodes if previous expressions
155
- // were not met and given expression is true.
156
- ElseIf(expr bool, elems ...UI) Condition
157
-
158
- // Else sets the condition with the given UI elements if previous
159
- // expressions were not met.
160
- Else(elems ...UI) Condition
161
- }
162
-
163
70
  // If returns a condition that filters the given elements according to the given
164
71
  // expression.
165
72
  func If(expr bool, elems ...UI) Condition {
@@ -167,18 +74,22 @@ func If(expr bool, elems ...UI) Condition {
167
74
  elems = nil
168
75
  }
169
76
 
170
- return condition{
77
+ return Condition{
171
78
  body: FilterUIElems(elems...),
172
79
  satisfied: expr,
173
80
  }
174
81
  }
175
82
 
83
+ // Condition represents a control structure that displays nodes depending on a
84
+ // given expression.
176
- type condition struct {
85
+ type Condition struct {
177
86
  body []UI
178
87
  satisfied bool
179
88
  }
180
89
 
90
+ // ElseIf sets the condition with the given nodes if previous expressions
91
+ // were not met and given expression is true.
181
- func (c condition) ElseIf(expr bool, elems ...UI) Condition {
92
+ func (c Condition) ElseIf(expr bool, elems ...UI) Condition {
182
93
  if c.satisfied {
183
94
  return c
184
95
  }
@@ -191,59 +102,8 @@ func (c condition) ElseIf(expr bool, elems ...UI) Condition {
191
102
  return c
192
103
  }
193
104
 
105
+ // Else sets the condition with the given UI elements if previous
106
+ // expressions were not met.
194
- func (c condition) Else(elems ...UI) Condition {
107
+ func (c Condition) Else(elems ...UI) Condition {
195
108
  return c.ElseIf(true, elems...)
196
109
  }
197
-
198
- func (c condition) Kind() Kind {
199
- return Selector
200
- }
201
-
202
- func (c condition) JSValue() js.Value {
203
- return nil
204
- }
205
-
206
- func (c condition) Mounted() bool {
207
- return false
208
- }
209
-
210
- func (c condition) name() string {
211
- return "if.else"
212
- }
213
-
214
- func (c condition) self() UI {
215
- return c
216
- }
217
-
218
- func (c condition) setSelf(UI) {
219
- }
220
-
221
- func (c condition) attributes() map[string]string {
222
- return nil
223
- }
224
-
225
- func (c condition) eventHandlers() map[string]js.EventHandler {
226
- return nil
227
- }
228
-
229
- func (c condition) parent() UI {
230
- return nil
231
- }
232
-
233
- func (c condition) setParent(UI) {
234
- }
235
-
236
- func (c condition) children() []UI {
237
- return c.body
238
- }
239
-
240
- func (c condition) mount() error {
241
- panic("can't mout condition")
242
- }
243
-
244
- func (c condition) dismount() {
245
- }
246
-
247
- func (c condition) update(UI) error {
248
- panic("condition cannot be updated")
249
- }