summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/aymerick/douceur/css
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/aymerick/douceur/css')
-rw-r--r--vendor/github.com/aymerick/douceur/css/declaration.go60
-rw-r--r--vendor/github.com/aymerick/douceur/css/rule.go230
-rw-r--r--vendor/github.com/aymerick/douceur/css/stylesheet.go25
3 files changed, 315 insertions, 0 deletions
diff --git a/vendor/github.com/aymerick/douceur/css/declaration.go b/vendor/github.com/aymerick/douceur/css/declaration.go
new file mode 100644
index 0000000000..61d29d3359
--- /dev/null
+++ b/vendor/github.com/aymerick/douceur/css/declaration.go
@@ -0,0 +1,60 @@
+package css
+
+import "fmt"
+
+// Declaration represents a parsed style property
+type Declaration struct {
+ Property string
+ Value string
+ Important bool
+}
+
+// NewDeclaration instanciates a new Declaration
+func NewDeclaration() *Declaration {
+ return &Declaration{}
+}
+
+// Returns string representation of the Declaration
+func (decl *Declaration) String() string {
+ return decl.StringWithImportant(true)
+}
+
+// StringWithImportant returns string representation with optional !important part
+func (decl *Declaration) StringWithImportant(option bool) string {
+ result := fmt.Sprintf("%s: %s", decl.Property, decl.Value)
+
+ if option && decl.Important {
+ result += " !important"
+ }
+
+ result += ";"
+
+ return result
+}
+
+// Equal returns true if both Declarations are equals
+func (decl *Declaration) Equal(other *Declaration) bool {
+ return (decl.Property == other.Property) && (decl.Value == other.Value) && (decl.Important == other.Important)
+}
+
+//
+// DeclarationsByProperty
+//
+
+// DeclarationsByProperty represents sortable style declarations
+type DeclarationsByProperty []*Declaration
+
+// Implements sort.Interface
+func (declarations DeclarationsByProperty) Len() int {
+ return len(declarations)
+}
+
+// Implements sort.Interface
+func (declarations DeclarationsByProperty) Swap(i, j int) {
+ declarations[i], declarations[j] = declarations[j], declarations[i]
+}
+
+// Implements sort.Interface
+func (declarations DeclarationsByProperty) Less(i, j int) bool {
+ return declarations[i].Property < declarations[j].Property
+}
diff --git a/vendor/github.com/aymerick/douceur/css/rule.go b/vendor/github.com/aymerick/douceur/css/rule.go
new file mode 100644
index 0000000000..b5a44b5429
--- /dev/null
+++ b/vendor/github.com/aymerick/douceur/css/rule.go
@@ -0,0 +1,230 @@
+package css
+
+import (
+ "fmt"
+ "strings"
+)
+
+const (
+ indentSpace = 2
+)
+
+// RuleKind represents a Rule kind
+type RuleKind int
+
+// Rule kinds
+const (
+ QualifiedRule RuleKind = iota
+ AtRule
+)
+
+// At Rules than have Rules inside their block instead of Declarations
+var atRulesWithRulesBlock = []string{
+ "@document", "@font-feature-values", "@keyframes", "@media", "@supports",
+}
+
+// Rule represents a parsed CSS rule
+type Rule struct {
+ Kind RuleKind
+
+ // At Rule name (eg: "@media")
+ Name string
+
+ // Raw prelude
+ Prelude string
+
+ // Qualified Rule selectors parsed from prelude
+ Selectors []string
+
+ // Style properties
+ Declarations []*Declaration
+
+ // At Rule embedded rules
+ Rules []*Rule
+
+ // Current rule embedding level
+ EmbedLevel int
+}
+
+// NewRule instanciates a new Rule
+func NewRule(kind RuleKind) *Rule {
+ return &Rule{
+ Kind: kind,
+ }
+}
+
+// Returns string representation of rule kind
+func (kind RuleKind) String() string {
+ switch kind {
+ case QualifiedRule:
+ return "Qualified Rule"
+ case AtRule:
+ return "At Rule"
+ default:
+ return "WAT"
+ }
+}
+
+// EmbedsRules returns true if this rule embeds another rules
+func (rule *Rule) EmbedsRules() bool {
+ if rule.Kind == AtRule {
+ for _, atRuleName := range atRulesWithRulesBlock {
+ if rule.Name == atRuleName {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+// Equal returns true if both rules are equals
+func (rule *Rule) Equal(other *Rule) bool {
+ if (rule.Kind != other.Kind) ||
+ (rule.Prelude != other.Prelude) ||
+ (rule.Name != other.Name) {
+ return false
+ }
+
+ if (len(rule.Selectors) != len(other.Selectors)) ||
+ (len(rule.Declarations) != len(other.Declarations)) ||
+ (len(rule.Rules) != len(other.Rules)) {
+ return false
+ }
+
+ for i, sel := range rule.Selectors {
+ if sel != other.Selectors[i] {
+ return false
+ }
+ }
+
+ for i, decl := range rule.Declarations {
+ if !decl.Equal(other.Declarations[i]) {
+ return false
+ }
+ }
+
+ for i, rule := range rule.Rules {
+ if !rule.Equal(other.Rules[i]) {
+ return false
+ }
+ }
+
+ return true
+}
+
+// Diff returns a string representation of rules differences
+func (rule *Rule) Diff(other *Rule) []string {
+ result := []string{}
+
+ if rule.Kind != other.Kind {
+ result = append(result, fmt.Sprintf("Kind: %s | %s", rule.Kind.String(), other.Kind.String()))
+ }
+
+ if rule.Prelude != other.Prelude {
+ result = append(result, fmt.Sprintf("Prelude: \"%s\" | \"%s\"", rule.Prelude, other.Prelude))
+ }
+
+ if rule.Name != other.Name {
+ result = append(result, fmt.Sprintf("Name: \"%s\" | \"%s\"", rule.Name, other.Name))
+ }
+
+ if len(rule.Selectors) != len(other.Selectors) {
+ result = append(result, fmt.Sprintf("Selectors: %v | %v", strings.Join(rule.Selectors, ", "), strings.Join(other.Selectors, ", ")))
+ } else {
+ for i, sel := range rule.Selectors {
+ if sel != other.Selectors[i] {
+ result = append(result, fmt.Sprintf("Selector: \"%s\" | \"%s\"", sel, other.Selectors[i]))
+ }
+ }
+ }
+
+ if len(rule.Declarations) != len(other.Declarations) {
+ result = append(result, fmt.Sprintf("Declarations Nb: %d | %d", len(rule.Declarations), len(other.Declarations)))
+ } else {
+ for i, decl := range rule.Declarations {
+ if !decl.Equal(other.Declarations[i]) {
+ result = append(result, fmt.Sprintf("Declaration: \"%s\" | \"%s\"", decl.String(), other.Declarations[i].String()))
+ }
+ }
+ }
+
+ if len(rule.Rules) != len(other.Rules) {
+ result = append(result, fmt.Sprintf("Rules Nb: %d | %d", len(rule.Rules), len(other.Rules)))
+ } else {
+
+ for i, rule := range rule.Rules {
+ if !rule.Equal(other.Rules[i]) {
+ result = append(result, fmt.Sprintf("Rule: \"%s\" | \"%s\"", rule.String(), other.Rules[i].String()))
+ }
+ }
+ }
+
+ return result
+}
+
+// Returns the string representation of a rule
+func (rule *Rule) String() string {
+ result := ""
+
+ if rule.Kind == QualifiedRule {
+ for i, sel := range rule.Selectors {
+ if i != 0 {
+ result += ", "
+ }
+ result += sel
+ }
+ } else {
+ // AtRule
+ result += fmt.Sprintf("%s", rule.Name)
+
+ if rule.Prelude != "" {
+ if result != "" {
+ result += " "
+ }
+ result += fmt.Sprintf("%s", rule.Prelude)
+ }
+ }
+
+ if (len(rule.Declarations) == 0) && (len(rule.Rules) == 0) {
+ result += ";"
+ } else {
+ result += " {\n"
+
+ if rule.EmbedsRules() {
+ for _, subRule := range rule.Rules {
+ result += fmt.Sprintf("%s%s\n", rule.indent(), subRule.String())
+ }
+ } else {
+ for _, decl := range rule.Declarations {
+ result += fmt.Sprintf("%s%s\n", rule.indent(), decl.String())
+ }
+ }
+
+ result += fmt.Sprintf("%s}", rule.indentEndBlock())
+ }
+
+ return result
+}
+
+// Returns identation spaces for declarations and rules
+func (rule *Rule) indent() string {
+ result := ""
+
+ for i := 0; i < ((rule.EmbedLevel + 1) * indentSpace); i++ {
+ result += " "
+ }
+
+ return result
+}
+
+// Returns identation spaces for end of block character
+func (rule *Rule) indentEndBlock() string {
+ result := ""
+
+ for i := 0; i < (rule.EmbedLevel * indentSpace); i++ {
+ result += " "
+ }
+
+ return result
+}
diff --git a/vendor/github.com/aymerick/douceur/css/stylesheet.go b/vendor/github.com/aymerick/douceur/css/stylesheet.go
new file mode 100644
index 0000000000..6b32c2ec90
--- /dev/null
+++ b/vendor/github.com/aymerick/douceur/css/stylesheet.go
@@ -0,0 +1,25 @@
+package css
+
+// Stylesheet represents a parsed stylesheet
+type Stylesheet struct {
+ Rules []*Rule
+}
+
+// NewStylesheet instanciate a new Stylesheet
+func NewStylesheet() *Stylesheet {
+ return &Stylesheet{}
+}
+
+// Returns string representation of the Stylesheet
+func (sheet *Stylesheet) String() string {
+ result := ""
+
+ for _, rule := range sheet.Rules {
+ if result != "" {
+ result += "\n"
+ }
+ result += rule.String()
+ }
+
+ return result
+}