ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/aya/vendor/github.com/yosssi/gcss/selector.go
Revision: 1.1
Committed: Mon Sep 30 00:42:06 2024 UTC (6 weeks, 4 days ago) by yakumo_izuru
Branch: MAIN
CVS Tags: HEAD
Log Message:
Mirrored from https://git.chaotic.ninja/git/yakumo_izuru/aya

File Contents

# User Rev Content
1 yakumo_izuru 1.1 package gcss
2    
3     import (
4     "bytes"
5     "fmt"
6     "io"
7     "strings"
8     )
9    
10     // selector represents a selector of CSS.
11     type selector struct {
12     elementBase
13     name string
14     }
15    
16     // WriteTo writes the selector to the writer.
17     func (sel *selector) WriteTo(w io.Writer) (int64, error) {
18     return sel.writeTo(w, nil)
19     }
20    
21     // writeTo writes the selector to the writer.
22     func (sel *selector) writeTo(w io.Writer, params map[string]string) (int64, error) {
23     bf := new(bytes.Buffer)
24    
25     // Write the declarations.
26     if len(sel.decs) > 0 || sel.hasMixinDecs() {
27     bf.WriteString(sel.names())
28     bf.WriteString(openBrace)
29    
30     // Writing to the bytes.Buffer never returns an error.
31     sel.writeDecsTo(bf, params)
32    
33     bf.WriteString(closeBrace)
34     }
35    
36     // Write the child selectors.
37     for _, childSel := range sel.sels {
38     // Writing to the bytes.Buffer never returns an error.
39     childSel.writeTo(bf, params)
40     }
41    
42     // Write the mixin's selectors.
43     for _, mi := range sel.mixins {
44     sels, prms := mi.selsParams()
45    
46     for _, sl := range sels {
47     sl.parent = sel
48     // Writing to the bytes.Buffer never returns an error.
49     sl.writeTo(bf, prms)
50     }
51     }
52    
53     n, err := w.Write(bf.Bytes())
54    
55     return int64(n), err
56     }
57    
58     // names returns the selector names.
59     func (sel *selector) names() string {
60     bf := new(bytes.Buffer)
61    
62     switch parent := sel.parent.(type) {
63     case nil, *atRule:
64     for _, name := range strings.Split(sel.name, comma) {
65     if bf.Len() > 0 {
66     bf.WriteString(comma)
67     }
68    
69     bf.WriteString(strings.TrimSpace(name))
70     }
71     case *selector:
72     for _, parentS := range strings.Split(parent.names(), comma) {
73     for _, s := range strings.Split(sel.name, comma) {
74     if bf.Len() > 0 {
75     bf.WriteString(comma)
76     }
77    
78     s = strings.TrimSpace(s)
79    
80     if strings.Index(s, ampersand) != -1 {
81     bf.WriteString(strings.Replace(s, ampersand, parentS, -1))
82     } else {
83     bf.WriteString(parentS)
84     bf.WriteString(space)
85     bf.WriteString(s)
86     }
87     }
88     }
89     }
90    
91     return bf.String()
92     }
93    
94     // newSelector creates and returns a selector.
95     func newSelector(ln *line, parent element) (*selector, error) {
96     name := strings.TrimSpace(ln.s)
97    
98     if strings.HasSuffix(name, openBrace) {
99     return nil, fmt.Errorf("selector must not end with %q [line: %d]", openBrace, ln.no)
100     }
101    
102     if strings.HasSuffix(name, closeBrace) {
103     return nil, fmt.Errorf("selector must not end with %q [line: %d]", closeBrace, ln.no)
104     }
105    
106     return &selector{
107     elementBase: newElementBase(ln, parent),
108     name: name,
109     }, nil
110     }