1
0
html/query.go

130 lines
2.1 KiB
Go
Raw Normal View History

2025-09-11 20:50:00 +02:00
package html
type nameQuery struct {
value string
}
type attributesQuery struct {
value Attributes
}
type attributeQuery struct {
name string
2025-10-05 20:06:39 +02:00
value any
2025-09-11 20:50:00 +02:00
found bool
}
type childrenQuery struct {
value []any
}
type validator struct {
err error
}
type renderGuidesQuery struct {
value []renderGuide
}
func groupChildren(c []any) ([]Attributes, []any, []renderGuide) {
var (
a []Attributes
cc []any
rg []renderGuide
)
for _, ci := range c {
if ai, ok := ci.(Attributes); ok {
a = append(a, ai)
continue
}
if rgi, ok := ci.(renderGuide); ok {
rg = append(rg, rgi)
continue
}
cc = append(cc, ci)
}
return a, cc, rg
}
func mergeAttributes(c []any) Attributes {
a, _, _ := groupChildren(c)
if len(a) == 0 {
return nil
}
to := make(Attributes)
for _, ai := range a {
for name, value := range ai {
to[name] = value
}
}
return to
}
2025-10-05 20:06:39 +02:00
func findAttribute(c []any, name string) (any, bool) {
2025-09-11 20:50:00 +02:00
a, _, _ := groupChildren(c)
for i := len(a) - 1; i >= 0; i-- {
value, ok := a[i][name]
if ok {
return value, true
}
}
2025-10-05 20:06:39 +02:00
return nil, false
2025-09-11 20:50:00 +02:00
}
func handleQuery(name string, children []any) bool {
if len(children) == 0 {
return false
}
last := len(children) - 1
lastChild := children[last]
if q, ok := lastChild.(*nameQuery); ok {
q.value = name
return true
}
if q, ok := lastChild.(*attributesQuery); ok {
q.value = mergeAttributes(children[:last])
return true
}
if q, ok := lastChild.(*attributeQuery); ok {
q.value, q.found = findAttribute(children[:last], q.name)
return true
}
if q, ok := lastChild.(*childrenQuery); ok {
_, q.value, _ = groupChildren(children[:last])
return true
}
if q, ok := lastChild.(*renderGuidesQuery); ok {
_, _, q.value = groupChildren(children[:last])
return true
}
if v, ok := lastChild.(*validator); ok {
v.err = validate(name, children[:last])
return true
}
if r, ok := lastChild.(*renderer); ok {
if err := validate(name, children[:last]); err != nil {
r.err = err
return true
}
r.render(name, children[:last])
2025-09-11 20:50:00 +02:00
return true
}
return false
}