1
0
html/validate.go
2025-10-06 23:49:11 +02:00

78 lines
1.3 KiB
Go

package html
import (
"errors"
"fmt"
"regexp"
"strings"
)
var symbolExp = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9-_.]*$`)
func validateSymbol(s string) error {
if !symbolExp.MatchString(s) {
return errors.New("invalid symbol")
}
return nil
}
func validateTagName(name string) error {
if strings.HasPrefix(name, "!") {
return nil
}
return validateSymbol(name)
}
func validateAttributeName(name string) error {
return validateSymbol(name)
}
func validate(name string, children []any) error {
if err := validateTagName(name); err != nil {
return err
}
isDeclaration := strings.HasPrefix(name, "!")
a, c, rgs := groupChildren(children)
rg := mergeRenderingGuides(rgs)
if rg.void && len(c) > 0 {
return fmt.Errorf("tag %s is void but it has children", name)
}
if isDeclaration && len(c) > 0 {
return fmt.Errorf("declarations cannot have children (%s)", name)
}
for _, ai := range a {
for _, name := range ai.names {
if isDeclaration {
continue
}
if err := validateAttributeName(name); err != nil {
return fmt.Errorf("tag %s: %w", name, err)
}
}
}
for _, ci := range c {
if tag, ok := ci.(Tag); ok {
if rg.script {
return fmt.Errorf("tag %s does not allow child elements", name)
}
var v validator
tag(&v)
if v.err != nil {
return v.err
}
continue
}
}
return nil
}