gui/pkg/display/hlcrf.go
Snider 2c5385e1cf
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
Harden GUI storage and manifest paths
2026-04-15 20:43:48 +01:00

77 lines
2.4 KiB
Go

package display
import (
"os"
"path/filepath"
"regexp"
"strings"
)
var hlcrfSlotPattern = regexp.MustCompile(`\{\{\s*slot\s+"([^"]+)"\s*\}\}`)
func (s *Service) buildHLCRFComponents(pageURL string) (string, error) {
loaded, err := s.loadManifestForOrigin(pageURL)
if err != nil || loaded == nil {
if err != nil && strings.Contains(err.Error(), "view manifest not found") {
return "", nil
}
return "", err
}
var scripts []string
for _, component := range loaded.Manifest.HLCRF {
templateBody := strings.TrimSpace(component.Template)
if templateBody == "" && strings.TrimSpace(component.Name) != "" {
resolvedPath, pathErr := safeManifestRelativePath(loaded.BaseDir, component.Name, "hlcrf component path")
if pathErr != nil {
return "", pathErr
}
body, readErr := os.ReadFile(resolvedPath)
if readErr == nil {
templateBody = string(body)
}
}
if templateBody == "" {
continue
}
tag := strings.TrimSpace(component.Tag)
if tag == "" {
tag = defaultHLCRFTag(component.Name)
}
scripts = append(scripts, renderHLCRFComponent(tag, templateBody))
}
return strings.Join(scripts, "\n"), nil
}
func renderHLCRFComponent(tag, templateBody string) string {
templateBody = compileHLCRFTemplate(templateBody)
return `(function(){if(customElements.get(` + quoteJS(tag) + `)){return;}const tpl=document.createElement('template');tpl.innerHTML=` +
quoteJS(templateBody) +
`;class CoreHLCRFElement extends HTMLElement{connectedCallback(){if(this.shadowRoot){return;}const root=this.attachShadow({mode:'open'});root.appendChild(tpl.content.cloneNode(true));}}customElements.define(` +
quoteJS(tag) +
`,CoreHLCRFElement);})();`
}
func compileHLCRFTemplate(templateBody string) string {
return hlcrfSlotPattern.ReplaceAllStringFunc(templateBody, func(source string) string {
match := hlcrfSlotPattern.FindStringSubmatch(source)
if len(match) < 2 {
return source
}
slotName := strings.TrimSpace(match[1])
if slotName == "" || strings.EqualFold(slotName, "default") {
return "<slot></slot>"
}
return `<slot name="` + slotName + `"></slot>`
})
}
func defaultHLCRFTag(name string) string {
name = strings.TrimSpace(strings.ToLower(name))
name = strings.TrimSuffix(name, filepath.Ext(name))
name = strings.ReplaceAll(name, "_", "-")
name = strings.ReplaceAll(name, " ", "-")
if !strings.Contains(name, "-") {
name = "core-" + name
}
return name
}