sassc-embedded 1.64.2 → 1.68.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +41 -8
  3. data/lib/sassc/embedded/version.rb +1 -1
  4. data/lib/sassc/embedded.rb +11 -9
  5. data/vendor/github.com/sass/sassc-ruby/LICENSE.txt +22 -0
  6. data/vendor/github.com/sass/sassc-ruby/lib/sassc/dependency.rb +17 -0
  7. data/vendor/github.com/sass/sassc-ruby/lib/sassc/engine.rb +141 -0
  8. data/vendor/github.com/sass/sassc-ruby/lib/sassc/error.rb +37 -0
  9. data/vendor/github.com/sass/sassc-ruby/lib/sassc/functions_handler.rb +73 -0
  10. data/vendor/github.com/sass/sassc-ruby/lib/sassc/import_handler.rb +50 -0
  11. data/vendor/github.com/sass/sassc-ruby/lib/sassc/importer.rb +31 -0
  12. data/vendor/github.com/sass/sassc-ruby/lib/sassc/native/native_context_api.rb +147 -0
  13. data/vendor/github.com/sass/sassc-ruby/lib/sassc/native/native_functions_api.rb +159 -0
  14. data/vendor/github.com/sass/sassc-ruby/lib/sassc/native/sass2scss_api.rb +10 -0
  15. data/vendor/github.com/sass/sassc-ruby/lib/sassc/native/sass_input_style.rb +13 -0
  16. data/vendor/github.com/sass/sassc-ruby/lib/sassc/native/sass_output_style.rb +12 -0
  17. data/vendor/github.com/sass/sassc-ruby/lib/sassc/native/sass_value.rb +97 -0
  18. data/vendor/github.com/sass/sassc-ruby/lib/sassc/native/string_list.rb +10 -0
  19. data/vendor/github.com/sass/sassc-ruby/lib/sassc/native.rb +64 -0
  20. data/vendor/github.com/sass/sassc-ruby/lib/sassc/sass_2_scss.rb +9 -0
  21. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/functions.rb +8 -0
  22. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value/bool.rb +32 -0
  23. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value/color.rb +95 -0
  24. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value/list.rb +136 -0
  25. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value/map.rb +69 -0
  26. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value/number.rb +389 -0
  27. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value/string.rb +96 -0
  28. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value.rb +137 -0
  29. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion/base.rb +13 -0
  30. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion/bool.rb +13 -0
  31. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion/color.rb +18 -0
  32. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion/list.rb +25 -0
  33. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion/map.rb +21 -0
  34. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion/number.rb +13 -0
  35. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion/string.rb +17 -0
  36. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion.rb +69 -0
  37. data/vendor/github.com/sass/sassc-ruby/lib/sassc/script.rb +17 -0
  38. data/vendor/github.com/sass/sassc-ruby/lib/sassc/util/normalized_map.rb +117 -0
  39. data/vendor/github.com/sass/sassc-ruby/lib/sassc/util.rb +231 -0
  40. data/vendor/github.com/sass/sassc-ruby/lib/sassc/version.rb +5 -0
  41. data/vendor/github.com/sass/sassc-ruby/lib/sassc.rb +64 -0
  42. metadata +44 -20
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Native
5
+ # Creators for sass function list and function descriptors
6
+ # ADDAPI Sass_C_Function_List ADDCALL sass_make_function_list (size_t length);
7
+ # ADDAPI Sass_C_Function_Callback ADDCALL sass_make_function (const char* signature, Sass_C_Function fn, void* cookie);
8
+ attach_function :sass_make_function_list, [:size_t], :sass_c_function_list_ptr
9
+ attach_function :sass_make_function, [:string, :sass_c_function, :pointer], :sass_c_function_callback_ptr
10
+
11
+ # Setters and getters for callbacks on function lists
12
+ # ADDAPI Sass_C_Function_Callback ADDCALL sass_function_get_list_entry(Sass_C_Function_List list, size_t pos);
13
+ # ADDAPI void ADDCALL sass_function_set_list_entry(Sass_C_Function_List list, size_t pos, Sass_C_Function_Callback cb);
14
+ attach_function :sass_function_get_list_entry, [:sass_c_function_list_ptr, :size_t], :sass_c_function_callback_ptr
15
+ attach_function :sass_function_set_list_entry, [:sass_c_function_list_ptr, :size_t, :sass_c_function_callback_ptr], :void
16
+
17
+ # ADDAPI union Sass_Value* ADDCALL sass_make_number (double val, const char* unit);
18
+ attach_function :sass_make_number, [:double, :string], :sass_value_ptr
19
+
20
+ # ADDAPI union Sass_Value* ADDCALL sass_make_string (const char* val);
21
+ attach_function :sass_make_string, [:string], :sass_value_ptr
22
+
23
+ # ADDAPI union Sass_Value* ADDCALL sass_make_qstring (const char* val);
24
+ attach_function :sass_make_qstring, [:string], :sass_value_ptr
25
+
26
+ # ADDAPI union Sass_Value* ADDCALL sass_make_color (double r, double g, double b, double a);
27
+ attach_function :sass_make_color, [:double, :double, :double, :double], :sass_value_ptr
28
+
29
+ # ADDAPI union Sass_Value* ADDCALL sass_make_map (size_t len);
30
+ attach_function :sass_make_map, [:size_t], :sass_value_ptr
31
+
32
+ # ADDAPI union Sass_Value* ADDCALL sass_make_list (size_t len, enum Sass_Separator sep)
33
+ attach_function :sass_make_list, [:size_t, SassSeparator], :sass_value_ptr
34
+
35
+ # ADDAPI union Sass_Value* ADDCALL sass_make_boolean (boolean val);
36
+ attach_function :sass_make_boolean, [:bool], :sass_value_ptr
37
+
38
+ # ADDAPI void ADDCALL sass_map_set_key (union Sass_Value* v, size_t i, union Sass_Value*);
39
+ attach_function :sass_map_set_key, [:sass_value_ptr, :size_t, :sass_value_ptr], :void
40
+
41
+ # ADDAPI union Sass_Value* ADDCALL sass_map_get_key (const union Sass_Value* v, size_t i);
42
+ attach_function :sass_map_get_key, [:sass_value_ptr, :size_t], :sass_value_ptr
43
+
44
+ # ADDAPI void ADDCALL sass_map_set_value (union Sass_Value* v, size_t i, union Sass_Value*);
45
+ attach_function :sass_map_set_value, [:sass_value_ptr, :size_t, :sass_value_ptr], :void
46
+
47
+ # ADDAPI union Sass_Value* ADDCALL sass_map_get_value (const union Sass_Value* v, size_t i);
48
+ attach_function :sass_map_get_value, [:sass_value_ptr, :size_t], :sass_value_ptr
49
+
50
+ # ADDAPI size_t ADDCALL sass_map_get_length (const union Sass_Value* v);
51
+ attach_function :sass_map_get_length, [:sass_value_ptr], :size_t
52
+
53
+ # ADDAPI union Sass_Value* ADDCALL sass_list_get_value (const union Sass_Value* v, size_t i);
54
+ attach_function :sass_list_get_value, [:sass_value_ptr, :size_t], :sass_value_ptr
55
+
56
+ # ADDAPI void ADDCALL sass_list_set_value (union Sass_Value* v, size_t i, union Sass_Value* value);
57
+ attach_function :sass_list_set_value, [:sass_value_ptr, :size_t, :sass_value_ptr], :void
58
+
59
+ # ADDAPI size_t ADDCALL sass_list_get_length (const union Sass_Value* v);
60
+ attach_function :sass_list_get_length, [:sass_value_ptr], :size_t
61
+
62
+ # ADDAPI union Sass_Value* ADDCALL sass_make_error (const char* msg);
63
+ attach_function :sass_make_error, [:string], :sass_value_ptr
64
+
65
+ # ADDAPI enum Sass_Tag ADDCALL sass_value_get_tag (const union Sass_Value* v);
66
+ attach_function :sass_value_get_tag, [:sass_value_ptr], SassTag
67
+ attach_function :sass_value_is_null, [:sass_value_ptr], :bool
68
+
69
+ # ADDAPI const char* ADDCALL sass_string_get_value (const union Sass_Value* v);
70
+ attach_function :sass_string_get_value, [:sass_value_ptr], :string
71
+
72
+ # ADDAPI bool ADDCALL sass_string_is_quoted(const union Sass_Value* v);
73
+ attach_function :sass_string_is_quoted, [:sass_value_ptr], :bool
74
+
75
+ # ADDAPI const char* ADDCALL sass_number_get_value (const union Sass_Value* v);
76
+ attach_function :sass_number_get_value, [:sass_value_ptr], :double
77
+
78
+ # ADDAPI const char* ADDCALL sass_number_get_unit (const union Sass_Value* v);
79
+ attach_function :sass_number_get_unit, [:sass_value_ptr], :string
80
+
81
+ # ADDAPI const char* ADDCALL sass_boolean_get_value (const union Sass_Value* v);
82
+ attach_function :sass_boolean_get_value, [:sass_value_ptr], :bool
83
+
84
+ def self.string_get_type(native_value)
85
+ string_is_quoted(native_value) ? :string : :identifier
86
+ end
87
+
88
+ # ADDAPI double ADDCALL sass_color_get_r (const union Sass_Value* v);
89
+ # ADDAPI void ADDCALL sass_color_set_r (union Sass_Value* v, double r);
90
+ # ADDAPI double ADDCALL sass_color_get_g (const union Sass_Value* v);
91
+ # ADDAPI void ADDCALL sass_color_set_g (union Sass_Value* v, double g);
92
+ # ADDAPI double ADDCALL sass_color_get_b (const union Sass_Value* v);
93
+ # ADDAPI void ADDCALL sass_color_set_b (union Sass_Value* v, double b);
94
+ # ADDAPI double ADDCALL sass_color_get_a (const union Sass_Value* v);
95
+ # ADDAPI void ADDCALL sass_color_set_a (union Sass_Value* v, double a);
96
+ ['r', 'g', 'b', 'a'].each do |color_channel|
97
+ attach_function "sass_color_get_#{color_channel}".to_sym, [:sass_value_ptr], :double
98
+ attach_function "sass_color_set_#{color_channel}".to_sym, [:sass_value_ptr, :double], :void
99
+ end
100
+
101
+ # ADDAPI char* ADDCALL sass_error_get_message (const union Sass_Value* v);
102
+ # ADDAPI void ADDCALL sass_error_set_message (union Sass_Value* v, char* msg);
103
+ attach_function :sass_error_get_message, [:sass_value_ptr], :string
104
+ attach_function :sass_error_set_message, [:sass_value_ptr, :pointer], :void
105
+
106
+ # Getters for custom function descriptors
107
+ # ADDAPI const char* ADDCALL sass_function_get_signature (Sass_C_Function_Callback fn);
108
+ # ADDAPI Sass_C_Function ADDCALL sass_function_get_function (Sass_C_Function_Callback fn);
109
+ # ADDAPI void* ADDCALL sass_function_get_cookie (Sass_C_Function_Callback fn);
110
+ attach_function :sass_function_get_signature, [:sass_c_function_callback_ptr], :string
111
+ attach_function :sass_function_get_function, [:sass_c_function_callback_ptr], :sass_c_function
112
+ attach_function :sass_function_get_cookie, [:sass_c_function_callback_ptr], :pointer
113
+
114
+ # Creators for custom importer callback (with some additional pointer)
115
+ # The pointer is mostly used to store the callback into the actual binding
116
+ # ADDAPI Sass_C_Import_Callback ADDCALL sass_make_importer (Sass_C_Import_Fn, void* cookie);
117
+ attach_function :sass_make_importer, [:sass_c_import_function, :pointer], :sass_importer
118
+
119
+ # Getters for import function descriptors
120
+ # ADDAPI Sass_C_Import_Fn ADDCALL sass_import_get_function (Sass_C_Import_Callback fn);
121
+ # ADDAPI void* ADDCALL sass_import_get_cookie (Sass_C_Import_Callback fn);
122
+
123
+ # Deallocator for associated memory
124
+ # ADDAPI void ADDCALL sass_delete_importer (Sass_C_Import_Callback fn);
125
+
126
+ # Creator for sass custom importer return argument list
127
+ # ADDAPI struct Sass_Import** ADDCALL sass_make_import_list (size_t length);
128
+ attach_function :sass_make_import_list, [:size_t], :sass_import_list_ptr
129
+
130
+ # Creator for a single import entry returned by the custom importer inside the list
131
+ # ADDAPI struct Sass_Import* ADDCALL sass_make_import_entry (const char* path, char* source, char* srcmap);
132
+ # ADDAPI struct Sass_Import* ADDCALL sass_make_import (const char* path, const char* base, char* source, char* srcmap);
133
+ attach_function :sass_make_import_entry, [:string, :pointer, :pointer], :sass_import_ptr
134
+
135
+ # Setters to insert an entry into the import list (you may also use [] access directly)
136
+ # Since we are dealing with pointers they should have a guaranteed and fixed size
137
+ # ADDAPI void ADDCALL sass_import_set_list_entry (struct Sass_Import** list, size_t idx, struct Sass_Import* entry);
138
+ attach_function :sass_import_set_list_entry, [:sass_import_list_ptr, :size_t, :sass_import_ptr], :void
139
+ # ADDAPI struct Sass_Import* ADDCALL sass_import_get_list_entry (struct Sass_Import** list, size_t idx);
140
+
141
+ # Getters for import entry
142
+ # ADDAPI const char* ADDCALL sass_import_get_imp_path (struct Sass_Import*);
143
+ attach_function :sass_import_get_imp_path, [:sass_import_ptr], :string
144
+ # ADDAPI const char* ADDCALL sass_import_get_abs_path (struct Sass_Import*);
145
+ attach_function :sass_import_get_abs_path, [:sass_import_ptr], :string
146
+ # ADDAPI const char* ADDCALL sass_import_get_source (struct Sass_Import*);
147
+ attach_function :sass_import_get_source, [:sass_import_ptr], :string
148
+ # ADDAPI const char* ADDCALL sass_import_get_srcmap (struct Sass_Import*);
149
+ # Explicit functions to take ownership of these items
150
+ # The property on our struct will be reset to NULL
151
+ # ADDAPI char* ADDCALL sass_import_take_source (struct Sass_Import*);
152
+ # ADDAPI char* ADDCALL sass_import_take_srcmap (struct Sass_Import*);
153
+
154
+ # Deallocator for associated memory (incl. entries)
155
+ # ADDAPI void ADDCALL sass_delete_import_list (struct Sass_Import**);
156
+ # Just in case we have some stray import structs
157
+ # ADDAPI void ADDCALL sass_delete_import (struct Sass_Import*);
158
+ end
159
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Native
5
+ # ADDAPI char* ADDCALL sass2scss (const char* sass, const int options);
6
+ attach_function :sass2scss, [:string, :int], :string
7
+
8
+ # ADDAPI const char* ADDCALL sass2scss_version(void);
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Native
5
+ SassInputStyle = enum(
6
+ :sass_context_null,
7
+ :sass_context_file,
8
+ :sass_context_data,
9
+ :sass_context_folder
10
+ )
11
+ end
12
+ end
13
+
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Native
5
+ SassOutputStyle = enum(
6
+ :sass_style_nested,
7
+ :sass_style_expanded,
8
+ :sass_style_compact,
9
+ :sass_style_compressed
10
+ )
11
+ end
12
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Native
5
+ class SassValue < FFI::Union; end
6
+
7
+ SassTag = enum(
8
+ :sass_boolean,
9
+ :sass_number,
10
+ :sass_color,
11
+ :sass_string,
12
+ :sass_list,
13
+ :sass_map,
14
+ :sass_null,
15
+ :sass_error,
16
+ :sass_warning
17
+ )
18
+
19
+ SassSeparator = enum(
20
+ :sass_comma,
21
+ :sass_space
22
+ )
23
+
24
+ class SassUnknown < FFI::Struct
25
+ layout :tag, SassTag
26
+ end
27
+
28
+ class SassBoolean < FFI::Struct
29
+ layout :tag, SassTag,
30
+ :value, :bool
31
+ end
32
+
33
+ class SassNumber < FFI::Struct
34
+ layout :tag, SassTag,
35
+ :value, :double,
36
+ :unit, :string
37
+ end
38
+
39
+ class SassColor < FFI::Struct
40
+ layout :tag, SassTag,
41
+ :r, :double,
42
+ :g, :double,
43
+ :b, :double,
44
+ :a, :double
45
+ end
46
+
47
+ class SassString < FFI::Struct
48
+ layout :tag, SassTag,
49
+ :value, :string
50
+ end
51
+
52
+ class SassList < FFI::Struct
53
+ layout :tag, SassTag,
54
+ :separator, SassSeparator,
55
+ :length, :size_t,
56
+ :values, :pointer
57
+ end
58
+
59
+ class SassMapPair < FFI::Struct
60
+ layout :key, SassValue.ptr,
61
+ :value, SassValue.ptr
62
+ end
63
+
64
+ class SassMap < FFI::Struct
65
+ layout :tag, SassTag,
66
+ :length, :size_t,
67
+ :pairs, SassMapPair.ptr
68
+ end
69
+
70
+ class SassNull < FFI::Struct
71
+ layout :tag, SassTag
72
+ end
73
+
74
+ class SassError < FFI::Struct
75
+ layout :tag, SassTag,
76
+ :message, :string
77
+ end
78
+
79
+ class SassWarning < FFI::Struct
80
+ layout :tag, SassTag,
81
+ :message, :string
82
+ end
83
+
84
+ class SassValue # < FFI::Union
85
+ layout :unknown, SassUnknown,
86
+ :boolean, SassBoolean,
87
+ :number, SassNumber,
88
+ :color, SassColor,
89
+ :string, SassString,
90
+ :list, SassList,
91
+ :map, SassMap,
92
+ :null, SassNull,
93
+ :error, SassError,
94
+ :warning, SassWarning
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Native
5
+ class StringList < FFI::Struct
6
+ layout :string_list, StringList.ptr,
7
+ :string, :string
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ffi"
4
+
5
+ module SassC
6
+ module Native
7
+ extend FFI::Library
8
+
9
+ dl_ext = RbConfig::MAKEFILE_CONFIG['DLEXT']
10
+ begin
11
+ ffi_lib File.expand_path("libsass.#{dl_ext}", __dir__)
12
+ rescue LoadError # Some non-rvm environments don't copy a shared object over to lib/sassc
13
+ ffi_lib File.expand_path("libsass.#{dl_ext}", "#{__dir__}/../../ext")
14
+ end
15
+
16
+ require_relative "native/sass_value"
17
+
18
+ typedef :pointer, :sass_options_ptr
19
+ typedef :pointer, :sass_context_ptr
20
+ typedef :pointer, :sass_file_context_ptr
21
+ typedef :pointer, :sass_data_context_ptr
22
+
23
+ typedef :pointer, :sass_c_function_list_ptr
24
+ typedef :pointer, :sass_c_function_callback_ptr
25
+ typedef :pointer, :sass_value_ptr
26
+
27
+ typedef :pointer, :sass_import_list_ptr
28
+ typedef :pointer, :sass_importer
29
+ typedef :pointer, :sass_import_ptr
30
+
31
+ callback :sass_c_function, [:pointer, :pointer], :pointer
32
+ callback :sass_c_import_function, [:pointer, :pointer, :pointer], :pointer
33
+
34
+ require_relative "native/sass_input_style"
35
+ require_relative "native/sass_output_style"
36
+ require_relative "native/string_list"
37
+
38
+ # Remove the redundant "sass_" from the beginning of every method name
39
+ def self.attach_function(*args)
40
+ return super if args.size != 3
41
+
42
+ if args[0] =~ /^sass_/
43
+ args.unshift args[0].to_s.sub(/^sass_/, "")
44
+ end
45
+
46
+ super(*args)
47
+ end
48
+
49
+ # https://github.com/ffi/ffi/wiki/Examples#array-of-strings
50
+ def self.return_string_array(ptr)
51
+ ptr.null? ? [] : ptr.get_array_of_string(0).compact
52
+ end
53
+
54
+ def self.native_string(string)
55
+ m = FFI::MemoryPointer.from_string(string)
56
+ m.autorelease = false
57
+ m
58
+ end
59
+
60
+ require_relative "native/native_context_api"
61
+ require_relative "native/native_functions_api"
62
+ require_relative "native/sass2scss_api"
63
+ end
64
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ class Sass2Scss
5
+ def self.convert(sass)
6
+ Native.sass2scss(sass, 0)
7
+ end
8
+ end
9
+ 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 = SassC::Util.clamp(red.to_i, 0, 255)
26
+ @green = SassC::Util.clamp(green.to_i, 0, 255)
27
+ @blue = SassC::Util.clamp(blue.to_i, 0, 255)
28
+ @alpha = SassC::Util.clamp(alpha.to_f, 0.0, 1.0)
29
+ elsif hue && saturation && lightness && alpha
30
+ @mode = :hsla
31
+ @hue = SassC::Util.clamp(hue.to_i, 0, 360)
32
+ @saturation = SassC::Util.clamp(saturation.to_i, 0, 100)
33
+ @lightness = SassC::Util.clamp(lightness.to_i, 0, 100)
34
+ @alpha = SassC::Util.clamp(alpha.to_f, 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