Skip to content

Commit b956108

Browse files
committed
Add support for lists in functions.
1 parent 39b9581 commit b956108

File tree

4 files changed

+77
-2
lines changed

4 files changed

+77
-2
lines changed

lib/sassc/native/native_functions_api.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ module Native
2626

2727
# ADDAPI union Sass_Value* ADDCALL sass_make_map (size_t len);
2828
attach_function :sass_make_map, [:size_t], :sass_value_ptr
29-
29+
30+
# ADDAPI union Sass_Value* ADDCALL sass_make_list (size_t len, enum Sass_Separator sep)
31+
attach_function :sass_make_list, [:size_t, SassSeparator], :sass_value_ptr
32+
3033
# ADDAPI union Sass_Value* ADDCALL sass_make_boolean (boolean val);
3134
attach_function :sass_make_boolean, [:bool], :sass_value_ptr
3235

@@ -45,6 +48,15 @@ module Native
4548
# ADDAPI size_t ADDCALL sass_map_get_length (const union Sass_Value* v);
4649
attach_function :sass_map_get_length, [:sass_value_ptr], :size_t
4750

51+
# ADDAPI union Sass_Value* ADDCALL sass_list_get_value (const union Sass_Value* v, size_t i);
52+
attach_function :sass_list_get_value, [:sass_value_ptr, :size_t], :sass_value_ptr
53+
54+
# ADDAPI void ADDCALL sass_list_set_value (union Sass_Value* v, size_t i, union Sass_Value* value);
55+
attach_function :sass_list_set_value, [:sass_value_ptr, :size_t, :sass_value_ptr], :void
56+
57+
# ADDAPI size_t ADDCALL sass_list_get_length (const union Sass_Value* v);
58+
attach_function :sass_list_get_length, [:sass_value_ptr], :size_t
59+
4860
# ADDAPI union Sass_Value* ADDCALL sass_make_error (const char* msg);
4961
attach_function :sass_make_error, [:string], :sass_value_ptr
5062

lib/sassc/script/value_conversion.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ def self.from_native(native_value, options)
4141

4242
argument = Sass::Script::Value::Map.new values
4343
argument
44+
when :sass_list
45+
length = Native::list_get_length(native_value)
46+
items = (0...length).map do |index|
47+
native_item = Native::list_get_value(native_value, index)
48+
from_native(native_item, options)
49+
end
50+
Sass::Script::Value::List.new(items, :space)
4451
else
4552
raise UnsupportedValue.new("Sass argument of type #{value_tag} unsupported")
4653
end
@@ -56,6 +63,8 @@ def self.to_native(value)
5663
Number.new(value).to_native
5764
when "Map"
5865
Map.new(value).to_native
66+
when "List"
67+
List.new(value).to_native
5968
when "Bool"
6069
Bool.new(value).to_native
6170
else
@@ -71,4 +80,5 @@ def self.to_native(value)
7180
require_relative "value_conversion/number"
7281
require_relative "value_conversion/color"
7382
require_relative "value_conversion/map"
74-
require_relative "value_conversion/bool"
83+
require_relative "value_conversion/list"
84+
require_relative "value_conversion/bool"
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module SassC
2+
module Script
3+
module ValueConversion
4+
SEPARATORS = {
5+
space: :sass_space,
6+
comma: :sass_comma
7+
}
8+
9+
class List < Base
10+
def to_native
11+
list = @value.to_a
12+
sep = SEPARATORS.fetch(@value.separator)
13+
native_list = Native::make_list(list.size, sep)
14+
list.each_with_index do |item, index|
15+
native_item = ValueConversion.to_native(item)
16+
Native::list_set_value(native_list, index, native_item)
17+
end
18+
native_list
19+
end
20+
end
21+
end
22+
end
23+
end

test/functions_test.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ def test_functions_may_accept_sass_color_type
119119
end
120120

121121
def test_function_with_unsupported_tag
122+
skip('What are other unsupported tags?')
122123
engine = Engine.new("div {url: function_with_unsupported_tag(());}")
123124

124125
exception = assert_raises(SassC::SyntaxError) do
@@ -166,6 +167,23 @@ def test_function_that_takes_a_sass_map
166167
CSS
167168
end
168169

170+
def test_function_that_returns_a_sass_list
171+
assert_sass <<-SCSS, <<-CSS
172+
$my-list: returns-sass-list();
173+
div { width: nth( $my-list, 2 ); }
174+
SCSS
175+
div { width: 20; }
176+
CSS
177+
end
178+
179+
def test_function_that_takes_a_sass_list
180+
assert_sass <<-SCSS, <<-CSS
181+
div { width: nth(inspect-list((10 20 30)), 2); }
182+
SCSS
183+
div { width: 20; }
184+
CSS
185+
end
186+
169187
private
170188

171189
def assert_sass(sass, expected_css)
@@ -250,6 +268,11 @@ def inspect_map ( argument )
250268
return argument
251269
end
252270

271+
def inspect_list(argument)
272+
raise StandardError.new "passed value is not a Sass::Script::Value::List" unless argument.is_a? Sass::Script::Value::List
273+
return argument
274+
end
275+
253276
def returns_sass_value
254277
return Sass::Script::Value::Color.new(red: 0, green: 0, blue: 0)
255278
end
@@ -263,6 +286,13 @@ def returns_sass_map
263286
return map
264287
end
265288

289+
def returns_sass_list
290+
numbers = [10, 20, 30].map do |n|
291+
Sass::Script::Value::Number.new(n, '')
292+
end
293+
Sass::Script::Value::List.new(numbers, :space)
294+
end
295+
266296
module Compass
267297
def stylesheet_path(path)
268298
Script::String.new("/css/#{path.value}", :identifier)

0 commit comments

Comments
 (0)