theme v1
This commit is contained in:
@@ -3,6 +3,7 @@ package templates
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -72,6 +73,29 @@ func TestGenPreview(t *testing.T) {
|
||||
writePreview(t, outDir, "preview-box-"+theme+".html", box, theme, "../static")
|
||||
}
|
||||
|
||||
// 主题预览:与箱主页同一份数据,只是打开 sakura 主题(验证令牌覆盖与深色块)
|
||||
themeBox := publicBaseData()
|
||||
themeBox["VConsole"] = false
|
||||
themeBox["ThemeSlug"] = "sakura"
|
||||
themeBox["PageUser"].(map[string]interface{})["Background"] = bgURI
|
||||
themeBox["PageUser"].(map[string]interface{})["Usernamecolor"] = "#3a2b30"
|
||||
themeBox["PageUser"].(map[string]interface{})["Introcolor"] = "#6b545c"
|
||||
themeCSS, err := os.ReadFile(filepath.Join("..", "static", "css", "themes", "sakura.css"))
|
||||
if err != nil {
|
||||
t.Fatalf("read theme css: %v", err)
|
||||
}
|
||||
for _, theme := range []string{"light", "dark"} {
|
||||
page, err := renderToString(t, "question/list", themeBox)
|
||||
if err != nil {
|
||||
t.Fatalf("render themed list: %v", err)
|
||||
}
|
||||
// 预览页走 file://,把主题 css 内联进去(真实页面是一次带缓存的静态请求)。
|
||||
// 用正则匹配:预览数据里没有 StaticVersion,v 参数为空串,不能按固定串替换。
|
||||
link := regexp.MustCompile(`<link rel="stylesheet" href="/static/css/themes/sakura\.css\?v=[^"]*"/>`)
|
||||
page = link.ReplaceAllString(page, "<style>"+string(themeCSS)+"</style>")
|
||||
writePreview(t, outDir, "preview-theme-sakura-"+theme+".html", page, theme, "../static")
|
||||
}
|
||||
|
||||
// 探索页:核对令牌替换后的卡片/列表配色
|
||||
explore := voteBaseData()
|
||||
explore["LangCode"] = "zh-CN"
|
||||
@@ -102,6 +126,12 @@ func TestGenPreview(t *testing.T) {
|
||||
|
||||
// 设置页「内容防护」面板:核对是否与其它面板同样是白底卡片
|
||||
profile := profileBaseData()
|
||||
// 主题选择器(account 面板):用固定假数据,避免测试依赖 conf 的 [theme] 段
|
||||
profile["Themes"] = []map[string]interface{}{
|
||||
{"Slug": "default", "Swatch": ""},
|
||||
{"Slug": "sakura", "Swatch": "linear-gradient(135deg, #fff6f8 0 55%, #e5678f 55% 100%)"},
|
||||
}
|
||||
profile["CurrentTheme"] = "sakura"
|
||||
profile["ActiveProfileTab"] = "security"
|
||||
profile["FeatureQuestion"] = nil
|
||||
profile["FeatureChat"] = nil
|
||||
@@ -113,6 +143,22 @@ func TestGenPreview(t *testing.T) {
|
||||
}
|
||||
writePreview(t, outDir, "preview-profile-"+theme+".html", page, theme, "../static")
|
||||
}
|
||||
|
||||
// 设置页「账号」面板:主题选择器的实际排版(卡片在面板末尾)
|
||||
profileAccount := profileBaseData()
|
||||
profileAccount["Themes"] = profile["Themes"]
|
||||
profileAccount["CurrentTheme"] = "sakura"
|
||||
profileAccount["ActiveProfileTab"] = "account"
|
||||
profileAccount["FeatureQuestion"] = nil
|
||||
profileAccount["FeatureChat"] = nil
|
||||
profileAccount["FeatureVote"] = nil
|
||||
for _, theme := range []string{"light"} {
|
||||
page, err := renderToString(t, "user/profile", profileAccount)
|
||||
if err != nil {
|
||||
t.Fatalf("render account profile: %v", err)
|
||||
}
|
||||
writePreview(t, outDir, "preview-profile-account-"+theme+".html", page, theme, "../static")
|
||||
}
|
||||
}
|
||||
|
||||
// writePreview 把 CDN 换成可直连的镜像、钉死主题,仅用于本地预览。
|
||||
@@ -120,7 +166,16 @@ func writePreview(t *testing.T, dir, name, html, theme, staticPrefix string) {
|
||||
t.Helper()
|
||||
html = strings.ReplaceAll(html, "https://cdnjs.snrat.com/", "https://cdnjs.cloudflare.com/")
|
||||
if theme == "dark" {
|
||||
html = strings.Replace(html, `<html lang="zh-CN">`, `<html lang="zh-CN" data-theme="dark">`, 1)
|
||||
// <html> 上可能还有 data-theme-style,只在这个开标签内判断/插入;
|
||||
// 不能全文搜索 —— 内联的主题 css 里有 html[data-theme="dark"] 选择器
|
||||
if i := strings.Index(html, "<html"); i >= 0 {
|
||||
if j := strings.Index(html[i:], ">"); j > 0 {
|
||||
tag := html[i : i+j]
|
||||
if !strings.Contains(tag, "data-theme=") {
|
||||
html = html[:i+j] + ` data-theme="dark"` + html[i+j:]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
html = strings.ReplaceAll(html, `href="/favicon.ico"`, `href="`+staticPrefix+`/favicon.ico"`)
|
||||
html = strings.Replace(html, `<title>`, `<title>预览 `+time.Now().Format("15:04")+` · `, 1)
|
||||
|
||||
Reference in New Issue
Block a user