sass 3.7.4 → 4.0.0.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/.yardopts +1 -1
- data/CODE_OF_CONDUCT.md +1 -1
- data/CONTRIBUTING.md +1 -146
- data/MIT-LICENSE +1 -1
- data/README.md +25 -39
- data/Rakefile +274 -0
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/lib/sass.rb +3 -3
- data/lib/sass/cache_stores/filesystem.rb +2 -2
- data/lib/sass/cache_stores/memory.rb +5 -4
- data/lib/sass/callbacks.rb +2 -2
- data/lib/sass/css.rb +12 -12
- data/lib/sass/engine.rb +44 -62
- data/lib/sass/environment.rb +7 -35
- data/lib/sass/error.rb +14 -14
- data/lib/sass/exec/base.rb +14 -3
- data/lib/sass/exec/sass_convert.rb +6 -20
- data/lib/sass/exec/sass_scss.rb +29 -5
- data/lib/sass/features.rb +2 -3
- data/lib/sass/importers/filesystem.rb +6 -11
- data/lib/sass/logger.rb +3 -8
- data/lib/sass/logger/base.rb +2 -19
- data/lib/sass/plugin.rb +2 -3
- data/lib/sass/plugin/compiler.rb +67 -48
- data/lib/sass/plugin/configuration.rb +3 -3
- data/lib/sass/plugin/merb.rb +1 -1
- data/lib/sass/plugin/rack.rb +3 -3
- data/lib/sass/plugin/staleness_checker.rb +3 -3
- data/lib/sass/railtie.rb +1 -1
- data/lib/sass/script.rb +3 -3
- data/lib/sass/script/css_parser.rb +15 -5
- data/lib/sass/script/functions.rb +121 -337
- data/lib/sass/script/lexer.rb +36 -102
- data/lib/sass/script/parser.rb +153 -529
- data/lib/sass/script/tree/funcall.rb +34 -42
- data/lib/sass/script/tree/interpolation.rb +26 -171
- data/lib/sass/script/tree/list_literal.rb +8 -23
- data/lib/sass/script/tree/map_literal.rb +2 -2
- data/lib/sass/script/tree/node.rb +3 -3
- data/lib/sass/script/tree/operation.rb +16 -43
- data/lib/sass/script/tree/string_interpolation.rb +43 -64
- data/lib/sass/script/tree/variable.rb +1 -1
- data/lib/sass/script/value.rb +0 -2
- data/lib/sass/script/value/arg_list.rb +1 -1
- data/lib/sass/script/value/base.rb +9 -27
- data/lib/sass/script/value/color.rb +18 -26
- data/lib/sass/script/value/helpers.rb +18 -44
- data/lib/sass/script/value/list.rb +14 -35
- data/lib/sass/script/value/map.rb +2 -2
- data/lib/sass/script/value/number.rb +16 -26
- data/lib/sass/script/value/string.rb +1 -30
- data/lib/sass/scss.rb +2 -0
- data/lib/sass/scss/css_parser.rb +3 -7
- data/lib/sass/scss/parser.rb +78 -196
- data/lib/sass/scss/rx.rb +14 -7
- data/lib/sass/scss/script_lexer.rb +15 -0
- data/lib/sass/scss/script_parser.rb +25 -0
- data/lib/sass/scss/static_parser.rb +55 -38
- data/lib/sass/selector.rb +10 -7
- data/lib/sass/selector/abstract_sequence.rb +12 -15
- data/lib/sass/selector/comma_sequence.rb +6 -24
- data/lib/sass/selector/pseudo.rb +6 -19
- data/lib/sass/selector/sequence.rb +16 -14
- data/lib/sass/selector/simple.rb +7 -9
- data/lib/sass/selector/simple_sequence.rb +12 -16
- data/lib/sass/shared.rb +1 -1
- data/lib/sass/source/map.rb +9 -7
- data/lib/sass/source/position.rb +4 -4
- data/lib/sass/stack.rb +3 -23
- data/lib/sass/tree/charset_node.rb +1 -1
- data/lib/sass/tree/comment_node.rb +1 -1
- data/lib/sass/tree/function_node.rb +3 -2
- data/lib/sass/tree/node.rb +3 -5
- data/lib/sass/tree/prop_node.rb +58 -49
- data/lib/sass/tree/rule_node.rb +8 -15
- data/lib/sass/tree/visitors/check_nesting.rb +23 -19
- data/lib/sass/tree/visitors/convert.rb +13 -15
- data/lib/sass/tree/visitors/cssize.rb +15 -4
- data/lib/sass/tree/visitors/deep_copy.rb +2 -2
- data/lib/sass/tree/visitors/extend.rb +14 -10
- data/lib/sass/tree/visitors/perform.rb +18 -29
- data/lib/sass/tree/visitors/set_options.rb +2 -2
- data/lib/sass/tree/visitors/to_css.rb +47 -77
- data/lib/sass/util.rb +311 -98
- data/lib/sass/util/cross_platform_random.rb +19 -0
- data/lib/sass/util/multibyte_string_scanner.rb +133 -127
- data/lib/sass/util/normalized_map.rb +8 -1
- data/lib/sass/util/ordered_hash.rb +192 -0
- data/lib/sass/version.rb +6 -2
- data/test/sass/cache_test.rb +131 -0
- data/test/sass/callbacks_test.rb +61 -0
- data/test/sass/compiler_test.rb +236 -0
- data/test/sass/conversion_test.rb +2171 -0
- data/test/sass/css2sass_test.rb +526 -0
- data/test/sass/data/hsl-rgb.txt +319 -0
- data/test/sass/encoding_test.rb +219 -0
- data/test/sass/engine_test.rb +3400 -0
- data/test/sass/exec_test.rb +86 -0
- data/test/sass/extend_test.rb +1719 -0
- data/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
- data/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
- data/test/sass/functions_test.rb +1984 -0
- data/test/sass/importer_test.rb +421 -0
- data/test/sass/logger_test.rb +58 -0
- data/test/sass/mock_importer.rb +49 -0
- data/test/sass/more_results/more1.css +9 -0
- data/test/sass/more_results/more1_with_line_comments.css +26 -0
- data/test/sass/more_results/more_import.css +29 -0
- data/test/sass/more_templates/_more_partial.sass +2 -0
- data/test/sass/more_templates/more1.sass +23 -0
- data/test/sass/more_templates/more_import.sass +11 -0
- data/test/sass/plugin_test.rb +556 -0
- data/test/sass/results/alt.css +4 -0
- data/test/sass/results/basic.css +9 -0
- data/test/sass/results/cached_import_option.css +3 -0
- data/test/sass/results/compact.css +5 -0
- data/test/sass/results/complex.css +86 -0
- data/test/sass/results/compressed.css +1 -0
- data/test/sass/results/expanded.css +19 -0
- data/test/sass/results/filename_fn.css +3 -0
- data/test/sass/results/if.css +3 -0
- data/test/sass/results/import.css +31 -0
- data/test/sass/results/import_charset.css +5 -0
- data/test/sass/results/import_charset_1_8.css +5 -0
- data/test/sass/results/import_charset_ibm866.css +5 -0
- data/test/sass/results/import_content.css +1 -0
- data/test/sass/results/line_numbers.css +49 -0
- data/test/sass/results/mixins.css +95 -0
- data/test/sass/results/multiline.css +24 -0
- data/test/sass/results/nested.css +22 -0
- data/test/sass/results/options.css +1 -0
- data/test/sass/results/parent_ref.css +13 -0
- data/test/sass/results/script.css +16 -0
- data/test/sass/results/scss_import.css +31 -0
- data/test/sass/results/scss_importee.css +2 -0
- data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
- data/test/sass/results/subdir/subdir.css +3 -0
- data/test/sass/results/units.css +11 -0
- data/test/sass/results/warn.css +0 -0
- data/test/sass/results/warn_imported.css +0 -0
- data/test/sass/script_conversion_test.rb +306 -0
- data/test/sass/script_test.rb +1206 -0
- data/test/sass/scss/css_test.rb +1281 -0
- data/test/sass/scss/rx_test.rb +160 -0
- data/test/sass/scss/scss_test.rb +4147 -0
- data/test/sass/scss/test_helper.rb +37 -0
- data/test/sass/source_map_test.rb +1055 -0
- data/test/sass/superselector_test.rb +210 -0
- data/test/sass/templates/_cached_import_option_partial.scss +1 -0
- data/test/sass/templates/_double_import_loop2.sass +1 -0
- data/test/sass/templates/_filename_fn_import.scss +11 -0
- data/test/sass/templates/_imported_charset_ibm866.sass +4 -0
- data/test/sass/templates/_imported_charset_utf8.sass +4 -0
- data/test/sass/templates/_imported_content.sass +3 -0
- data/test/sass/templates/_partial.sass +2 -0
- data/test/sass/templates/_same_name_different_partiality.scss +1 -0
- data/test/sass/templates/alt.sass +16 -0
- data/test/sass/templates/basic.sass +23 -0
- data/test/sass/templates/bork1.sass +2 -0
- data/test/sass/templates/bork2.sass +2 -0
- data/test/sass/templates/bork3.sass +2 -0
- data/test/sass/templates/bork4.sass +2 -0
- data/test/sass/templates/bork5.sass +3 -0
- data/test/sass/templates/cached_import_option.scss +3 -0
- data/test/sass/templates/compact.sass +17 -0
- data/test/sass/templates/complex.sass +305 -0
- data/test/sass/templates/compressed.sass +15 -0
- data/test/sass/templates/double_import_loop1.sass +1 -0
- data/test/sass/templates/expanded.sass +17 -0
- data/test/sass/templates/filename_fn.scss +18 -0
- data/test/sass/templates/if.sass +11 -0
- data/test/sass/templates/import.sass +12 -0
- data/test/sass/templates/import_charset.sass +9 -0
- data/test/sass/templates/import_charset_1_8.sass +6 -0
- data/test/sass/templates/import_charset_ibm866.sass +11 -0
- data/test/sass/templates/import_content.sass +4 -0
- data/test/sass/templates/importee.less +2 -0
- data/test/sass/templates/importee.sass +19 -0
- data/test/sass/templates/line_numbers.sass +13 -0
- data/test/sass/templates/mixin_bork.sass +5 -0
- data/test/sass/templates/mixins.sass +76 -0
- data/test/sass/templates/multiline.sass +20 -0
- data/test/sass/templates/nested.sass +25 -0
- data/test/sass/templates/nested_bork1.sass +2 -0
- data/test/sass/templates/nested_bork2.sass +2 -0
- data/test/sass/templates/nested_bork3.sass +2 -0
- data/test/sass/templates/nested_bork4.sass +2 -0
- data/test/sass/templates/nested_import.sass +2 -0
- data/test/sass/templates/nested_mixin_bork.sass +6 -0
- data/test/sass/templates/options.sass +2 -0
- data/test/sass/templates/parent_ref.sass +25 -0
- data/test/sass/templates/same_name_different_ext.sass +2 -0
- data/test/sass/templates/same_name_different_ext.scss +1 -0
- data/test/sass/templates/same_name_different_partiality.scss +1 -0
- data/test/sass/templates/script.sass +101 -0
- data/test/sass/templates/scss_import.scss +12 -0
- data/test/sass/templates/scss_importee.scss +1 -0
- data/test/sass/templates/single_import_loop.sass +1 -0
- data/test/sass/templates/subdir/import_up1.scss +1 -0
- data/test/sass/templates/subdir/import_up2.scss +1 -0
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
- data/test/sass/templates/subdir/subdir.sass +6 -0
- data/test/sass/templates/units.sass +11 -0
- data/test/sass/templates/warn.sass +3 -0
- data/test/sass/templates/warn_imported.sass +4 -0
- data/test/sass/test_helper.rb +8 -0
- data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
- data/test/sass/util/normalized_map_test.rb +51 -0
- data/test/sass/util/subset_map_test.rb +91 -0
- data/test/sass/util_test.rb +438 -0
- data/test/sass/value_helpers_test.rb +179 -0
- data/test/test_helper.rb +110 -0
- data/vendor/listen/CHANGELOG.md +1 -0
- data/vendor/listen/CONTRIBUTING.md +38 -0
- data/vendor/listen/Gemfile +20 -0
- data/vendor/listen/Guardfile +8 -0
- data/vendor/listen/LICENSE +20 -0
- data/vendor/listen/README.md +349 -0
- data/vendor/listen/Rakefile +5 -0
- data/vendor/listen/Vagrantfile +96 -0
- data/vendor/listen/lib/listen.rb +54 -0
- data/vendor/listen/lib/listen/adapter.rb +327 -0
- data/vendor/listen/lib/listen/adapters/bsd.rb +75 -0
- data/vendor/listen/lib/listen/adapters/darwin.rb +48 -0
- data/vendor/listen/lib/listen/adapters/linux.rb +81 -0
- data/vendor/listen/lib/listen/adapters/polling.rb +58 -0
- data/vendor/listen/lib/listen/adapters/windows.rb +91 -0
- data/vendor/listen/lib/listen/directory_record.rb +406 -0
- data/vendor/listen/lib/listen/listener.rb +323 -0
- data/vendor/listen/lib/listen/turnstile.rb +32 -0
- data/vendor/listen/lib/listen/version.rb +3 -0
- data/vendor/listen/listen.gemspec +28 -0
- data/vendor/listen/spec/listen/adapter_spec.rb +149 -0
- data/vendor/listen/spec/listen/adapters/bsd_spec.rb +36 -0
- data/vendor/listen/spec/listen/adapters/darwin_spec.rb +37 -0
- data/vendor/listen/spec/listen/adapters/linux_spec.rb +47 -0
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +68 -0
- data/vendor/listen/spec/listen/adapters/windows_spec.rb +30 -0
- data/vendor/listen/spec/listen/directory_record_spec.rb +1250 -0
- data/vendor/listen/spec/listen/listener_spec.rb +258 -0
- data/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
- data/vendor/listen/spec/listen_spec.rb +67 -0
- data/vendor/listen/spec/spec_helper.rb +25 -0
- data/vendor/listen/spec/support/adapter_helper.rb +666 -0
- data/vendor/listen/spec/support/directory_record_helper.rb +57 -0
- data/vendor/listen/spec/support/fixtures_helper.rb +29 -0
- data/vendor/listen/spec/support/listeners_helper.rb +179 -0
- data/vendor/listen/spec/support/platform_helper.rb +15 -0
- metadata +217 -76
- data/extra/sass-spec-ref.sh +0 -40
- data/lib/sass/deprecation.rb +0 -55
- data/lib/sass/logger/delayed.rb +0 -50
- data/lib/sass/script/value/callable.rb +0 -25
- data/lib/sass/script/value/function.rb +0 -19
@@ -49,14 +49,14 @@ module Sass::Script::Tree
|
|
49
49
|
# @see Node#_perform
|
50
50
|
def _perform(environment)
|
51
51
|
keys = Set.new
|
52
|
-
map = Sass::Script::Value::Map.new(
|
52
|
+
map = Sass::Script::Value::Map.new(Sass::Util.to_hash(pairs.map do |(k, v)|
|
53
53
|
k, v = k.perform(environment), v.perform(environment)
|
54
54
|
if keys.include?(k)
|
55
55
|
raise Sass::SyntaxError.new("Duplicate key #{k.inspect} in map #{to_sass}.")
|
56
56
|
end
|
57
57
|
keys << k
|
58
58
|
[k, v]
|
59
|
-
end
|
59
|
+
end))
|
60
60
|
map.options = options
|
61
61
|
map
|
62
62
|
end
|
@@ -10,7 +10,7 @@ module Sass::Script::Tree
|
|
10
10
|
|
11
11
|
# The line of the document on which this node appeared.
|
12
12
|
#
|
13
|
-
# @return [
|
13
|
+
# @return [Fixnum]
|
14
14
|
attr_accessor :line
|
15
15
|
|
16
16
|
# The source range in the document on which this node appeared.
|
@@ -25,7 +25,7 @@ module Sass::Script::Tree
|
|
25
25
|
|
26
26
|
# Sets the options hash for this node,
|
27
27
|
# as well as for all child nodes.
|
28
|
-
# See {file:SASS_REFERENCE.md#
|
28
|
+
# See {file:SASS_REFERENCE.md#options the Sass options documentation}.
|
29
29
|
#
|
30
30
|
# @param options [{Symbol => Object}] The options
|
31
31
|
def options=(options)
|
@@ -90,7 +90,7 @@ module Sass::Script::Tree
|
|
90
90
|
# Converts underscores to dashes if the :dasherize option is set.
|
91
91
|
def dasherize(s, opts)
|
92
92
|
if opts[:dasherize]
|
93
|
-
s.
|
93
|
+
s.gsub(/_/, '-')
|
94
94
|
else
|
95
95
|
s
|
96
96
|
end
|
@@ -2,9 +2,6 @@ module Sass::Script::Tree
|
|
2
2
|
# A SassScript parse node representing a binary operation,
|
3
3
|
# such as `$a + $b` or `"foo" + 1`.
|
4
4
|
class Operation < Node
|
5
|
-
@@color_arithmetic_deprecation = Sass::Deprecation.new
|
6
|
-
@@unitless_equals_deprecation = Sass::Deprecation.new
|
7
|
-
|
8
5
|
attr_reader :operand1
|
9
6
|
attr_reader :operand2
|
10
7
|
attr_reader :operator
|
@@ -88,52 +85,28 @@ module Sass::Script::Tree
|
|
88
85
|
raise Sass::SyntaxError.new("Undefined operation: \"#{value1} #{@operator} #{value2}\".")
|
89
86
|
end
|
90
87
|
|
91
|
-
|
92
|
-
|
88
|
+
if (@operator == :eq || @operator == :neq) && value1.is_a?(Sass::Script::Value::Number) &&
|
89
|
+
value2.is_a?(Sass::Script::Value::Number) && value1.unitless? != value2.unitless? &&
|
90
|
+
result == (if @operator == :eq
|
91
|
+
Sass::Script::Value::Bool::TRUE
|
92
|
+
else
|
93
|
+
Sass::Script::Value::Bool::FALSE
|
94
|
+
end)
|
95
|
+
|
96
|
+
operation = "#{value1} #{@operator == :eq ? '==' : '!='} #{value2}"
|
97
|
+
future_value = @operator == :neq
|
98
|
+
Sass::Util.sass_warn <<WARNING
|
99
|
+
DEPRECATION WARNING on line #{line}#{" of #{filename}" if filename}:
|
100
|
+
The result of `#{operation}` will be `#{future_value}` in future releases of Sass.
|
101
|
+
Unitless numbers will no longer be equal to the same numbers with units.
|
102
|
+
WARNING
|
103
|
+
end
|
93
104
|
|
94
105
|
result
|
95
106
|
end
|
96
107
|
|
97
108
|
private
|
98
109
|
|
99
|
-
def warn_for_color_arithmetic(value1, value2)
|
100
|
-
return unless @operator == :plus || @operator == :times || @operator == :minus ||
|
101
|
-
@operator == :div || @operator == :mod
|
102
|
-
|
103
|
-
if value1.is_a?(Sass::Script::Value::Number)
|
104
|
-
return unless value2.is_a?(Sass::Script::Value::Color)
|
105
|
-
elsif value1.is_a?(Sass::Script::Value::Color)
|
106
|
-
return unless value2.is_a?(Sass::Script::Value::Color) || value2.is_a?(Sass::Script::Value::Number)
|
107
|
-
else
|
108
|
-
return
|
109
|
-
end
|
110
|
-
|
111
|
-
@@color_arithmetic_deprecation.warn(filename, line, <<WARNING)
|
112
|
-
The operation `#{value1} #{@operator} #{value2}` is deprecated and will be an error in future versions.
|
113
|
-
Consider using Sass's color functions instead.
|
114
|
-
https://sass-lang.com/documentation/Sass/Script/Functions.html#other_color_functions
|
115
|
-
WARNING
|
116
|
-
end
|
117
|
-
|
118
|
-
def warn_for_unitless_equals(value1, value2, result)
|
119
|
-
return unless @operator == :eq || @operator == :neq
|
120
|
-
return unless value1.is_a?(Sass::Script::Value::Number)
|
121
|
-
return unless value2.is_a?(Sass::Script::Value::Number)
|
122
|
-
return unless value1.unitless? != value2.unitless?
|
123
|
-
return unless result == (if @operator == :eq
|
124
|
-
Sass::Script::Value::Bool::TRUE
|
125
|
-
else
|
126
|
-
Sass::Script::Value::Bool::FALSE
|
127
|
-
end)
|
128
|
-
|
129
|
-
operation = "#{value1.to_sass} #{@operator == :eq ? '==' : '!='} #{value2.to_sass}"
|
130
|
-
future_value = @operator == :neq
|
131
|
-
@@unitless_equals_deprecation.warn(filename, line, <<WARNING)
|
132
|
-
The result of `#{operation}` will be `#{future_value}` in future releases of Sass.
|
133
|
-
Unitless numbers will no longer be equal to the same numbers with units.
|
134
|
-
WARNING
|
135
|
-
end
|
136
|
-
|
137
110
|
def operand_to_sass(op, side, opts)
|
138
111
|
return "(#{op.to_sass(opts)})" if op.is_a?(Sass::Script::Tree::ListLiteral)
|
139
112
|
return op.to_sass(opts) unless op.is_a?(Operation)
|
@@ -3,15 +3,9 @@ module Sass::Script::Tree
|
|
3
3
|
#
|
4
4
|
# @see Interpolation
|
5
5
|
class StringInterpolation < Node
|
6
|
-
# @return [
|
7
|
-
|
8
|
-
|
9
|
-
# @return [Node] The SassScript within the interpolation
|
10
|
-
attr_reader :mid
|
11
|
-
|
12
|
-
# @return [StringInterpolation, Literal]
|
13
|
-
# The string literal or string interpolation before this interpolation.
|
14
|
-
attr_reader :after
|
6
|
+
# @return [[Node, String]] The contents of the interpolation. Strings are
|
7
|
+
# literal text, nodes are interpolated segments.
|
8
|
+
attr_reader :contents
|
15
9
|
|
16
10
|
# Whether this is a CSS string or a CSS identifier. The difference is that
|
17
11
|
# strings are written with double-quotes, while identifiers aren't.
|
@@ -20,62 +14,56 @@ module Sass::Script::Tree
|
|
20
14
|
# functions such as `url()`.
|
21
15
|
#
|
22
16
|
# @return [Symbol] `:string` or `:identifier`
|
23
|
-
|
24
|
-
@before.value.type
|
25
|
-
end
|
17
|
+
attr_reader :type
|
26
18
|
|
27
|
-
#
|
28
|
-
# representation of this interpolation.
|
29
|
-
def quote
|
30
|
-
quote_for(self) || '"'
|
31
|
-
end
|
32
|
-
|
33
|
-
# Interpolation in a string is of the form `"before #{mid} after"`,
|
34
|
-
# where `before` and `after` may include more interpolation.
|
19
|
+
# Interpolation in a string.
|
35
20
|
#
|
36
|
-
# @param
|
37
|
-
# @param
|
38
|
-
|
39
|
-
|
40
|
-
@
|
41
|
-
@mid = mid
|
42
|
-
@after = after
|
21
|
+
# @param contents [[Node, String]] See {StringInterpolation#contents}
|
22
|
+
# @param type [Symbol] See {StringInterpolation#type}
|
23
|
+
def initialize(contents, type = :string)
|
24
|
+
@contents = Sass::Util.merge_adjacent_strings(contents)
|
25
|
+
@type = type
|
43
26
|
end
|
44
27
|
|
45
28
|
# @return [String] A human-readable s-expression representation of the interpolation
|
46
29
|
def inspect
|
47
|
-
"(string_interpolation #{@
|
30
|
+
"(string_interpolation #{@type.inspect} #{contents.map {|c| c.inspect}.join(', ')})"
|
48
31
|
end
|
49
32
|
|
50
33
|
# @see Node#to_sass
|
51
34
|
def to_sass(opts = {})
|
52
|
-
quote = type == :string ? opts[:quote] ||
|
35
|
+
quote = type == :string ? opts[:quote] || detected_quote : :none
|
53
36
|
opts = opts.merge(:quote => quote)
|
54
37
|
|
55
38
|
res = ""
|
56
39
|
res << quote if quote != :none
|
57
|
-
|
58
|
-
|
59
|
-
|
40
|
+
contents.each do |c|
|
41
|
+
if c.is_a?(String)
|
42
|
+
c = Sass::Script::Value::String.quote(c, opts).slice(1...-1) if quote != :none
|
43
|
+
res << c
|
44
|
+
else
|
45
|
+
res << '#{' << c.to_sass(opts.merge(:quote => nil)) << '}'
|
46
|
+
end
|
47
|
+
end
|
60
48
|
res << quote if quote != :none
|
61
49
|
res
|
62
50
|
end
|
63
51
|
|
64
|
-
# Returns the
|
52
|
+
# Returns the node contents of this interpolation.
|
65
53
|
#
|
66
54
|
# @return [Array<Node>]
|
67
55
|
# @see #initialize
|
68
56
|
# @see Node#children
|
69
57
|
def children
|
70
|
-
|
58
|
+
contents.select {|c| c.is_a?(Sass::Script::Tree::Node)}
|
71
59
|
end
|
72
60
|
|
73
61
|
# @see Node#deep_copy
|
74
62
|
def deep_copy
|
75
63
|
node = dup
|
76
|
-
node.instance_variable_set('@
|
77
|
-
|
78
|
-
|
64
|
+
node.instance_variable_set('@contents', contents.map do |c|
|
65
|
+
c.is_a?(String) ? c : c.deep_copy
|
66
|
+
end)
|
79
67
|
node
|
80
68
|
end
|
81
69
|
|
@@ -87,39 +75,30 @@ module Sass::Script::Tree
|
|
87
75
|
# @return [Sass::Script::Value::String]
|
88
76
|
# The SassScript string that is the value of the interpolation
|
89
77
|
def _perform(environment)
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
res << @after.perform(environment).value
|
96
|
-
opts(Sass::Script::Value::String.new(res, before.type))
|
78
|
+
opts(Sass::Script::Value::String.new(contents.map do |c|
|
79
|
+
next c if c.is_a?(String)
|
80
|
+
value = c.perform(environment)
|
81
|
+
value.is_a?(Sass::Script::Value::String) ? value.value : value.to_s(:quote => :none)
|
82
|
+
end.join, type))
|
97
83
|
end
|
98
84
|
|
99
85
|
private
|
100
86
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
return
|
87
|
+
# Returns the best quote to use for this interpolation.
|
88
|
+
#
|
89
|
+
# @return [String]
|
90
|
+
def detected_quote
|
91
|
+
has_double_quote = false
|
92
|
+
contents.each do |c|
|
93
|
+
next if c.is_a?(Sass::Script::Tree::Node)
|
94
|
+
|
95
|
+
# Double-quotes take precedence over single quotes, so if any string contains
|
96
|
+
# a single quote we'll definitely end up using double quotes.
|
97
|
+
return '"' if c.include?("'")
|
98
|
+
has_double_quote ||= c.include?('"')
|
112
99
|
end
|
113
100
|
|
114
|
-
|
115
|
-
before_quote = quote_for(string_or_interp.before)
|
116
|
-
return '"' if before_quote == '"'
|
117
|
-
after_quote = quote_for(string_or_interp.after)
|
118
|
-
return '"' if after_quote == '"'
|
119
|
-
|
120
|
-
# Returns "'" if either or both insist on single quotes, and nil
|
121
|
-
# otherwise.
|
122
|
-
before_quote || after_quote
|
101
|
+
has_double_quote ? "'" : '"'
|
123
102
|
end
|
124
103
|
end
|
125
104
|
end
|
data/lib/sass/script/value.rb
CHANGED
@@ -17,7 +17,7 @@ module Sass::Script::Value
|
|
17
17
|
# @param keywords [Hash<String, Value>, NormalizedMap<Value>] See \{#keywords}
|
18
18
|
# @param separator [String] See \{List#separator}.
|
19
19
|
def initialize(value, keywords, separator)
|
20
|
-
super(value, separator
|
20
|
+
super(value, separator)
|
21
21
|
if keywords.is_a?(Sass::Util::NormalizedMap)
|
22
22
|
@keywords = keywords
|
23
23
|
else
|
@@ -22,12 +22,11 @@ module Sass::Script::Value
|
|
22
22
|
def initialize(value = nil)
|
23
23
|
value.freeze unless value.nil? || value == true || value == false
|
24
24
|
@value = value
|
25
|
-
@options = nil
|
26
25
|
end
|
27
26
|
|
28
27
|
# Sets the options hash for this node,
|
29
28
|
# as well as for all child nodes.
|
30
|
-
# See {file:SASS_REFERENCE.md#
|
29
|
+
# See {file:SASS_REFERENCE.md#options the Sass options documentation}.
|
31
30
|
#
|
32
31
|
# @param options [{Symbol => Object}] The options
|
33
32
|
attr_writer :options
|
@@ -88,7 +87,7 @@ MSG
|
|
88
87
|
# @return [Script::Value::String] A string containing both values
|
89
88
|
# separated by `"="`
|
90
89
|
def single_eq(other)
|
91
|
-
Sass::Script::Value::String.new("#{
|
90
|
+
Sass::Script::Value::String.new("#{to_s}=#{other.to_s}")
|
92
91
|
end
|
93
92
|
|
94
93
|
# The SassScript `+` operation.
|
@@ -107,7 +106,7 @@ MSG
|
|
107
106
|
# @return [Script::Value::String] A string containing both values
|
108
107
|
# separated by `"-"`
|
109
108
|
def minus(other)
|
110
|
-
Sass::Script::Value::String.new("#{
|
109
|
+
Sass::Script::Value::String.new("#{to_s}-#{other.to_s}")
|
111
110
|
end
|
112
111
|
|
113
112
|
# The SassScript `/` operation.
|
@@ -116,7 +115,7 @@ MSG
|
|
116
115
|
# @return [Script::Value::String] A string containing both values
|
117
116
|
# separated by `"/"`
|
118
117
|
def div(other)
|
119
|
-
Sass::Script::Value::String.new("#{
|
118
|
+
Sass::Script::Value::String.new("#{to_s}/#{other.to_s}")
|
120
119
|
end
|
121
120
|
|
122
121
|
# The SassScript unary `+` operation (e.g. `+$a`).
|
@@ -125,7 +124,7 @@ MSG
|
|
125
124
|
# @return [Script::Value::String] A string containing the value
|
126
125
|
# preceded by `"+"`
|
127
126
|
def unary_plus
|
128
|
-
Sass::Script::Value::String.new("+#{
|
127
|
+
Sass::Script::Value::String.new("+#{to_s}")
|
129
128
|
end
|
130
129
|
|
131
130
|
# The SassScript unary `-` operation (e.g. `-$a`).
|
@@ -134,7 +133,7 @@ MSG
|
|
134
133
|
# @return [Script::Value::String] A string containing the value
|
135
134
|
# preceded by `"-"`
|
136
135
|
def unary_minus
|
137
|
-
Sass::Script::Value::String.new("-#{
|
136
|
+
Sass::Script::Value::String.new("-#{to_s}")
|
138
137
|
end
|
139
138
|
|
140
139
|
# The SassScript unary `/` operation (e.g. `/$a`).
|
@@ -143,13 +142,13 @@ MSG
|
|
143
142
|
# @return [Script::Value::String] A string containing the value
|
144
143
|
# preceded by `"/"`
|
145
144
|
def unary_div
|
146
|
-
Sass::Script::Value::String.new("/#{
|
145
|
+
Sass::Script::Value::String.new("/#{to_s}")
|
147
146
|
end
|
148
147
|
|
149
148
|
# Returns the hash code of this value. Two objects' hash codes should be
|
150
149
|
# equal if the objects are equal.
|
151
150
|
#
|
152
|
-
# @return [
|
151
|
+
# @return [Fixnum] The hash code.
|
153
152
|
def hash
|
154
153
|
value.hash
|
155
154
|
end
|
@@ -176,7 +175,7 @@ MSG
|
|
176
175
|
eq(other).to_bool
|
177
176
|
end
|
178
177
|
|
179
|
-
# @return [
|
178
|
+
# @return [Fixnum] The integer value of this value
|
180
179
|
# @raise [Sass::SyntaxError] if this value isn't an integer
|
181
180
|
def to_i
|
182
181
|
raise Sass::SyntaxError.new("#{inspect} is not an integer.")
|
@@ -192,12 +191,6 @@ MSG
|
|
192
191
|
# @return [Symbol]
|
193
192
|
def separator; nil; end
|
194
193
|
|
195
|
-
# Whether the value is surrounded by square brackets. For non-list values,
|
196
|
-
# this will be `false`.
|
197
|
-
#
|
198
|
-
# @return [Boolean]
|
199
|
-
def bracketed; false; end
|
200
|
-
|
201
194
|
# Returns the value of this value as a list.
|
202
195
|
# Single values are considered the same as single-element lists.
|
203
196
|
#
|
@@ -234,17 +227,6 @@ MSG
|
|
234
227
|
false
|
235
228
|
end
|
236
229
|
|
237
|
-
# Creates a new list containing `contents` but with the same brackets and
|
238
|
-
# separators as this object, when interpreted as a list.
|
239
|
-
#
|
240
|
-
# @param contents [Array<Value>] The contents of the new list.
|
241
|
-
# @param separator [Symbol] The separator of the new list. Defaults to \{#separator}.
|
242
|
-
# @param bracketed [Boolean] Whether the new list is bracketed. Defaults to \{#bracketed}.
|
243
|
-
# @return [Sass::Script::Value::List]
|
244
|
-
def with_contents(contents, separator: self.separator, bracketed: self.bracketed)
|
245
|
-
Sass::Script::Value::List.new(contents, separator: separator, bracketed: bracketed)
|
246
|
-
end
|
247
|
-
|
248
230
|
protected
|
249
231
|
|
250
232
|
# Evaluates the value.
|
@@ -17,16 +17,15 @@ module Sass::Script::Value
|
|
17
17
|
# @private
|
18
18
|
#
|
19
19
|
# Convert a ruby integer to a rgba components
|
20
|
-
# @param color [
|
21
|
-
# @return [Array<
|
20
|
+
# @param color [Fixnum]
|
21
|
+
# @return [Array<Fixnum>] Array of 4 numbers representing r,g,b and alpha
|
22
22
|
def self.int_to_rgba(color)
|
23
23
|
rgba = (0..3).map {|n| color >> (n << 3) & 0xff}.reverse
|
24
24
|
rgba[-1] = rgba[-1] / 255.0
|
25
25
|
rgba
|
26
26
|
end
|
27
27
|
|
28
|
-
ALTERNATE_COLOR_NAMES = Sass::Util.map_vals(
|
29
|
-
{
|
28
|
+
ALTERNATE_COLOR_NAMES = Sass::Util.map_vals({
|
30
29
|
'aqua' => 0x00FFFFFF,
|
31
30
|
'darkgrey' => 0xA9A9A9FF,
|
32
31
|
'darkslategrey' => 0x2F4F4FFF,
|
@@ -36,11 +35,10 @@ module Sass::Script::Value
|
|
36
35
|
'lightgrey' => 0xD3D3D3FF,
|
37
36
|
'lightslategrey' => 0x778899FF,
|
38
37
|
'slategrey' => 0x708090FF,
|
39
|
-
|
38
|
+
}, &method(:int_to_rgba))
|
40
39
|
|
41
40
|
# A hash from color names to `[red, green, blue]` value arrays.
|
42
|
-
COLOR_NAMES = Sass::Util.map_vals(
|
43
|
-
{
|
41
|
+
COLOR_NAMES = Sass::Util.map_vals({
|
44
42
|
'aliceblue' => 0xF0F8FFFF,
|
45
43
|
'antiquewhite' => 0xFAEBD7FF,
|
46
44
|
'aquamarine' => 0x7FFFD4FF,
|
@@ -181,7 +179,7 @@ module Sass::Script::Value
|
|
181
179
|
'whitesmoke' => 0xF5F5F5FF,
|
182
180
|
'yellow' => 0xFFFF00FF,
|
183
181
|
'yellowgreen' => 0x9ACD32FF
|
184
|
-
|
182
|
+
}, &method(:int_to_rgba))
|
185
183
|
|
186
184
|
# A hash from `[red, green, blue, alpha]` value arrays to color names.
|
187
185
|
COLOR_NAMES_REVERSE = COLOR_NAMES.invert.freeze
|
@@ -239,7 +237,7 @@ module Sass::Script::Value
|
|
239
237
|
@attrs[:alpha] = attrs[3] ? attrs[3].to_f : 1
|
240
238
|
@representation = representation
|
241
239
|
else
|
242
|
-
attrs = attrs.reject {|
|
240
|
+
attrs = attrs.reject {|k, v| v.nil?}
|
243
241
|
hsl = [:hue, :saturation, :lightness] & attrs.keys
|
244
242
|
rgb = [:red, :green, :blue] & attrs.keys
|
245
243
|
if !allow_both_rgb_and_hsl && !hsl.empty? && !rgb.empty?
|
@@ -277,14 +275,13 @@ module Sass::Script::Value
|
|
277
275
|
#
|
278
276
|
# @return [Color]
|
279
277
|
def self.from_hex(hex_string, alpha = nil)
|
280
|
-
unless hex_string =~ /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})
|
281
|
-
hex_string =~ /^#?([0-9a-f])([0-9a-f])([0-9a-f])
|
278
|
+
unless hex_string =~ /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i ||
|
279
|
+
hex_string =~ /^#?([0-9a-f])([0-9a-f])([0-9a-f])$/i
|
282
280
|
raise ArgumentError.new("#{hex_string.inspect} is not a valid hex color.")
|
283
281
|
end
|
284
282
|
red = $1.ljust(2, $1).to_i(16)
|
285
283
|
green = $2.ljust(2, $2).to_i(16)
|
286
284
|
blue = $3.ljust(2, $3).to_i(16)
|
287
|
-
alpha = $4.ljust(2, $4).to_i(16).to_f / 0xff if $4
|
288
285
|
|
289
286
|
hex_string = "##{hex_string}" unless hex_string[0] == ?#
|
290
287
|
attrs = {:red => red, :green => green, :blue => blue, :representation => hex_string}
|
@@ -294,7 +291,7 @@ module Sass::Script::Value
|
|
294
291
|
|
295
292
|
# The red component of the color.
|
296
293
|
#
|
297
|
-
# @return [
|
294
|
+
# @return [Fixnum]
|
298
295
|
def red
|
299
296
|
hsl_to_rgb!
|
300
297
|
@attrs[:red]
|
@@ -302,7 +299,7 @@ module Sass::Script::Value
|
|
302
299
|
|
303
300
|
# The green component of the color.
|
304
301
|
#
|
305
|
-
# @return [
|
302
|
+
# @return [Fixnum]
|
306
303
|
def green
|
307
304
|
hsl_to_rgb!
|
308
305
|
@attrs[:green]
|
@@ -310,7 +307,7 @@ module Sass::Script::Value
|
|
310
307
|
|
311
308
|
# The blue component of the color.
|
312
309
|
#
|
313
|
-
# @return [
|
310
|
+
# @return [Fixnum]
|
314
311
|
def blue
|
315
312
|
hsl_to_rgb!
|
316
313
|
@attrs[:blue]
|
@@ -343,7 +340,7 @@ module Sass::Script::Value
|
|
343
340
|
# The alpha channel (opacity) of the color.
|
344
341
|
# This is 1 unless otherwise defined.
|
345
342
|
#
|
346
|
-
# @return [
|
343
|
+
# @return [Fixnum]
|
347
344
|
def alpha
|
348
345
|
@attrs[:alpha].to_f
|
349
346
|
end
|
@@ -358,7 +355,7 @@ module Sass::Script::Value
|
|
358
355
|
|
359
356
|
# Returns the red, green, and blue components of the color.
|
360
357
|
#
|
361
|
-
# @return [Array<
|
358
|
+
# @return [Array<Fixnum>] A frozen three-element array of the red, green, and blue
|
362
359
|
# values (respectively) of the color
|
363
360
|
def rgb
|
364
361
|
[red, green, blue].freeze
|
@@ -366,7 +363,7 @@ module Sass::Script::Value
|
|
366
363
|
|
367
364
|
# Returns the red, green, blue, and alpha components of the color.
|
368
365
|
#
|
369
|
-
# @return [Array<
|
366
|
+
# @return [Array<Fixnum>] A frozen four-element array of the red, green,
|
370
367
|
# blue, and alpha values (respectively) of the color
|
371
368
|
def rgba
|
372
369
|
[red, green, blue, alpha].freeze
|
@@ -374,7 +371,7 @@ module Sass::Script::Value
|
|
374
371
|
|
375
372
|
# Returns the hue, saturation, and lightness components of the color.
|
376
373
|
#
|
377
|
-
# @return [Array<
|
374
|
+
# @return [Array<Fixnum>] A frozen three-element array of the
|
378
375
|
# hue, saturation, and lightness values (respectively) of the color
|
379
376
|
def hsl
|
380
377
|
[hue, saturation, lightness].freeze
|
@@ -382,7 +379,7 @@ module Sass::Script::Value
|
|
382
379
|
|
383
380
|
# Returns the hue, saturation, lightness, and alpha components of the color.
|
384
381
|
#
|
385
|
-
# @return [Array<
|
382
|
+
# @return [Array<Fixnum>] A frozen four-element array of the hue,
|
386
383
|
# saturation, lightness, and alpha values (respectively) of the color
|
387
384
|
def hsla
|
388
385
|
[hue, saturation, lightness, alpha].freeze
|
@@ -424,7 +421,7 @@ module Sass::Script::Value
|
|
424
421
|
# @return [Color] The new Color object
|
425
422
|
# @raise [ArgumentError] if both RGB and HSL keys are specified
|
426
423
|
def with(attrs)
|
427
|
-
attrs = attrs.reject {|
|
424
|
+
attrs = attrs.reject {|k, v| v.nil?}
|
428
425
|
hsl = !([:hue, :saturation, :lightness] & attrs.keys).empty?
|
429
426
|
rgb = !([:red, :green, :blue] & attrs.keys).empty?
|
430
427
|
if hsl && rgb
|
@@ -564,11 +561,6 @@ module Sass::Script::Value
|
|
564
561
|
def to_s(opts = {})
|
565
562
|
return smallest if options[:style] == :compressed
|
566
563
|
return representation if representation
|
567
|
-
|
568
|
-
# IE10 doesn't properly support the color name "transparent", so we emit
|
569
|
-
# generated transparent colors as rgba(0, 0, 0, 0) in favor of that. See
|
570
|
-
# #1782.
|
571
|
-
return rgba_str if Number.basically_equal?(alpha, 0)
|
572
564
|
return name if name
|
573
565
|
alpha? ? rgba_str : hex_str
|
574
566
|
end
|