Skip to content

Commit

Permalink
Merge branch 'scoped-styles'
Browse files Browse the repository at this point in the history
  • Loading branch information
movsb committed Nov 21, 2024
2 parents 3379034 + af8afa7 commit ec36a49
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 3 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ require (
github.com/rivo/uniseg v0.2.0 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/skeema/knownhosts v1.2.2 // indirect
github.com/tdewolff/parse/v2 v2.7.19 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
golang.org/x/crypto v0.22.0 // indirect
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tdewolff/parse/v2 v2.7.19 h1:7Ljh26yj+gdLFEq/7q9LT4SYyKtwQX4ocNrj45UCePg=
github.com/tdewolff/parse/v2 v2.7.19/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA=
github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
Expand Down
7 changes: 7 additions & 0 deletions service/modules/renderers/all_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
gold_utils "github.com/movsb/taoblog/service/modules/renderers/goldutils"
"github.com/movsb/taoblog/service/modules/renderers/imaging"
"github.com/movsb/taoblog/service/modules/renderers/media_size"
"github.com/movsb/taoblog/service/modules/renderers/scoped_css"
"github.com/yuin/goldmark/extension"
)

Expand Down Expand Up @@ -167,6 +168,12 @@ func TestMarkdownAll(t *testing.T) {
Markdown: `a #b c #桃子`,
Html: `<p>a <span class="hashtag"><a href="http://localhost/tags/b">#b</a></span> c <span class="hashtag"><a href="http://localhost/tags/%E6%A1%83%E5%AD%90">#桃子</a></span></p>`,
},
{
ID: 12.0,
Options: []renderers.Option2{scoped_css.New(`article#123`)},
Markdown: `<style>table { min-width: 100px; }</style>`,
Html: `<style>article#123 table{min-width:100px;}</style>`,
},
}
for _, tc := range cases {
if tc.ID == 10.0 {
Expand Down
27 changes: 27 additions & 0 deletions service/modules/renderers/scoped_css/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Scoped CSS

单篇文章的样式文件应该只应用到文章本身,而不应该影响到其它文章。
编写样式的时候,不应该手动限制样式为当前文章标签,这样会有较大的心智负担。

比较,文章里面可以这样写:

```html
<style>
table {
min-width: 100px;
}
</style>
```

当把多篇文章显示在同一个页面下时,会影响到所有表格,这种行为是不预期的。
所以应该限定一下范围(scope),比如改写成如下形式:

```html
<style>
article#123 table {
min-width: 100px;
}
</style>
```

把其范围限制到只对文章(编号为 123)有效。
31 changes: 31 additions & 0 deletions service/modules/renderers/scoped_css/all_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package scoped_css

import "testing"

func TestAddScope(t *testing.T) {
testCases := []struct {
scope string
before string
after string
}{
{
scope: `article`,
before: `
table, tr td {
min-width: 100px;
}
`,
after: `article table,article tr td{min-width:100px;}`,
},
}
for i, tc := range testCases {
output, err := addScope(tc.before, tc.scope)
if err != nil {
t.Errorf(`Error %d: %v`, i, err)
continue
}
if output != tc.after {
t.Errorf("Not Equal: %d:\n%s\n%s", i, output, tc.after)
}
}
}
80 changes: 80 additions & 0 deletions service/modules/renderers/scoped_css/scoped_css.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package scoped_css

import (
"io"

"github.com/PuerkitoBio/goquery"
"github.com/tdewolff/parse/v2"
"github.com/tdewolff/parse/v2/css"
"golang.org/x/net/html"
)

func New(scope string) *ScopedCSS {
return &ScopedCSS{
scope: scope,
}
}

type ScopedCSS struct {
scope string
}

func (p *ScopedCSS) TransformHtml(doc *goquery.Document) error {
var err error
doc.Find(`style`).Each(func(i int, s *goquery.Selection) {
if er := p.addScope(s); er != nil {
err = er
}
})
return err
}

func (p *ScopedCSS) addScope(s *goquery.Selection) error {
if first := s.Nodes[0].FirstChild; first != nil && first.Type == html.TextNode {
raw := first.Data
scoped, err := addScope(raw, p.scope)
if err != nil {
return err
}
first.Data = scoped
}
return nil
}

// 可以参考:https://github.com/tdewolff/parse/blob/master/css/parse_test.go
func addScope(raw string, scope string) (string, error) {
p := css.NewParser(parse.NewInputString(raw), false)
output := ""
for {
grammar, _, data := p.Next()
data = parse.Copy(data)
// log.Println(grammar, string(data), p.Values())
if grammar == css.ErrorGrammar {
if err := p.Err(); err != io.EOF {
return ``, err
}
break
}
if grammar == css.AtRuleGrammar || grammar == css.BeginAtRuleGrammar || grammar == css.QualifiedRuleGrammar || grammar == css.BeginRulesetGrammar || grammar == css.DeclarationGrammar || grammar == css.CustomPropertyGrammar {
if grammar == css.DeclarationGrammar || grammar == css.CustomPropertyGrammar {
data = append(data, ":"...)
}
if grammar == css.QualifiedRuleGrammar || grammar == css.BeginRulesetGrammar {
data = append(data, scope...)
data = append(data, ' ')
}
for _, val := range p.Values() {
data = append(data, val.Data...)
}
if grammar == css.BeginAtRuleGrammar || grammar == css.BeginRulesetGrammar {
data = append(data, "{"...)
} else if grammar == css.AtRuleGrammar || grammar == css.DeclarationGrammar || grammar == css.CustomPropertyGrammar {
data = append(data, ";"...)
} else if grammar == css.QualifiedRuleGrammar {
data = append(data, ","...)
}
}
output += string(data)
}
return output, nil
}
2 changes: 2 additions & 0 deletions service/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/movsb/taoblog/service/modules/renderers/media_size"
"github.com/movsb/taoblog/service/modules/renderers/media_tags"
"github.com/movsb/taoblog/service/modules/renderers/rooted_path"
"github.com/movsb/taoblog/service/modules/renderers/scoped_css"
task_list "github.com/movsb/taoblog/service/modules/renderers/tasklist"
"github.com/movsb/taorm"
"github.com/yuin/goldmark/extension"
Expand Down Expand Up @@ -268,6 +269,7 @@ func (s *Service) renderMarkdown(secure bool, postId, commentId int64, sourceTyp
)
}
options = append(options, media_tags.New(s.OpenAsset(postId), mediaTagOptions...))
options = append(options, scoped_css.New(fmt.Sprintf(`article.post-%d .entry .content`, postId)))
}
if !secure {
options = append(options,
Expand Down
2 changes: 1 addition & 1 deletion theme/blog/templates/_tweet.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{{ define "_tweet" }}
{{ $p := $.Partial }}
<article class="post {{ $p.OriginClass }}" id="{{$p.ID}}">
<article class="post post-{{$p.ID}} {{ $p.OriginClass }}" id="{{$p.ID}}">
<script>
TaoBlog.posts["{{$p.ID}}"] = {{ $.Strip $p }};
</script>
Expand Down
2 changes: 1 addition & 1 deletion theme/blog/templates/post.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

{{- $dot:=. -}}
{{- render "header" . -}}
<article class="post">
<article class="post post-{{.Post.Post.ID}}" id="{{.Post.Post.Id}}">
{{ with .Post.Post }}
<h1 class="title">{{.StatusString}}{{ .Title }}</h1>
<div class="entry">
Expand Down
2 changes: 1 addition & 1 deletion theme/blog/templates/tweet.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
TaoBlog.posts["{{.Post.Post.Id}}"] = {{ $.Strip .Post.Post }};
</script>
<div class="tweet">
<article class="post {{.Post.Post.OriginClass}}">
<article class="post post-{{.Post.Post.Id}} {{.Post.Post.OriginClass}}" id="{{.Post.Post.Id}}">
<div class="entry">
<div class="content">
{{ .Post.Post.Content }}
Expand Down

0 comments on commit ec36a49

Please sign in to comment.