Copyright (c) 2017 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd

package safehtml

import (
	
	
	
	
)
A StyleSheet is an immutable string-like type which represents a CSS style sheet and guarantees that its value, as a string, will not cause untrusted script execution (cross-site scripting) when evaluated as CSS in a browser. StyleSheet's string representation can safely be interpolated as the content of a style element within HTML. The StyleSheet string should not be escaped before interpolation.
We declare a StyleSheet not as a string but as a struct wrapping a string to prevent construction of StyleSheet values through string conversion.
StyleSheetFromConstant constructs a StyleSheet with the underlying stylesheet set to the given styleSheet, which must be an untyped string constant. No runtime validation or sanitization is performed on script; being under application control, it is simply assumed to comply with the StyleSheet contract.
func ( stringConstant) StyleSheet {
	return StyleSheet{string()}
}
CSSRule constructs a StyleSheet containng a CSS rule of the form: selector{style} It returns an error if selector contains disallowed characters or unbalanced brackets. The constructed StyleSheet value is guaranteed to fulfill its type contract, but is not guaranteed to be semantically valid CSS.
func ( string,  Style) (StyleSheet, error) {
	if strings.ContainsRune(, '<') {
		return StyleSheet{}, fmt.Errorf("selector %q contains '<'", )
	}
	 := cssStringPattern.ReplaceAllString(, "")
	if  := invalidCSSSelectorRune.FindStringSubmatch();  != nil {
		return StyleSheet{}, fmt.Errorf("selector %q contains %q, which is disallowed outside of CSS strings", , [0])
	}
	if !hasBalancedBrackets() {
		return StyleSheet{}, fmt.Errorf("selector %q contains unbalanced () or [] brackets", )
	}
	return StyleSheet{fmt.Sprintf("%s{%s}", , .String())}, nil
}

cssStringPattern matches a single- or double-quoted CSS string.
	cssStringPattern = regexp.MustCompile(
		`"([^"\r\n\f\\]|\\[\s\S])*"|` + // Double-quoted string literal
			`'([^'\r\n\f\\]|\\[\s\S])*'`) // Single-quoted string literal
invalidCSSSelectorRune matches a rune that is not allowed in a CSS3 selector that does not contain string literals. See https://w3.org/TR/css3-selectors/#selectors.
	invalidCSSSelectorRune = regexp.MustCompile(`[^-_a-zA-Z0-9#.:* ,>+~[\]()=^$|]`)
)
hasBalancedBrackets returns whether s has balanced () and [] brackets.
func ( string) bool {
	 := list.New()
	for  := 0;  < len(); ++ {
		 := []
		if ,  := matchingBrackets[];  {
			 := .Back()
			if  == nil {
				return false
Skip success check for this type assertion since it is trivial to see that only bytes are pushed onto this stack.
			if  := .Value.(byte);  !=  {
				return false
			}
			.Remove()
			continue
		}
		for ,  := range matchingBrackets {
			if  ==  {
				.PushBack()
				break
			}
		}
	}
	return .Len() == 0
}
matchingBrackets[x] is the opening bracket that matches closing bracket x.
var matchingBrackets = map[byte]byte{
	')': '(',
	']': '[',
}
String returns the string form of the StyleSheet.
func ( StyleSheet) () string {
	return .str