github.com/evanw/esbuild@v0.21.4/internal/css_parser/css_decls_box_shadow.go (about)

     1  package css_parser
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/evanw/esbuild/internal/css_ast"
     7  	"github.com/evanw/esbuild/internal/css_lexer"
     8  )
     9  
    10  func (p *parser) lowerAndMangleBoxShadow(tokens []css_ast.Token, wouldClipColor *bool) []css_ast.Token {
    11  	insetCount := 0
    12  	colorCount := 0
    13  	numbersBegin := 0
    14  	numbersCount := 0
    15  	numbersDone := false
    16  	foundUnexpectedToken := false
    17  
    18  	for i, t := range tokens {
    19  		if t.Kind == css_lexer.TNumber || t.Kind == css_lexer.TDimension {
    20  			if numbersDone {
    21  				// Track if we found a non-number in between two numbers
    22  				foundUnexpectedToken = true
    23  			}
    24  			if p.options.minifySyntax && t.TurnLengthIntoNumberIfZero() {
    25  				// "0px" => "0"
    26  				tokens[i] = t
    27  			}
    28  			if numbersCount == 0 {
    29  				// Track the index of the first number
    30  				numbersBegin = i
    31  			}
    32  			numbersCount++
    33  		} else {
    34  			if numbersCount != 0 {
    35  				// Track when we find a non-number after a number
    36  				numbersDone = true
    37  			}
    38  
    39  			if looksLikeColor(t) {
    40  				colorCount++
    41  				tokens[i] = p.lowerAndMinifyColor(t, wouldClipColor)
    42  			} else if t.Kind == css_lexer.TIdent && strings.EqualFold(t.Text, "inset") {
    43  				insetCount++
    44  			} else {
    45  				// Track if we found a token other than a number, a color, or "inset"
    46  				foundUnexpectedToken = true
    47  			}
    48  		}
    49  	}
    50  
    51  	// If everything looks like a valid rule, trim trailing zeros off the numbers.
    52  	// There are three valid configurations of numbers:
    53  	//
    54  	//   offset-x | offset-y
    55  	//   offset-x | offset-y | blur-radius
    56  	//   offset-x | offset-y | blur-radius | spread-radius
    57  	//
    58  	// If omitted, blur-radius and spread-radius are implied to be zero.
    59  	if p.options.minifySyntax && insetCount <= 1 && colorCount <= 1 && numbersCount > 2 && numbersCount <= 4 && !foundUnexpectedToken {
    60  		numbersEnd := numbersBegin + numbersCount
    61  		for numbersCount > 2 && tokens[numbersBegin+numbersCount-1].IsZero() {
    62  			numbersCount--
    63  		}
    64  		tokens = append(tokens[:numbersBegin+numbersCount], tokens[numbersEnd:]...)
    65  	}
    66  
    67  	// Set the whitespace flags
    68  	for i := range tokens {
    69  		var whitespace css_ast.WhitespaceFlags
    70  		if i > 0 || !p.options.minifyWhitespace {
    71  			whitespace |= css_ast.WhitespaceBefore
    72  		}
    73  		if i+1 < len(tokens) {
    74  			whitespace |= css_ast.WhitespaceAfter
    75  		}
    76  		tokens[i].Whitespace = whitespace
    77  	}
    78  	return tokens
    79  }
    80  
    81  func (p *parser) lowerAndMangleBoxShadows(tokens []css_ast.Token, wouldClipColor *bool) []css_ast.Token {
    82  	n := len(tokens)
    83  	end := 0
    84  	i := 0
    85  
    86  	for i < n {
    87  		// Find the comma or the end of the token list
    88  		comma := i
    89  		for comma < n && tokens[comma].Kind != css_lexer.TComma {
    90  			comma++
    91  		}
    92  
    93  		// Mangle this individual shadow
    94  		end += copy(tokens[end:], p.lowerAndMangleBoxShadow(tokens[i:comma], wouldClipColor))
    95  
    96  		// Skip over the comma
    97  		if comma < n {
    98  			tokens[end] = tokens[comma]
    99  			end++
   100  			comma++
   101  		}
   102  		i = comma
   103  	}
   104  
   105  	return tokens[:end]
   106  }