sass 3.4.25 → 3.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CODE_OF_CONDUCT.md +1 -1
- data/CONTRIBUTING.md +3 -3
- data/README.md +17 -9
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/extra/sass-spec-ref.sh +9 -1
- data/lib/sass.rb +0 -7
- data/lib/sass/cache_stores/filesystem.rb +1 -1
- data/lib/sass/css.rb +1 -2
- data/lib/sass/engine.rb +39 -29
- data/lib/sass/environment.rb +26 -5
- data/lib/sass/error.rb +2 -2
- data/lib/sass/exec/base.rb +2 -13
- data/lib/sass/exec/sass_scss.rb +1 -5
- data/lib/sass/features.rb +1 -0
- data/lib/sass/importers/filesystem.rb +6 -4
- data/lib/sass/logger/base.rb +11 -0
- data/lib/sass/plugin/compiler.rb +20 -50
- data/lib/sass/plugin/configuration.rb +2 -2
- data/lib/sass/railtie.rb +1 -1
- data/lib/sass/script/css_parser.rb +4 -1
- data/lib/sass/script/functions.rb +308 -81
- data/lib/sass/script/lexer.rb +63 -9
- data/lib/sass/script/parser.rb +287 -118
- data/lib/sass/script/tree/funcall.rb +35 -34
- data/lib/sass/script/tree/interpolation.rb +0 -3
- data/lib/sass/script/tree/list_literal.rb +23 -8
- data/lib/sass/script/tree/map_literal.rb +2 -2
- data/lib/sass/script/tree/node.rb +0 -8
- data/lib/sass/script/tree/operation.rb +1 -8
- data/lib/sass/script/value.rb +2 -0
- data/lib/sass/script/value/arg_list.rb +1 -1
- data/lib/sass/script/value/base.rb +17 -0
- data/lib/sass/script/value/callable.rb +25 -0
- data/lib/sass/script/value/color.rb +8 -2
- data/lib/sass/script/value/function.rb +19 -0
- data/lib/sass/script/value/helpers.rb +37 -11
- data/lib/sass/script/value/list.rb +35 -14
- data/lib/sass/script/value/map.rb +2 -2
- data/lib/sass/script/value/number.rb +3 -2
- data/lib/sass/scss/css_parser.rb +6 -1
- data/lib/sass/scss/parser.rb +145 -56
- data/lib/sass/scss/rx.rb +5 -11
- data/lib/sass/scss/static_parser.rb +20 -42
- data/lib/sass/selector.rb +4 -0
- data/lib/sass/selector/abstract_sequence.rb +7 -6
- data/lib/sass/selector/comma_sequence.rb +9 -5
- data/lib/sass/selector/pseudo.rb +20 -3
- data/lib/sass/selector/sequence.rb +35 -10
- data/lib/sass/selector/simple.rb +9 -2
- data/lib/sass/selector/simple_sequence.rb +8 -4
- data/lib/sass/source/map.rb +2 -6
- data/lib/sass/stack.rb +21 -1
- data/lib/sass/tree/charset_node.rb +1 -1
- data/lib/sass/tree/prop_node.rb +45 -53
- data/lib/sass/tree/rule_node.rb +6 -8
- data/lib/sass/tree/visitors/check_nesting.rb +1 -1
- data/lib/sass/tree/visitors/convert.rb +2 -3
- data/lib/sass/tree/visitors/cssize.rb +4 -15
- data/lib/sass/tree/visitors/deep_copy.rb +1 -1
- data/lib/sass/tree/visitors/extend.rb +2 -8
- data/lib/sass/tree/visitors/perform.rb +23 -15
- data/lib/sass/tree/visitors/set_options.rb +1 -1
- data/lib/sass/tree/visitors/to_css.rb +49 -22
- data/lib/sass/util.rb +72 -310
- data/lib/sass/util/multibyte_string_scanner.rb +127 -131
- data/lib/sass/util/normalized_map.rb +1 -8
- data/lib/sass/version.rb +0 -4
- metadata +55 -202
- data/Rakefile +0 -453
- data/lib/sass/script/css_variable_warning.rb +0 -52
- data/lib/sass/util/cross_platform_random.rb +0 -19
- data/lib/sass/util/ordered_hash.rb +0 -192
- data/test/sass-spec.yml +0 -3
- data/test/sass/cache_test.rb +0 -131
- data/test/sass/callbacks_test.rb +0 -61
- data/test/sass/compiler_test.rb +0 -236
- data/test/sass/conversion_test.rb +0 -2188
- data/test/sass/css2sass_test.rb +0 -526
- data/test/sass/css_variable_test.rb +0 -132
- data/test/sass/data/hsl-rgb.txt +0 -319
- data/test/sass/encoding_test.rb +0 -219
- data/test/sass/engine_test.rb +0 -3447
- data/test/sass/exec_test.rb +0 -96
- data/test/sass/extend_test.rb +0 -1733
- data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
- data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
- data/test/sass/functions_test.rb +0 -1977
- data/test/sass/importer_test.rb +0 -421
- data/test/sass/logger_test.rb +0 -58
- data/test/sass/mock_importer.rb +0 -49
- data/test/sass/more_results/more1.css +0 -9
- data/test/sass/more_results/more1_with_line_comments.css +0 -26
- data/test/sass/more_results/more_import.css +0 -29
- data/test/sass/more_templates/_more_partial.sass +0 -2
- data/test/sass/more_templates/more1.sass +0 -23
- data/test/sass/more_templates/more_import.sass +0 -11
- data/test/sass/plugin_test.rb +0 -556
- data/test/sass/results/alt.css +0 -4
- data/test/sass/results/basic.css +0 -9
- data/test/sass/results/cached_import_option.css +0 -3
- data/test/sass/results/compact.css +0 -5
- data/test/sass/results/complex.css +0 -86
- data/test/sass/results/compressed.css +0 -1
- data/test/sass/results/expanded.css +0 -19
- data/test/sass/results/filename_fn.css +0 -3
- data/test/sass/results/if.css +0 -3
- data/test/sass/results/import.css +0 -31
- data/test/sass/results/import_charset.css +0 -5
- data/test/sass/results/import_charset_1_8.css +0 -5
- data/test/sass/results/import_charset_ibm866.css +0 -5
- data/test/sass/results/import_content.css +0 -1
- data/test/sass/results/line_numbers.css +0 -49
- data/test/sass/results/mixins.css +0 -95
- data/test/sass/results/multiline.css +0 -24
- data/test/sass/results/nested.css +0 -22
- data/test/sass/results/options.css +0 -1
- data/test/sass/results/parent_ref.css +0 -13
- data/test/sass/results/script.css +0 -16
- data/test/sass/results/scss_import.css +0 -31
- data/test/sass/results/scss_importee.css +0 -2
- data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
- data/test/sass/results/subdir/subdir.css +0 -3
- data/test/sass/results/units.css +0 -11
- data/test/sass/results/warn.css +0 -0
- data/test/sass/results/warn_imported.css +0 -0
- data/test/sass/script_conversion_test.rb +0 -357
- data/test/sass/script_test.rb +0 -1431
- data/test/sass/scss/css_test.rb +0 -1281
- data/test/sass/scss/rx_test.rb +0 -160
- data/test/sass/scss/scss_test.rb +0 -4205
- data/test/sass/scss/test_helper.rb +0 -37
- data/test/sass/source_map_test.rb +0 -1055
- data/test/sass/superselector_test.rb +0 -210
- data/test/sass/templates/_cached_import_option_partial.scss +0 -1
- data/test/sass/templates/_double_import_loop2.sass +0 -1
- data/test/sass/templates/_filename_fn_import.scss +0 -11
- data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
- data/test/sass/templates/_imported_charset_utf8.sass +0 -4
- data/test/sass/templates/_imported_content.sass +0 -3
- data/test/sass/templates/_partial.sass +0 -2
- data/test/sass/templates/_same_name_different_partiality.scss +0 -1
- data/test/sass/templates/alt.sass +0 -16
- data/test/sass/templates/basic.sass +0 -23
- data/test/sass/templates/bork1.sass +0 -2
- data/test/sass/templates/bork2.sass +0 -2
- data/test/sass/templates/bork3.sass +0 -2
- data/test/sass/templates/bork4.sass +0 -2
- data/test/sass/templates/bork5.sass +0 -3
- data/test/sass/templates/cached_import_option.scss +0 -3
- data/test/sass/templates/compact.sass +0 -17
- data/test/sass/templates/complex.sass +0 -305
- data/test/sass/templates/compressed.sass +0 -15
- data/test/sass/templates/double_import_loop1.sass +0 -1
- data/test/sass/templates/expanded.sass +0 -17
- data/test/sass/templates/filename_fn.scss +0 -18
- data/test/sass/templates/if.sass +0 -11
- data/test/sass/templates/import.sass +0 -12
- data/test/sass/templates/import_charset.sass +0 -9
- data/test/sass/templates/import_charset_1_8.sass +0 -6
- data/test/sass/templates/import_charset_ibm866.sass +0 -11
- data/test/sass/templates/import_content.sass +0 -4
- data/test/sass/templates/importee.less +0 -2
- data/test/sass/templates/importee.sass +0 -19
- data/test/sass/templates/line_numbers.sass +0 -13
- data/test/sass/templates/mixin_bork.sass +0 -5
- data/test/sass/templates/mixins.sass +0 -76
- data/test/sass/templates/multiline.sass +0 -20
- data/test/sass/templates/nested.sass +0 -25
- data/test/sass/templates/nested_bork1.sass +0 -2
- data/test/sass/templates/nested_bork2.sass +0 -2
- data/test/sass/templates/nested_bork3.sass +0 -2
- data/test/sass/templates/nested_bork4.sass +0 -2
- data/test/sass/templates/nested_import.sass +0 -2
- data/test/sass/templates/nested_mixin_bork.sass +0 -6
- data/test/sass/templates/options.sass +0 -2
- data/test/sass/templates/parent_ref.sass +0 -25
- data/test/sass/templates/same_name_different_ext.sass +0 -2
- data/test/sass/templates/same_name_different_ext.scss +0 -1
- data/test/sass/templates/same_name_different_partiality.scss +0 -1
- data/test/sass/templates/script.sass +0 -101
- data/test/sass/templates/scss_import.scss +0 -12
- data/test/sass/templates/scss_importee.scss +0 -1
- data/test/sass/templates/single_import_loop.sass +0 -1
- data/test/sass/templates/subdir/import_up1.scss +0 -1
- data/test/sass/templates/subdir/import_up2.scss +0 -1
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
- data/test/sass/templates/subdir/subdir.sass +0 -6
- data/test/sass/templates/units.sass +0 -11
- data/test/sass/templates/warn.sass +0 -3
- data/test/sass/templates/warn_imported.sass +0 -4
- data/test/sass/test_helper.rb +0 -8
- data/test/sass/util/multibyte_string_scanner_test.rb +0 -155
- data/test/sass/util/normalized_map_test.rb +0 -51
- data/test/sass/util/subset_map_test.rb +0 -91
- data/test/sass/util_test.rb +0 -438
- data/test/sass/value_helpers_test.rb +0 -179
- data/test/test_helper.rb +0 -110
- data/vendor/listen/CHANGELOG.md +0 -1
- data/vendor/listen/CONTRIBUTING.md +0 -38
- data/vendor/listen/Gemfile +0 -20
- data/vendor/listen/Guardfile +0 -8
- data/vendor/listen/LICENSE +0 -20
- data/vendor/listen/README.md +0 -349
- data/vendor/listen/Rakefile +0 -5
- data/vendor/listen/Vagrantfile +0 -96
- data/vendor/listen/lib/listen.rb +0 -54
- data/vendor/listen/lib/listen/adapter.rb +0 -327
- data/vendor/listen/lib/listen/adapters/bsd.rb +0 -75
- data/vendor/listen/lib/listen/adapters/darwin.rb +0 -48
- data/vendor/listen/lib/listen/adapters/linux.rb +0 -81
- data/vendor/listen/lib/listen/adapters/polling.rb +0 -58
- data/vendor/listen/lib/listen/adapters/windows.rb +0 -91
- data/vendor/listen/lib/listen/directory_record.rb +0 -406
- data/vendor/listen/lib/listen/listener.rb +0 -323
- data/vendor/listen/lib/listen/turnstile.rb +0 -32
- data/vendor/listen/lib/listen/version.rb +0 -3
- data/vendor/listen/listen.gemspec +0 -28
- data/vendor/listen/spec/listen/adapter_spec.rb +0 -149
- data/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
- data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -37
- data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -47
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
- data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -30
- data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1250
- data/vendor/listen/spec/listen/listener_spec.rb +0 -258
- data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
- data/vendor/listen/spec/listen_spec.rb +0 -67
- data/vendor/listen/spec/spec_helper.rb +0 -25
- data/vendor/listen/spec/support/adapter_helper.rb +0 -666
- data/vendor/listen/spec/support/directory_record_helper.rb +0 -57
- data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
- data/vendor/listen/spec/support/listeners_helper.rb +0 -179
- data/vendor/listen/spec/support/platform_helper.rb +0 -15
|
@@ -14,13 +14,20 @@ module Sass::Script::Value
|
|
|
14
14
|
# @return [Symbol]
|
|
15
15
|
attr_reader :separator
|
|
16
16
|
|
|
17
|
+
# Whether the list is surrounded by square brackets.
|
|
18
|
+
#
|
|
19
|
+
# @return [Boolean]
|
|
20
|
+
attr_reader :bracketed
|
|
21
|
+
|
|
17
22
|
# Creates a new list.
|
|
18
23
|
#
|
|
19
24
|
# @param value [Array<Value>] See \{#value}
|
|
20
25
|
# @param separator [Symbol] See \{#separator}
|
|
21
|
-
|
|
26
|
+
# @param bracketed [Boolean] See \{#bracketed}
|
|
27
|
+
def initialize(value, separator: nil, bracketed: false)
|
|
22
28
|
super(value)
|
|
23
29
|
@separator = separator
|
|
30
|
+
@bracketed = bracketed
|
|
24
31
|
end
|
|
25
32
|
|
|
26
33
|
# @see Value#options=
|
|
@@ -33,24 +40,30 @@ module Sass::Script::Value
|
|
|
33
40
|
def eq(other)
|
|
34
41
|
Sass::Script::Value::Bool.new(
|
|
35
42
|
other.is_a?(List) && value == other.value &&
|
|
36
|
-
separator == other.separator)
|
|
43
|
+
separator == other.separator && bracketed == other.bracketed)
|
|
37
44
|
end
|
|
38
45
|
|
|
39
46
|
def hash
|
|
40
|
-
@hash ||= [value, separator].hash
|
|
47
|
+
@hash ||= [value, separator, bracketed].hash
|
|
41
48
|
end
|
|
42
49
|
|
|
43
50
|
# @see Value#to_s
|
|
44
51
|
def to_s(opts = {})
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
if !bracketed && value.empty?
|
|
53
|
+
raise Sass::SyntaxError.new("#{inspect} isn't a valid CSS value.")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
members = value.
|
|
47
57
|
reject {|e| e.is_a?(Null) || e.is_a?(List) && e.value.empty?}.
|
|
48
|
-
map {|e| e.to_s(opts)}
|
|
58
|
+
map {|e| e.to_s(opts)}
|
|
59
|
+
|
|
60
|
+
contents = members.join(sep_str)
|
|
61
|
+
bracketed ? "[#{contents}]" : contents
|
|
49
62
|
end
|
|
50
63
|
|
|
51
64
|
# @see Value#to_sass
|
|
52
65
|
def to_sass(opts = {})
|
|
53
|
-
return "()" if value.empty?
|
|
66
|
+
return bracketed ? "[]" : "()" if value.empty?
|
|
54
67
|
members = value.map do |v|
|
|
55
68
|
if element_needs_parens?(v)
|
|
56
69
|
"(#{v.to_sass(opts)})"
|
|
@@ -58,19 +71,26 @@ module Sass::Script::Value
|
|
|
58
71
|
v.to_sass(opts)
|
|
59
72
|
end
|
|
60
73
|
end
|
|
61
|
-
|
|
62
|
-
members.
|
|
74
|
+
|
|
75
|
+
if separator == :comma && members.length == 1
|
|
76
|
+
return "#{bracketed ? '[' : '('}#{members.first},#{bracketed ? ']' : ')'}"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
contents = members.join(sep_str(nil))
|
|
80
|
+
bracketed ? "[#{contents}]" : contents
|
|
63
81
|
end
|
|
64
82
|
|
|
65
83
|
# @see Value#to_h
|
|
66
84
|
def to_h
|
|
67
|
-
return
|
|
85
|
+
return {} if value.empty?
|
|
68
86
|
super
|
|
69
87
|
end
|
|
70
88
|
|
|
71
89
|
# @see Value#inspect
|
|
72
90
|
def inspect
|
|
73
|
-
|
|
91
|
+
(bracketed ? '[' : '(') +
|
|
92
|
+
value.map {|e| e.inspect}.join(sep_str(nil)) +
|
|
93
|
+
(bracketed ? ']' : ')')
|
|
74
94
|
end
|
|
75
95
|
|
|
76
96
|
# Asserts an index is within the list.
|
|
@@ -94,9 +114,10 @@ module Sass::Script::Value
|
|
|
94
114
|
|
|
95
115
|
def element_needs_parens?(element)
|
|
96
116
|
if element.is_a?(List)
|
|
97
|
-
return false if element.value.
|
|
98
|
-
|
|
99
|
-
|
|
117
|
+
return false if element.value.length < 2
|
|
118
|
+
return false if element.bracketed
|
|
119
|
+
precedence = Sass::Script::Parser.precedence_of(separator || :space)
|
|
120
|
+
return Sass::Script::Parser.precedence_of(element.separator || :space) <= precedence
|
|
100
121
|
end
|
|
101
122
|
|
|
102
123
|
return false unless separator == :space
|
|
@@ -12,7 +12,7 @@ module Sass::Script::Value
|
|
|
12
12
|
#
|
|
13
13
|
# @param hash [Hash<Node, Node>]
|
|
14
14
|
def initialize(hash)
|
|
15
|
-
super(
|
|
15
|
+
super(hash)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
# @see Value#options=
|
|
@@ -32,7 +32,7 @@ module Sass::Script::Value
|
|
|
32
32
|
# @see Value#to_a
|
|
33
33
|
def to_a
|
|
34
34
|
value.map do |k, v|
|
|
35
|
-
list = List.new([k, v], :space)
|
|
35
|
+
list = List.new([k, v], separator: :space)
|
|
36
36
|
list.options = options
|
|
37
37
|
list
|
|
38
38
|
end
|
|
@@ -34,7 +34,7 @@ module Sass::Script::Value
|
|
|
34
34
|
attr_accessor :original
|
|
35
35
|
|
|
36
36
|
def self.precision
|
|
37
|
-
Thread.current[:sass_numeric_precision] || Thread.main[:sass_numeric_precision] ||
|
|
37
|
+
Thread.current[:sass_numeric_precision] || Thread.main[:sass_numeric_precision] || 10
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
# Sets the number of digits of precision
|
|
@@ -189,6 +189,7 @@ module Sass::Script::Value
|
|
|
189
189
|
# @raise [Sass::UnitConversionError] if `other` has incompatible units
|
|
190
190
|
def mod(other)
|
|
191
191
|
if other.is_a?(Number)
|
|
192
|
+
return Number.new(Float::NAN) if other.value == 0
|
|
192
193
|
operate(other, :%)
|
|
193
194
|
else
|
|
194
195
|
raise NoMethodError.new(nil, :mod)
|
|
@@ -472,7 +473,7 @@ module Sass::Script::Value
|
|
|
472
473
|
sans_common_units(@numerator_units, @denominator_units)
|
|
473
474
|
|
|
474
475
|
@denominator_units.each_with_index do |d, i|
|
|
475
|
-
next unless convertable?(d) && (u = @numerator_units.find
|
|
476
|
+
next unless convertable?(d) && (u = @numerator_units.find {|n| convertable?([n, d])})
|
|
476
477
|
@value /= conversion_factor(d, u)
|
|
477
478
|
@denominator_units.delete_at(i)
|
|
478
479
|
@numerator_units.delete_at(@numerator_units.index(u))
|
data/lib/sass/scss/css_parser.rb
CHANGED
|
@@ -47,7 +47,12 @@ module Sass
|
|
|
47
47
|
def keyframes_ruleset
|
|
48
48
|
start_pos = source_position
|
|
49
49
|
return unless (selector = keyframes_selector)
|
|
50
|
-
block(
|
|
50
|
+
block(
|
|
51
|
+
node(
|
|
52
|
+
Sass::Tree::KeyframeRuleNode.new(
|
|
53
|
+
Sass::Util.strip_except_escapes(selector)),
|
|
54
|
+
start_pos),
|
|
55
|
+
:ruleset)
|
|
51
56
|
end
|
|
52
57
|
|
|
53
58
|
@sass_script_parser = Sass::Script::CssParser
|
data/lib/sass/scss/parser.rb
CHANGED
|
@@ -99,6 +99,18 @@ module Sass
|
|
|
99
99
|
condition
|
|
100
100
|
end
|
|
101
101
|
|
|
102
|
+
# Parses a custom property value.
|
|
103
|
+
#
|
|
104
|
+
# @return [Array<String, Sass::Script;:Tree::Node>] The interpolated value.
|
|
105
|
+
# @raise [Sass::SyntaxError] if there's a syntax error in the value,
|
|
106
|
+
# or if it doesn't take up the entire input string.
|
|
107
|
+
def parse_declaration_value
|
|
108
|
+
init_scanner!
|
|
109
|
+
value = declaration_value
|
|
110
|
+
expected('"}"') unless value && @scanner.eos?
|
|
111
|
+
value
|
|
112
|
+
end
|
|
113
|
+
|
|
102
114
|
private
|
|
103
115
|
|
|
104
116
|
include Sass::SCSS::RX
|
|
@@ -191,7 +203,7 @@ module Sass
|
|
|
191
203
|
def directive
|
|
192
204
|
start_pos = source_position
|
|
193
205
|
return unless tok(/@/)
|
|
194
|
-
name =
|
|
206
|
+
name = ident!
|
|
195
207
|
ss
|
|
196
208
|
|
|
197
209
|
if (dir = special_directive(name, start_pos))
|
|
@@ -228,14 +240,14 @@ module Sass
|
|
|
228
240
|
end
|
|
229
241
|
|
|
230
242
|
def mixin_directive(start_pos)
|
|
231
|
-
name =
|
|
243
|
+
name = ident!
|
|
232
244
|
args, splat = sass_script(:parse_mixin_definition_arglist)
|
|
233
245
|
ss
|
|
234
246
|
block(node(Sass::Tree::MixinDefNode.new(name, args, splat), start_pos), :directive)
|
|
235
247
|
end
|
|
236
248
|
|
|
237
249
|
def include_directive(start_pos)
|
|
238
|
-
name =
|
|
250
|
+
name = ident!
|
|
239
251
|
args, keywords, splat, kwarg_splat = sass_script(:parse_mixin_include_arglist)
|
|
240
252
|
ss
|
|
241
253
|
include_node = node(
|
|
@@ -254,7 +266,7 @@ module Sass
|
|
|
254
266
|
end
|
|
255
267
|
|
|
256
268
|
def function_directive(start_pos)
|
|
257
|
-
name =
|
|
269
|
+
name = ident!
|
|
258
270
|
args, splat = sass_script(:parse_function_definition_arglist)
|
|
259
271
|
ss
|
|
260
272
|
block(node(Sass::Tree::FunctionNode.new(name, args, splat), start_pos), :function)
|
|
@@ -274,7 +286,7 @@ module Sass
|
|
|
274
286
|
|
|
275
287
|
def for_directive(start_pos)
|
|
276
288
|
tok!(/\$/)
|
|
277
|
-
var =
|
|
289
|
+
var = ident!
|
|
278
290
|
ss
|
|
279
291
|
|
|
280
292
|
tok!(/from/)
|
|
@@ -291,12 +303,12 @@ module Sass
|
|
|
291
303
|
|
|
292
304
|
def each_directive(start_pos)
|
|
293
305
|
tok!(/\$/)
|
|
294
|
-
vars = [
|
|
306
|
+
vars = [ident!]
|
|
295
307
|
ss
|
|
296
308
|
while tok(/,/)
|
|
297
309
|
ss
|
|
298
310
|
tok!(/\$/)
|
|
299
|
-
vars <<
|
|
311
|
+
vars << ident!
|
|
300
312
|
ss
|
|
301
313
|
end
|
|
302
314
|
|
|
@@ -465,12 +477,23 @@ module Sass
|
|
|
465
477
|
return unless tok(/\(/)
|
|
466
478
|
res = ['(']
|
|
467
479
|
ss
|
|
468
|
-
|
|
480
|
+
stop_at = Set[:single_eq, :lt, :lte, :gt, :gte]
|
|
481
|
+
res << sass_script(:parse_until, stop_at)
|
|
469
482
|
|
|
470
483
|
if tok(/:/)
|
|
471
484
|
res << ': '
|
|
472
485
|
ss
|
|
473
486
|
res << sass_script(:parse)
|
|
487
|
+
elsif comparison1 = tok(/=|[<>]=?/)
|
|
488
|
+
res << ' ' << comparison1 << ' '
|
|
489
|
+
ss
|
|
490
|
+
res << sass_script(:parse_until, stop_at)
|
|
491
|
+
if ((comparison1 == ">" || comparison1 == ">=") && comparison2 = tok(/>=?/)) ||
|
|
492
|
+
((comparison1 == "<" || comparison1 == "<=") && comparison2 = tok(/<=?/))
|
|
493
|
+
res << ' ' << comparison2 << ' '
|
|
494
|
+
ss
|
|
495
|
+
res << sass_script(:parse_until, stop_at)
|
|
496
|
+
end
|
|
474
497
|
end
|
|
475
498
|
res << tok!(/\)/)
|
|
476
499
|
ss
|
|
@@ -530,10 +553,10 @@ module Sass
|
|
|
530
553
|
end
|
|
531
554
|
|
|
532
555
|
def at_root_directive_list
|
|
533
|
-
return unless (first =
|
|
556
|
+
return unless (first = ident)
|
|
534
557
|
arr = [first]
|
|
535
558
|
ss
|
|
536
|
-
while (e =
|
|
559
|
+
while (e = ident)
|
|
537
560
|
arr << e
|
|
538
561
|
ss
|
|
539
562
|
end
|
|
@@ -624,12 +647,12 @@ module Sass
|
|
|
624
647
|
def variable
|
|
625
648
|
return unless tok(/\$/)
|
|
626
649
|
start_pos = source_position
|
|
627
|
-
name =
|
|
650
|
+
name = ident!
|
|
628
651
|
ss; tok!(/:/); ss
|
|
629
652
|
|
|
630
653
|
expr = sass_script(:parse)
|
|
631
654
|
while tok(/!/)
|
|
632
|
-
flag_name =
|
|
655
|
+
flag_name = ident!
|
|
633
656
|
if flag_name == 'default'
|
|
634
657
|
guarded ||= true
|
|
635
658
|
elsif flag_name == 'global'
|
|
@@ -767,6 +790,12 @@ module Sass
|
|
|
767
790
|
mid = [str {ss}]
|
|
768
791
|
return name + mid unless tok(/:/)
|
|
769
792
|
mid << ':'
|
|
793
|
+
|
|
794
|
+
# If this is a CSS variable, parse it as a property no matter what.
|
|
795
|
+
if name.first.is_a?(String) && name.first.start_with?("--")
|
|
796
|
+
return css_variable_declaration(name, name_start_pos, name_end_pos)
|
|
797
|
+
end
|
|
798
|
+
|
|
770
799
|
return name + mid + [':'] if tok(/:/)
|
|
771
800
|
mid << str {ss}
|
|
772
801
|
post_colon_whitespace = !mid.last.empty?
|
|
@@ -775,7 +804,7 @@ module Sass
|
|
|
775
804
|
value_start_pos = source_position
|
|
776
805
|
value = nil
|
|
777
806
|
error = catch_error do
|
|
778
|
-
value = value!
|
|
807
|
+
value = value!
|
|
779
808
|
if tok?(/\{/)
|
|
780
809
|
# Properties that are ambiguous with selectors can't have additional
|
|
781
810
|
# properties nested beneath them.
|
|
@@ -802,7 +831,7 @@ module Sass
|
|
|
802
831
|
ss
|
|
803
832
|
require_block = tok?(/\{/)
|
|
804
833
|
|
|
805
|
-
node = node(Sass::Tree::PropNode.new(name.flatten.compact, value, :new),
|
|
834
|
+
node = node(Sass::Tree::PropNode.new(name.flatten.compact, [value], :new),
|
|
806
835
|
name_start_pos, value_end_pos)
|
|
807
836
|
node.name_source_range = range(name_start_pos, name_end_pos)
|
|
808
837
|
node.value_source_range = range(value_start_pos, value_end_pos)
|
|
@@ -811,13 +840,21 @@ module Sass
|
|
|
811
840
|
nested_properties! node
|
|
812
841
|
end
|
|
813
842
|
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
843
|
+
def css_variable_declaration(name, name_start_pos, name_end_pos)
|
|
844
|
+
value_start_pos = source_position
|
|
845
|
+
value = declaration_value
|
|
846
|
+
value_end_pos = source_position
|
|
847
|
+
|
|
848
|
+
node = node(Sass::Tree::PropNode.new(name.flatten.compact, value, :new),
|
|
849
|
+
name_start_pos, value_end_pos)
|
|
850
|
+
node.name_source_range = range(name_start_pos, name_end_pos)
|
|
851
|
+
node.value_source_range = range(value_start_pos, value_end_pos)
|
|
852
|
+
node
|
|
853
|
+
end
|
|
854
|
+
|
|
855
|
+
# This production consumes values that could be a selector, an expression,
|
|
856
|
+
# or a combination of both. It respects strings and comments and supports
|
|
857
|
+
# interpolation. It will consume up to "{", "}", ";", or "!".
|
|
821
858
|
#
|
|
822
859
|
# Values consumed by this production will usually be parsed more
|
|
823
860
|
# thoroughly once interpolation has been resolved.
|
|
@@ -851,6 +888,60 @@ module Sass
|
|
|
851
888
|
interpolation(:warn_for_color)
|
|
852
889
|
end
|
|
853
890
|
|
|
891
|
+
def declaration_value(top_level: true)
|
|
892
|
+
return unless (tok = declaration_value_token(top_level))
|
|
893
|
+
value = [tok]
|
|
894
|
+
while (tok = declaration_value_token(top_level))
|
|
895
|
+
value << tok
|
|
896
|
+
end
|
|
897
|
+
merge(value)
|
|
898
|
+
end
|
|
899
|
+
|
|
900
|
+
def declaration_value_token(top_level)
|
|
901
|
+
# This comes, more or less, from the [token consumption algorithm][].
|
|
902
|
+
# However, since we don't have to worry about the token semantics, we
|
|
903
|
+
# just consume everything until we come across a token with special
|
|
904
|
+
# semantics.
|
|
905
|
+
#
|
|
906
|
+
# [token consumption algorithm]: https://drafts.csswg.org/css-syntax-3/#consume-token.
|
|
907
|
+
result = tok(%r{
|
|
908
|
+
(
|
|
909
|
+
(?!
|
|
910
|
+
url\(
|
|
911
|
+
)
|
|
912
|
+
[^()\[\]{}"'#/ \t\r\n\f#{top_level ? ";" : ""}]
|
|
913
|
+
|
|
|
914
|
+
\#(?!\{)
|
|
915
|
+
|
|
|
916
|
+
/(?!\*)
|
|
917
|
+
)+
|
|
918
|
+
}xi) || interp_string || interp_uri || interpolation || tok(COMMENT)
|
|
919
|
+
return result if result
|
|
920
|
+
|
|
921
|
+
# Fold together multiple characters of whitespace that don't include
|
|
922
|
+
# newlines. The value only cares about the tokenization, so this is safe
|
|
923
|
+
# as long as we don't delete whitespace entirely. It's important that we
|
|
924
|
+
# fold here rather than post-processing, since we aren't allowed to fold
|
|
925
|
+
# whitespace within strings and we lose that context later on.
|
|
926
|
+
if (ws = tok(S))
|
|
927
|
+
return ws.include?("\n") ? ws.gsub(/\A[^\n]*/, '') : ' '
|
|
928
|
+
end
|
|
929
|
+
|
|
930
|
+
if tok(/\(/)
|
|
931
|
+
value = declaration_value(top_level: false)
|
|
932
|
+
tok!(/\)/)
|
|
933
|
+
['(', *value, ')']
|
|
934
|
+
elsif tok(/\[/)
|
|
935
|
+
value = declaration_value(top_level: false)
|
|
936
|
+
tok!(/\]/)
|
|
937
|
+
['[', *value, ']']
|
|
938
|
+
elsif tok(/\{/)
|
|
939
|
+
value = declaration_value(top_level: false)
|
|
940
|
+
tok!(/\}/)
|
|
941
|
+
['{', *value, '}']
|
|
942
|
+
end
|
|
943
|
+
end
|
|
944
|
+
|
|
854
945
|
def declaration
|
|
855
946
|
# This allows the "*prop: val", ":prop: val", "#prop: val", and ".prop:
|
|
856
947
|
# val" hacks.
|
|
@@ -871,12 +962,12 @@ module Sass
|
|
|
871
962
|
tok!(/:/)
|
|
872
963
|
ss
|
|
873
964
|
value_start_pos = source_position
|
|
874
|
-
value = value!
|
|
965
|
+
value = value!
|
|
875
966
|
value_end_pos = source_position
|
|
876
967
|
ss
|
|
877
968
|
require_block = tok?(/\{/)
|
|
878
969
|
|
|
879
|
-
node = node(Sass::Tree::PropNode.new(name.flatten.compact, value, :new),
|
|
970
|
+
node = node(Sass::Tree::PropNode.new(name.flatten.compact, [value], :new),
|
|
880
971
|
name_start_pos, value_end_pos)
|
|
881
972
|
node.name_source_range = range(name_start_pos, name_end_pos)
|
|
882
973
|
node.value_source_range = range(value_start_pos, value_end_pos)
|
|
@@ -885,7 +976,7 @@ module Sass
|
|
|
885
976
|
nested_properties! node
|
|
886
977
|
end
|
|
887
978
|
|
|
888
|
-
def value!
|
|
979
|
+
def value!
|
|
889
980
|
if tok?(/\{/)
|
|
890
981
|
str = Sass::Script::Tree::Literal.new(Sass::Script::Value::String.new(""))
|
|
891
982
|
str.line = source_position.line
|
|
@@ -899,25 +990,19 @@ module Sass
|
|
|
899
990
|
# we don't parse it at all, and instead return a plain old string
|
|
900
991
|
# containing the value.
|
|
901
992
|
# This results in a dramatic speed increase.
|
|
902
|
-
if (val = tok(STATIC_VALUE
|
|
903
|
-
|
|
993
|
+
if (val = tok(STATIC_VALUE))
|
|
994
|
+
# If val ends with escaped whitespace, leave it be.
|
|
995
|
+
str = Sass::Script::Tree::Literal.new(
|
|
996
|
+
Sass::Script::Value::String.new(
|
|
997
|
+
Sass::Util.strip_except_escapes(val)))
|
|
904
998
|
str.line = start_pos.line
|
|
905
999
|
str.source_range = range(start_pos)
|
|
906
1000
|
return str
|
|
907
1001
|
end
|
|
908
|
-
|
|
909
|
-
sass_script(:parse, css_variable)
|
|
1002
|
+
sass_script(:parse)
|
|
910
1003
|
end
|
|
911
1004
|
|
|
912
1005
|
def nested_properties!(node)
|
|
913
|
-
if node.name.first.is_a?(String) && node.name.first.start_with?("--")
|
|
914
|
-
Sass::Util.sass_warn(<<WARNING)
|
|
915
|
-
DEPRECATION WARNING on line #{@line}#{" of #{@filename}" if @filename}:
|
|
916
|
-
Sass 3.6 will change the way CSS variables are parsed. Instead of being parsed as
|
|
917
|
-
normal properties, they will not allow any Sass-specific behavior other than \#{}.
|
|
918
|
-
WARNING
|
|
919
|
-
end
|
|
920
|
-
|
|
921
1006
|
@expected = 'expression (e.g. 1px, bold) or "{"'
|
|
922
1007
|
block(node, :property)
|
|
923
1008
|
end
|
|
@@ -966,7 +1051,7 @@ WARNING
|
|
|
966
1051
|
def var_expr
|
|
967
1052
|
return unless tok(/\$/)
|
|
968
1053
|
line = @line
|
|
969
|
-
var = Sass::Script::Tree::Variable.new(
|
|
1054
|
+
var = Sass::Script::Tree::Variable.new(ident!)
|
|
970
1055
|
var.line = line
|
|
971
1056
|
var
|
|
972
1057
|
end
|
|
@@ -1004,11 +1089,27 @@ WARNING
|
|
|
1004
1089
|
res
|
|
1005
1090
|
end
|
|
1006
1091
|
|
|
1007
|
-
def
|
|
1008
|
-
|
|
1092
|
+
def ident
|
|
1093
|
+
(ident = tok(IDENT)) && Sass::Util.normalize_ident_escapes(ident)
|
|
1094
|
+
end
|
|
1095
|
+
|
|
1096
|
+
def ident!
|
|
1097
|
+
Sass::Util.normalize_ident_escapes(tok!(IDENT))
|
|
1098
|
+
end
|
|
1099
|
+
|
|
1100
|
+
def name
|
|
1101
|
+
(name = tok(NAME)) && Sass::Util.normalize_ident_escapes(name)
|
|
1102
|
+
end
|
|
1103
|
+
|
|
1104
|
+
def name!
|
|
1105
|
+
Sass::Util.normalize_ident_escapes(tok!(NAME))
|
|
1106
|
+
end
|
|
1107
|
+
|
|
1108
|
+
def interp_ident
|
|
1109
|
+
val = ident || interpolation(:warn_for_color) || tok(IDENT_HYPHEN_INTERP)
|
|
1009
1110
|
return unless val
|
|
1010
1111
|
res = [val]
|
|
1011
|
-
while (val =
|
|
1112
|
+
while (val = name || interpolation(:warn_for_color))
|
|
1012
1113
|
res << val
|
|
1013
1114
|
end
|
|
1014
1115
|
res
|
|
@@ -1084,7 +1185,7 @@ WARNING
|
|
|
1084
1185
|
:media_expr => "media expression (e.g. (min-device-width: 800px))",
|
|
1085
1186
|
:at_root_query => "@at-root query (e.g. (without: media))",
|
|
1086
1187
|
:at_root_directive_list => '* or identifier',
|
|
1087
|
-
:
|
|
1188
|
+
:declaration_value => "expression (e.g. fr, 2n+1)",
|
|
1088
1189
|
:interp_ident => "identifier",
|
|
1089
1190
|
:qualified_name => "identifier",
|
|
1090
1191
|
:expr => "expression (e.g. 1px, bold)",
|
|
@@ -1099,9 +1200,9 @@ WARNING
|
|
|
1099
1200
|
:keyframes_selector => "keyframes selector (e.g. 10%)"
|
|
1100
1201
|
}
|
|
1101
1202
|
|
|
1102
|
-
TOK_NAMES = Sass::
|
|
1203
|
+
TOK_NAMES = Hash[Sass::SCSS::RX.constants.map do |c|
|
|
1103
1204
|
[Sass::SCSS::RX.const_get(c), c.downcase]
|
|
1104
|
-
end
|
|
1205
|
+
end].merge(
|
|
1105
1206
|
IDENT => "identifier",
|
|
1106
1207
|
/[;{}]/ => '";"',
|
|
1107
1208
|
/\b(without|with)\b/ => '"with" or "without"'
|
|
@@ -1213,23 +1314,11 @@ WARNING
|
|
|
1213
1314
|
# This is important because `#tok` is called all the time.
|
|
1214
1315
|
NEWLINE = "\n"
|
|
1215
1316
|
|
|
1216
|
-
def tok(rx
|
|
1317
|
+
def tok(rx)
|
|
1217
1318
|
res = @scanner.scan(rx)
|
|
1218
1319
|
|
|
1219
1320
|
return unless res
|
|
1220
1321
|
|
|
1221
|
-
# This fixes https://github.com/nex3/sass/issues/104, which affects
|
|
1222
|
-
# Ruby 1.8.7 and REE. This fix is to replace the ?= zero-width
|
|
1223
|
-
# positive lookahead operator in the Regexp (which matches without
|
|
1224
|
-
# consuming the matched group), with a match that does consume the
|
|
1225
|
-
# group, but then rewinds the scanner and removes the group from the
|
|
1226
|
-
# end of the matched string. This fix makes the assumption that the
|
|
1227
|
-
# matched group will always occur at the end of the match.
|
|
1228
|
-
if last_group_lookahead && @scanner[-1]
|
|
1229
|
-
@scanner.pos -= @scanner[-1].length
|
|
1230
|
-
res.slice!(-@scanner[-1].length..-1)
|
|
1231
|
-
end
|
|
1232
|
-
|
|
1233
1322
|
newline_count = res.count(NEWLINE)
|
|
1234
1323
|
if newline_count > 0
|
|
1235
1324
|
@line += newline_count
|