Skip to content

Commit

Permalink
css: extract wrapping logic to a helper function
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Aug 11, 2023
1 parent a05a2f9 commit c73f0f8
Showing 1 changed file with 64 additions and 55 deletions.
119 changes: 64 additions & 55 deletions internal/linker/linker.go
Original file line number Diff line number Diff line change
Expand Up @@ -5909,61 +5909,7 @@ func (c *linkerContext) generateChunkCSS(chunkIndex int, chunkWaitGroup *sync.Wa
rules = []css_ast.Rule{{Data: &css_ast.RAtLayer{Names: layers}}}
}

for i := len(entry.conditions) - 1; i >= 0; i-- {
conditions := entry.conditions[i]

// Generate "@layer" wrappers. Note that empty "@layer" rules still have
// a side effect (they set the layer order) so they cannot be removed.
for _, t := range conditions.Layers {
if len(rules) == 0 {
if t.Children == nil {
// Omit an empty "@layer {}" entirely
continue
} else {
// Generate "@layer foo;" instead of "@layer foo {}"
rules = nil
}
}
var prelude []css_ast.Token
if t.Children != nil {
prelude = *t.Children
}
prelude, ast.ImportRecords = css_ast.CloneTokensWithImportRecords(prelude, entry.conditionImportRecords, nil, ast.ImportRecords)
rules = []css_ast.Rule{{Data: &css_ast.RKnownAt{
AtToken: "layer",
Prelude: prelude,
Rules: rules,
}}}
}

// Generate "@supports" wrappers. This is not done if the rule block is
// empty because empty "@supports" rules have no effect.
if len(rules) > 0 {
for _, t := range conditions.Supports {
t.Kind = css_lexer.TOpenParen
t.Text = "("
var prelude []css_ast.Token
prelude, ast.ImportRecords = css_ast.CloneTokensWithImportRecords([]css_ast.Token{t}, entry.conditionImportRecords, nil, ast.ImportRecords)
rules = []css_ast.Rule{{Data: &css_ast.RKnownAt{
AtToken: "supports",
Prelude: prelude,
Rules: rules,
}}}
}
}

// Generate "@media" wrappers. This is not done if the rule block is
// empty because empty "@media" rules have no effect.
if len(rules) > 0 && len(conditions.Media) > 0 {
var prelude []css_ast.Token
prelude, ast.ImportRecords = css_ast.CloneTokensWithImportRecords(conditions.Media, entry.conditionImportRecords, nil, ast.ImportRecords)
rules = []css_ast.Rule{{Data: &css_ast.RKnownAt{
AtToken: "media",
Prelude: prelude,
Rules: rules,
}}}
}
}
rules, ast.ImportRecords = wrapRulesWithConditions(rules, ast.ImportRecords, entry.conditions, entry.conditionImportRecords)

// Remove top-level duplicate rules across files
if c.options.MinifySyntax {
Expand Down Expand Up @@ -6253,6 +6199,69 @@ func (c *linkerContext) generateChunkCSS(chunkIndex int, chunkWaitGroup *sync.Wa
chunkWaitGroup.Done()
}

func wrapRulesWithConditions(
rules []css_ast.Rule, importRecords []ast.ImportRecord,
conditions []css_ast.ImportConditions, conditionImportRecords []ast.ImportRecord,
) ([]css_ast.Rule, []ast.ImportRecord) {
for i := len(conditions) - 1; i >= 0; i-- {
item := conditions[i]

// Generate "@layer" wrappers. Note that empty "@layer" rules still have
// a side effect (they set the layer order) so they cannot be removed.
for _, t := range item.Layers {
if len(rules) == 0 {
if t.Children == nil {
// Omit an empty "@layer {}" entirely
continue
} else {
// Generate "@layer foo;" instead of "@layer foo {}"
rules = nil
}
}
var prelude []css_ast.Token
if t.Children != nil {
prelude = *t.Children
}
prelude, importRecords = css_ast.CloneTokensWithImportRecords(prelude, conditionImportRecords, nil, importRecords)
rules = []css_ast.Rule{{Data: &css_ast.RKnownAt{
AtToken: "layer",
Prelude: prelude,
Rules: rules,
}}}
}

// Generate "@supports" wrappers. This is not done if the rule block is
// empty because empty "@supports" rules have no effect.
if len(rules) > 0 {
for _, t := range item.Supports {
t.Kind = css_lexer.TOpenParen
t.Text = "("
var prelude []css_ast.Token
prelude, importRecords = css_ast.CloneTokensWithImportRecords([]css_ast.Token{t}, conditionImportRecords, nil, importRecords)
rules = []css_ast.Rule{{Data: &css_ast.RKnownAt{
AtToken: "supports",
Prelude: prelude,
Rules: rules,
}}}
}
}

// Generate "@media" wrappers. This is not done if the rule block is
// empty because empty "@media" rules have no effect.
if len(rules) > 0 && len(item.Media) > 0 {
var prelude []css_ast.Token
prelude, importRecords = css_ast.CloneTokensWithImportRecords(item.Media, conditionImportRecords, nil, importRecords)
rules = []css_ast.Rule{{Data: &css_ast.RKnownAt{
AtToken: "media",
Prelude: prelude,
Rules: rules,
}}}
}
}

return rules, importRecords
}

type legalCommentEntry struct {
sourceIndex uint32
comments []string
Expand Down

0 comments on commit c73f0f8

Please sign in to comment.