/
uzer_007
/
Rixea
Обзор
Документация
Войти
/
uzer_007
/
Rixea
Код
Запросы
0
Задачи
Вики
Пакеты
5
Релизы
2
CI/CD
Аналитика
Безопасность
master
modules/markup/internal/renderinternal.go
83 строки
2 KB
uzer_007
feat: первая версия Rixea
02 авг 2026, 22:16
02 авг 2026, 22:16
d4f7504
Код
Авторство
О чём код?
// Copyright 2026 Uzer_007. All rights reserved. // SPDX-License-Identifier: MIT package internal import ( "crypto/rand" "html/template" "io" "regexp" "strings" "sync" "gitverse.ru/uzer_007/Rixea/modules/htmlutil" base64 "gitverse.ru/uzer_007/gobase64" "golang.org/x/net/html" ) var reAttrClass = sync.OnceValue(func() *regexp.Regexp { // TODO: it isn't a problem at the moment because our HTML contents are always well constructed return regexp.MustCompile(`(<[^>]+)\s+class="([^"]+)"([^>]*>)`) }) // RenderInternal also works without initialization // If no initialization (no secureID), it will not protect any attributes and return the original name&value type RenderInternal struct { secureID string secureIDPrefix string } func (r *RenderInternal) Init(output io.Writer, extraHeadHTML template.HTML) io.WriteCloser { buf := make([]byte, 12) _, err := rand.Read(buf) if err != nil { panic("unable to generate secure id") } return r.init(base64.URLEncoding.EncodeToString(buf), output, extraHeadHTML) } func (r *RenderInternal) init(secID string, output io.Writer, extraHeadHTML template.HTML) io.WriteCloser { r.secureID = secID r.secureIDPrefix = r.secureID + ":" return &finalProcessor{renderInternal: r, output: output, extraHeadHTML: extraHeadHTML} } func (r *RenderInternal) RecoverProtectedValue(v string) (string, bool) { if !strings.HasPrefix(v, r.secureIDPrefix) { return "", false } return v[len(r.secureIDPrefix):], true } func (r *RenderInternal) SafeAttr(name string) string { if r.secureID == "" { return name } return "data-attr-" + name } func (r *RenderInternal) SafeValue(val string) string { if r.secureID == "" { return val } return r.secureID + ":" + val } func (r *RenderInternal) NodeSafeAttr(attr, val string) html.Attribute { return html.Attribute{Key: r.SafeAttr(attr), Val: r.SafeValue(val)} } func (r *RenderInternal) ProtectSafeAttrs(content template.HTML) template.HTML { if r.secureID == "" { return content } return template.HTML(reAttrClass().ReplaceAllString(string(content), `$1 data-attr-class="`+r.secureIDPrefix+`$2"$3`)) } func (r *RenderInternal) FormatWithSafeAttrs(w io.Writer, fmt template.HTML, a ...any) error { htmlStr := r.ProtectSafeAttrs(htmlutil.HTMLFormat(fmt, a...)) _, err := io.WriteString(w, string(htmlStr)) return err }