dartsass-ruby 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ class Importer
5
+ attr_reader :options
6
+
7
+ def initialize(options)
8
+ @options = options
9
+ end
10
+
11
+ def imports(path, parent_path)
12
+ # A custom importer must override this method.
13
+ # Custom importer may return an Import, or an array of Imports.
14
+ raise NotImplementedError
15
+ end
16
+
17
+ class Import
18
+ attr_accessor :path, :source, :source_map_path
19
+
20
+ def initialize(path, source: nil, source_map_path: nil)
21
+ @path = path
22
+ @source = source
23
+ @source_map_path = source_map_path
24
+ end
25
+
26
+ def to_s
27
+ "Import: #{path} #{source} #{source_map_path}"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Protocol
5
+ FILE = 'file:'
6
+ IMPORT = 'sassc-embedded-import:'
7
+ LOADED = 'sassc-embedded-loaded:'
8
+ end
9
+
10
+ private_constant :Protocol
11
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ class Sass2Scss
5
+ def self.convert(sass)
6
+ {
7
+ contents: sass,
8
+ syntax: :indented
9
+ }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Script
5
+ module Functions
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A SassScript object representing a boolean (true or false) value.
4
+
5
+ class SassC::Script::Value::Bool < SassC::Script::Value
6
+
7
+ # The true value in SassScript.
8
+ # This is assigned before new is overridden below so that we use the default implementation.
9
+ TRUE = new(true)
10
+
11
+ # The false value in SassScript.
12
+ # This is assigned before new is overridden below so that we use the default implementation.
13
+ FALSE = new(false)
14
+
15
+ # We override object creation so that users of the core API
16
+ # will not need to know that booleans are specific constants.
17
+ # Tests `value` for truthiness and returns the TRUE or FALSE constant.
18
+ def self.new(value)
19
+ value ? TRUE : FALSE
20
+ end
21
+
22
+ # The pure Ruby value of this Boolean
23
+ attr_reader :value
24
+ alias_method :to_bool, :value
25
+
26
+ # Returns the string "true" or "false" for this value
27
+ def to_s(opts = {})
28
+ @value.to_s
29
+ end
30
+ alias_method :to_sass, :to_s
31
+
32
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A SassScript object representing a CSS color.
4
+ # This class provides a very bare-bones system for storing a RGB(A) or HSL(A)
5
+ # color and converting it to a CSS color function.
6
+ #
7
+ # If your Sass method accepts a color you will need to perform any
8
+ # needed color mathematics or transformations yourself.
9
+
10
+ class SassC::Script::Value::Color < SassC::Script::Value
11
+
12
+ attr_reader :red
13
+ attr_reader :green
14
+ attr_reader :blue
15
+ attr_reader :hue
16
+ attr_reader :saturation
17
+ attr_reader :lightness
18
+ attr_reader :alpha
19
+
20
+ # Creates a new color with (`red`, `green`, `blue`) or (`hue`, `saturation`, `lightness`
21
+ # values, plus an optional `alpha` transparency value.
22
+ def initialize(red:nil, green:nil, blue:nil, hue:nil, saturation:nil, lightness:nil, alpha:1.0)
23
+ if red && green && blue && alpha
24
+ @mode = :rgba
25
+ @red = red.to_i.clamp(0, 255)
26
+ @green = green.to_i.clamp(0, 255)
27
+ @blue = blue.to_i.clamp(0, 255)
28
+ @alpha = alpha.to_f.clamp(0.0, 1.0)
29
+ elsif hue && saturation && lightness && alpha
30
+ @mode = :hsla
31
+ @hue = hue.to_i.clamp(0, 360)
32
+ @saturation = saturation.to_i.clamp(0, 100)
33
+ @lightness = lightness.to_i.clamp(0, 100)
34
+ @alpha = alpha.to_f.clamp(0.0, 1.0)
35
+ else
36
+ raise SassC::UnsupportedValue, "Unable to determine color configuration for "
37
+ end
38
+ end
39
+
40
+ # Returns a CSS color declaration in the form
41
+ # `rgb(…)`, `rgba(…)`, `hsl(…)`, or `hsla(…)`.
42
+ def to_s
43
+ if rgba? && @alpha == 1.0
44
+ return "rgb(#{@red}, #{@green}, #{@blue})"
45
+ elsif rgba?
46
+ return "rgba(#{@red}, #{@green}, #{@blue}, #{alpha_string})"
47
+ elsif hsla? && @alpha == 1.0
48
+ return "hsl(#{@hue}, #{@saturation}%, #{@lightness}%)"
49
+ else # hsla?
50
+ return "hsla(#{@hue}, #{@saturation}%, #{@lightness}%, #{alpha_string})"
51
+ end
52
+ end
53
+
54
+ # True if this color has RGBA values
55
+ def rgba?
56
+ @mode == :rgba
57
+ end
58
+
59
+ # True if this color has HSLA values
60
+ def hlsa?
61
+ @mode == :hlsa
62
+ end
63
+
64
+ # Returns the alpha value of this color as a string
65
+ # and rounded to 8 decimal places.
66
+ def alpha_string
67
+ alpha.round(8).to_s
68
+ end
69
+
70
+ # Returns the values of this color in an array.
71
+ # Provided for compatibility between different SassC::Script::Value classes
72
+ def value
73
+ return [
74
+ red, green, blue,
75
+ hue, saturation, lightness,
76
+ alpha,
77
+ ].compact
78
+ end
79
+
80
+ # True if this Color is equal to `other_color`
81
+ def eql?(other_color)
82
+ unless other_color.is_a?(self.class)
83
+ raise ArgumentError, "No implicit conversion of #{other_color.class} to #{self.class}"
84
+ end
85
+ self.value == other_color.value
86
+ end
87
+ alias_method :==, :eql?
88
+
89
+ # Returns a numeric value for comparing two Color objects
90
+ # This method is used internally by the Hash class and is not the same as `.to_h`
91
+ def hash
92
+ value.hash
93
+ end
94
+
95
+ end
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A SassScript object representing a CSS list.
4
+ # This includes both comma-separated lists and space-separated lists.
5
+
6
+ class SassC::Script::Value::List < SassC::Script::Value
7
+
8
+ # The Ruby array containing the contents of the list.
9
+ #
10
+ # @return [Array<Value>]
11
+ attr_reader :value
12
+ alias_method :to_a, :value
13
+
14
+ # The operator separating the values of the list.
15
+ # Either `:comma` or `:space`.
16
+ #
17
+ # @return [Symbol]
18
+ attr_reader :separator
19
+
20
+ # Whether the list is surrounded by square brackets.
21
+ #
22
+ # @return [Boolean]
23
+ attr_reader :bracketed
24
+
25
+ # Creates a new list.
26
+ #
27
+ # @param value [Array<Value>] See \{#value}
28
+ # @param separator [Symbol] See \{#separator}
29
+ # @param bracketed [Boolean] See \{#bracketed}
30
+ def initialize(value, separator: nil, bracketed: false)
31
+ super(value)
32
+ @separator = separator
33
+ @bracketed = bracketed
34
+ end
35
+
36
+ # @see Value#options=
37
+ def options=(options)
38
+ super
39
+ value.each {|v| v.options = options}
40
+ end
41
+
42
+ # @see Value#eq
43
+ def eq(other)
44
+ SassC::Script::Value::Bool.new(
45
+ other.is_a?(List) && value == other.value &&
46
+ separator == other.separator && bracketed == other.bracketed
47
+ )
48
+ end
49
+
50
+ def hash
51
+ @hash ||= [value, separator, bracketed].hash
52
+ end
53
+
54
+ # @see Value#to_s
55
+ def to_s(opts = {})
56
+ if !bracketed && value.empty?
57
+ raise SassC::SyntaxError.new("#{inspect} isn't a valid CSS value.")
58
+ end
59
+
60
+ members = value.
61
+ reject {|e| e.is_a?(Null) || e.is_a?(List) && e.value.empty?}.
62
+ map {|e| e.to_s(opts)}
63
+
64
+ contents = members.join(sep_str)
65
+ bracketed ? "[#{contents}]" : contents
66
+ end
67
+
68
+ # @see Value#to_sass
69
+ def to_sass(opts = {})
70
+ return bracketed ? "[]" : "()" if value.empty?
71
+ members = value.map do |v|
72
+ if element_needs_parens?(v)
73
+ "(#{v.to_sass(opts)})"
74
+ else
75
+ v.to_sass(opts)
76
+ end
77
+ end
78
+
79
+ if separator == :comma && members.length == 1
80
+ return "#{bracketed ? '[' : '('}#{members.first},#{bracketed ? ']' : ')'}"
81
+ end
82
+
83
+ contents = members.join(sep_str(nil))
84
+ bracketed ? "[#{contents}]" : contents
85
+ end
86
+
87
+ # @see Value#to_h
88
+ def to_h
89
+ return {} if value.empty?
90
+ super
91
+ end
92
+
93
+ # @see Value#inspect
94
+ def inspect
95
+ (bracketed ? '[' : '(') + value.map {|e| e.inspect}.join(sep_str(nil)) + (bracketed ? ']' : ')')
96
+ end
97
+
98
+ # Asserts an index is within the list.
99
+ #
100
+ # @private
101
+ #
102
+ # @param list [Sass::Script::Value::List] The list for which the index should be checked.
103
+ # @param n [Sass::Script::Value::Number] The index being checked.
104
+ def self.assert_valid_index(list, n)
105
+ if !n.int? || n.to_i == 0
106
+ raise ArgumentError.new("List index #{n} must be a non-zero integer")
107
+ elsif list.to_a.size == 0
108
+ raise ArgumentError.new("List index is #{n} but list has no items")
109
+ elsif n.to_i.abs > (size = list.to_a.size)
110
+ raise ArgumentError.new(
111
+ "List index is #{n} but list is only #{size} item#{'s' if size != 1} long")
112
+ end
113
+ end
114
+
115
+ private
116
+
117
+ def element_needs_parens?(element)
118
+ if element.is_a?(List)
119
+ return false if element.value.length < 2
120
+ return false if element.bracketed
121
+ precedence = Sass::Script::Parser.precedence_of(separator || :space)
122
+ return Sass::Script::Parser.precedence_of(element.separator || :space) <= precedence
123
+ end
124
+
125
+ return false unless separator == :space
126
+ return false unless element.is_a?(Sass::Script::Tree::UnaryOperation)
127
+ element.operator == :minus || element.operator == :plus
128
+ end
129
+
130
+ def sep_str(opts = options)
131
+ return ' ' if separator == :space
132
+ return ',' if opts && opts[:style] == :compressed
133
+ ', '
134
+ end
135
+
136
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SassC::Script::Value::Map < SassC::Script::Value
4
+
5
+ # The Ruby hash containing the contents of this map.
6
+ # @return [Hash<Node, Node>]
7
+ attr_reader :value
8
+ alias_method :to_h, :value
9
+
10
+ # Creates a new map.
11
+ #
12
+ # @param hash [Hash<Node, Node>]
13
+ def initialize(hash)
14
+ super(hash)
15
+ end
16
+
17
+ # @see Value#options=
18
+ def options=(options)
19
+ super
20
+ value.each do |k, v|
21
+ k.options = options
22
+ v.options = options
23
+ end
24
+ end
25
+
26
+ # @see Value#separator
27
+ def separator
28
+ :comma unless value.empty?
29
+ end
30
+
31
+ # @see Value#to_a
32
+ def to_a
33
+ value.map do |k, v|
34
+ list = SassC::Script::Value::List.new([k, v], separator: :space)
35
+ list.options = options
36
+ list
37
+ end
38
+ end
39
+
40
+ # @see Value#eq
41
+ def eq(other)
42
+ SassC::Script::Value::Bool.new(other.is_a?(Map) && value == other.value)
43
+ end
44
+
45
+ def hash
46
+ @hash ||= value.hash
47
+ end
48
+
49
+ # @see Value#to_s
50
+ def to_s(opts = {})
51
+ raise SassC::SyntaxError.new("#{inspect} isn't a valid CSS value.")
52
+ end
53
+
54
+ def to_sass(opts = {})
55
+ return "()" if value.empty?
56
+
57
+ to_sass = lambda do |value|
58
+ if value.is_a?(List) && value.separator == :comma
59
+ "(#{value.to_sass(opts)})"
60
+ else
61
+ value.to_sass(opts)
62
+ end
63
+ end
64
+
65
+ "(#{value.map {|(k, v)| "#{to_sass[k]}: #{to_sass[v]}"}.join(', ')})"
66
+ end
67
+ alias_method :inspect, :to_sass
68
+
69
+ end