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
|
@@ -163,7 +163,7 @@ module Sass
|
|
|
163
163
|
next sel if seen.include?([sel])
|
|
164
164
|
extended = sel.selector.do_extend(extends, parent_directives, replace, seen, false)
|
|
165
165
|
next sel if extended == sel.selector
|
|
166
|
-
extended.members.reject! {|seq| seq.
|
|
166
|
+
extended.members.reject! {|seq| seq.invisible?}
|
|
167
167
|
|
|
168
168
|
# For `:not()`, we usually want to get rid of any complex
|
|
169
169
|
# selectors because that will cause the selector to fail to
|
|
@@ -184,17 +184,16 @@ module Sass
|
|
|
184
184
|
result
|
|
185
185
|
end.flatten
|
|
186
186
|
|
|
187
|
-
groups =
|
|
187
|
+
groups = extends[members.to_set].group_by {|ex| ex.extender}.to_a
|
|
188
188
|
groups.map! do |seq, group|
|
|
189
189
|
sels = group.map {|e| e.target}.flatten
|
|
190
190
|
# If A {@extend B} and C {...},
|
|
191
191
|
# seq is A, sels is B, and self is C
|
|
192
192
|
|
|
193
193
|
self_without_sel = Sass::Util.array_minus(members, sels)
|
|
194
|
-
group.each {|e| e.
|
|
194
|
+
group.each {|e| e.success = true}
|
|
195
195
|
unified = seq.members.last.unify(SimpleSequence.new(self_without_sel, subject?))
|
|
196
196
|
next unless unified
|
|
197
|
-
group.each {|e| e.result = :succeeded}
|
|
198
197
|
group.each {|e| check_directives_match!(e, parent_directives)}
|
|
199
198
|
new_seq = Sequence.new(seq.members[0...-1] + [unified])
|
|
200
199
|
new_seq.add_sources!(sources + [seq])
|
|
@@ -287,6 +286,11 @@ module Sass
|
|
|
287
286
|
# @see Simple#to_s
|
|
288
287
|
def to_s(opts = {})
|
|
289
288
|
res = @members.map {|m| m.to_s(opts)}.join
|
|
289
|
+
|
|
290
|
+
# :not(%foo) may resolve to the empty string, but it should match every
|
|
291
|
+
# selector so we replace it with "*".
|
|
292
|
+
res = '*' if res.empty?
|
|
293
|
+
|
|
290
294
|
res << '!' if subject?
|
|
291
295
|
res
|
|
292
296
|
end
|
data/lib/sass/source/map.rb
CHANGED
|
@@ -84,8 +84,6 @@ module Sass::Source
|
|
|
84
84
|
# @return [String] The JSON string.
|
|
85
85
|
# @raise [ArgumentError] If neither `:css_uri` nor `:css_path` and
|
|
86
86
|
# `:sourcemap_path` are specified.
|
|
87
|
-
# @comment
|
|
88
|
-
# rubocop:disable MethodLength
|
|
89
87
|
def to_json(options)
|
|
90
88
|
css_uri, css_path, sourcemap_path =
|
|
91
89
|
options[:css_uri], options[:css_path], options[:sourcemap_path]
|
|
@@ -93,8 +91,8 @@ module Sass::Source
|
|
|
93
91
|
raise ArgumentError.new("Sass::Source::Map#to_json requires either " \
|
|
94
92
|
"the :css_uri option or both the :css_path and :soucemap_path options.")
|
|
95
93
|
end
|
|
96
|
-
css_path &&= Sass::Util.pathname(
|
|
97
|
-
sourcemap_path &&= Sass::Util.pathname(
|
|
94
|
+
css_path &&= Sass::Util.pathname(File.absolute_path(css_path))
|
|
95
|
+
sourcemap_path &&= Sass::Util.pathname(File.absolute_path(sourcemap_path))
|
|
98
96
|
css_uri ||= Sass::Util.file_uri_from_path(
|
|
99
97
|
Sass::Util.relative_path_from(css_path, sourcemap_path.dirname))
|
|
100
98
|
|
|
@@ -197,8 +195,6 @@ module Sass::Source
|
|
|
197
195
|
result << "\n}"
|
|
198
196
|
result
|
|
199
197
|
end
|
|
200
|
-
# @comment
|
|
201
|
-
# rubocop:enable MethodLength
|
|
202
198
|
|
|
203
199
|
private
|
|
204
200
|
|
data/lib/sass/stack.rb
CHANGED
|
@@ -98,8 +98,28 @@ module Sass
|
|
|
98
98
|
with_frame(filename, line, :mixin, name) {yield}
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
+
# Pushes a function frame onto the stack.
|
|
102
|
+
#
|
|
103
|
+
# @param filename [String] See \{Frame#filename}.
|
|
104
|
+
# @param line [String] See \{Frame#line}.
|
|
105
|
+
# @param name [String] See \{Frame#name}.
|
|
106
|
+
# @yield [] A block in which the new frame is on the stack.
|
|
107
|
+
def with_function(filename, line, name)
|
|
108
|
+
with_frame(filename, line, :function, name) {yield}
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Pushes a function frame onto the stack.
|
|
112
|
+
#
|
|
113
|
+
# @param filename [String] See \{Frame#filename}.
|
|
114
|
+
# @param line [String] See \{Frame#line}.
|
|
115
|
+
# @param name [String] See \{Frame#name}.
|
|
116
|
+
# @yield [] A block in which the new frame is on the stack.
|
|
117
|
+
def with_directive(filename, line, name)
|
|
118
|
+
with_frame(filename, line, :directive, name) {yield}
|
|
119
|
+
end
|
|
120
|
+
|
|
101
121
|
def to_s
|
|
102
|
-
|
|
122
|
+
(frames.reverse + [nil]).each_cons(2).each_with_index.
|
|
103
123
|
map do |(frame, caller), i|
|
|
104
124
|
"#{i == 0 ? 'on' : 'from'} line #{frame.line}" +
|
|
105
125
|
" of #{frame.filename || 'an unknown file'}" +
|
data/lib/sass/tree/prop_node.rb
CHANGED
|
@@ -20,7 +20,11 @@ module Sass::Tree
|
|
|
20
20
|
|
|
21
21
|
# The value of the property.
|
|
22
22
|
#
|
|
23
|
-
#
|
|
23
|
+
# For most properties, this will just contain a single Node. However, for
|
|
24
|
+
# CSS variables, it will contain multiple strings and nodes representing
|
|
25
|
+
# interpolation. Any adjacent strings will be merged together.
|
|
26
|
+
#
|
|
27
|
+
# @return [Array<String, Sass::Script::Tree::Node>]
|
|
24
28
|
attr_accessor :value
|
|
25
29
|
|
|
26
30
|
# The value of the property
|
|
@@ -52,14 +56,22 @@ module Sass::Tree
|
|
|
52
56
|
# @return [Sass::Source::Range]
|
|
53
57
|
attr_accessor :value_source_range
|
|
54
58
|
|
|
59
|
+
# Whether this represents a CSS custom property.
|
|
60
|
+
#
|
|
61
|
+
# @return [Boolean]
|
|
62
|
+
def custom_property?
|
|
63
|
+
name.first.is_a?(String) && name.first.start_with?("--")
|
|
64
|
+
end
|
|
65
|
+
|
|
55
66
|
# @param name [Array<String, Sass::Script::Tree::Node>] See \{#name}
|
|
56
|
-
# @param value [Sass::Script::Tree::Node] See \{#value}
|
|
67
|
+
# @param value [Array<String, Sass::Script::Tree::Node>] See \{#value}
|
|
57
68
|
# @param prop_syntax [Symbol] `:new` if this property uses `a: b`-style syntax,
|
|
58
69
|
# `:old` if it uses `:a b`-style syntax
|
|
59
70
|
def initialize(name, value, prop_syntax)
|
|
60
71
|
@name = Sass::Util.strip_string_array(
|
|
61
72
|
Sass::Util.merge_adjacent_strings(name))
|
|
62
|
-
@value = value
|
|
73
|
+
@value = Sass::Util.merge_adjacent_strings(value)
|
|
74
|
+
@value = Sass::Util.strip_string_array(@value) unless custom_property?
|
|
63
75
|
@tabs = 0
|
|
64
76
|
@prop_syntax = prop_syntax
|
|
65
77
|
super()
|
|
@@ -81,9 +93,10 @@ module Sass::Tree
|
|
|
81
93
|
# @return [String] The message
|
|
82
94
|
def pseudo_class_selector_message
|
|
83
95
|
if @prop_syntax == :new ||
|
|
84
|
-
|
|
85
|
-
!value.
|
|
86
|
-
!value.
|
|
96
|
+
custom_property? ||
|
|
97
|
+
!value.first.is_a?(Sass::Script::Tree::Literal) ||
|
|
98
|
+
!value.first.value.is_a?(Sass::Script::Value::String) ||
|
|
99
|
+
!value.first.value.value.empty?
|
|
87
100
|
return ""
|
|
88
101
|
end
|
|
89
102
|
|
|
@@ -98,73 +111,52 @@ module Sass::Tree
|
|
|
98
111
|
# @param fmt [Symbol] `:scss` or `:sass`.
|
|
99
112
|
def declaration(opts = {:old => @prop_syntax == :old}, fmt = :sass)
|
|
100
113
|
name = self.name.map {|n| n.is_a?(String) ? n : n.to_sass(opts)}.join
|
|
114
|
+
value = self.value.map {|n| n.is_a?(String) ? n : n.to_sass(opts)}.join
|
|
115
|
+
value = "(#{value})" if value_needs_parens?
|
|
116
|
+
|
|
101
117
|
if name[0] == ?:
|
|
102
|
-
raise Sass::SyntaxError.new("The \"#{name}: #{
|
|
118
|
+
raise Sass::SyntaxError.new("The \"#{name}: #{value}\"" +
|
|
103
119
|
" hack is not allowed in the Sass indented syntax")
|
|
104
120
|
end
|
|
105
121
|
|
|
122
|
+
# The indented syntax doesn't support newlines in custom property values,
|
|
123
|
+
# but we can losslessly convert them to spaces instead.
|
|
124
|
+
value = value.tr("\n", " ") if fmt == :sass
|
|
125
|
+
|
|
106
126
|
old = opts[:old] && fmt == :sass
|
|
107
|
-
|
|
108
|
-
mid = old ? '' : ':'
|
|
109
|
-
"#{initial}#{name}#{mid} #{self.class.val_to_sass(value, opts)}".rstrip
|
|
127
|
+
"#{old ? ':' : ''}#{name}#{old ? '' : ':'}#{custom_property? ? '' : ' '}#{value}".rstrip
|
|
110
128
|
end
|
|
111
129
|
|
|
112
130
|
# A property node is invisible if its value is empty.
|
|
113
131
|
#
|
|
114
132
|
# @return [Boolean]
|
|
115
133
|
def invisible?
|
|
116
|
-
resolved_value.empty?
|
|
134
|
+
!custom_property? && resolved_value.empty?
|
|
117
135
|
end
|
|
118
136
|
|
|
119
137
|
private
|
|
120
138
|
|
|
139
|
+
# Returns whether \{#value} neesd parentheses in order to be parsed
|
|
140
|
+
# properly as division.
|
|
141
|
+
def value_needs_parens?
|
|
142
|
+
return false if custom_property?
|
|
143
|
+
|
|
144
|
+
root = value.first
|
|
145
|
+
root.is_a?(Sass::Script::Tree::Operation) &&
|
|
146
|
+
root.operator == :div &&
|
|
147
|
+
root.operand1.is_a?(Sass::Script::Tree::Literal) &&
|
|
148
|
+
root.operand1.value.is_a?(Sass::Script::Value::Number) &&
|
|
149
|
+
root.operand1.value.original.nil? &&
|
|
150
|
+
root.operand2.is_a?(Sass::Script::Tree::Literal) &&
|
|
151
|
+
root.operand2.value.is_a?(Sass::Script::Value::Number) &&
|
|
152
|
+
root.operand2.value.original.nil?
|
|
153
|
+
end
|
|
154
|
+
|
|
121
155
|
def check!
|
|
122
156
|
return unless @options[:property_syntax] && @options[:property_syntax] != @prop_syntax
|
|
123
157
|
raise Sass::SyntaxError.new(
|
|
124
158
|
"Illegal property syntax: can't use #{@prop_syntax} syntax when " +
|
|
125
159
|
":property_syntax => #{@options[:property_syntax].inspect} is set.")
|
|
126
160
|
end
|
|
127
|
-
|
|
128
|
-
class << self
|
|
129
|
-
# @private
|
|
130
|
-
def val_to_sass(value, opts)
|
|
131
|
-
val_to_sass_comma(value, opts).to_sass(opts)
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
private
|
|
135
|
-
|
|
136
|
-
def val_to_sass_comma(node, opts)
|
|
137
|
-
return node unless node.is_a?(Sass::Script::Tree::Operation)
|
|
138
|
-
return val_to_sass_concat(node, opts) unless node.operator == :comma
|
|
139
|
-
|
|
140
|
-
Sass::Script::Tree::Operation.new(
|
|
141
|
-
val_to_sass_concat(node.operand1, opts),
|
|
142
|
-
val_to_sass_comma(node.operand2, opts),
|
|
143
|
-
node.operator)
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
def val_to_sass_concat(node, opts)
|
|
147
|
-
return node unless node.is_a?(Sass::Script::Tree::Operation)
|
|
148
|
-
return val_to_sass_div(node, opts) unless node.operator == :space
|
|
149
|
-
|
|
150
|
-
Sass::Script::Tree::Operation.new(
|
|
151
|
-
val_to_sass_div(node.operand1, opts),
|
|
152
|
-
val_to_sass_concat(node.operand2, opts),
|
|
153
|
-
node.operator)
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
def val_to_sass_div(node, opts)
|
|
157
|
-
unless node.is_a?(Sass::Script::Tree::Operation) && node.operator == :div &&
|
|
158
|
-
node.operand1.is_a?(Sass::Script::Tree::Literal) &&
|
|
159
|
-
node.operand1.value.is_a?(Sass::Script::Value::Number) &&
|
|
160
|
-
node.operand2.is_a?(Sass::Script::Tree::Literal) &&
|
|
161
|
-
node.operand2.value.is_a?(Sass::Script::Value::Number) &&
|
|
162
|
-
(!node.operand1.value.original || !node.operand2.value.original)
|
|
163
|
-
return node
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
Sass::Script::Value::String.new("(#{node.to_sass(opts)})")
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
161
|
end
|
|
170
162
|
end
|
data/lib/sass/tree/rule_node.rb
CHANGED
|
@@ -120,13 +120,14 @@ module Sass::Tree
|
|
|
120
120
|
#
|
|
121
121
|
# @return [{#to_s => #to_s}]
|
|
122
122
|
def debug_info
|
|
123
|
-
{:filename => filename &&
|
|
123
|
+
{:filename => filename &&
|
|
124
|
+
("file://" + URI::DEFAULT_PARSER.escape(File.expand_path(filename))),
|
|
124
125
|
:line => line}
|
|
125
126
|
end
|
|
126
127
|
|
|
127
128
|
# A rule node is invisible if it has only placeholder selectors.
|
|
128
129
|
def invisible?
|
|
129
|
-
resolved_rules.members.all? {|seq| seq.
|
|
130
|
+
resolved_rules.members.all? {|seq| seq.invisible?}
|
|
130
131
|
end
|
|
131
132
|
|
|
132
133
|
private
|
|
@@ -138,13 +139,10 @@ module Sass::Tree
|
|
|
138
139
|
# We don't use real filename/line info because we don't have it yet.
|
|
139
140
|
# When we get it, we'll set it on the parsed rules if possible.
|
|
140
141
|
parser = nil
|
|
141
|
-
warnings = Sass
|
|
142
|
-
parser = Sass::SCSS::StaticParser.new(
|
|
143
|
-
|
|
142
|
+
warnings = Sass.logger.capture do
|
|
143
|
+
parser = Sass::SCSS::StaticParser.new(
|
|
144
|
+
Sass::Util.strip_except_escapes(@rule.join), nil, nil, 1)
|
|
144
145
|
@parsed_rules = parser.parse_selector rescue nil
|
|
145
|
-
# rubocop:enable RescueModifier
|
|
146
|
-
|
|
147
|
-
$stderr.string
|
|
148
146
|
end
|
|
149
147
|
|
|
150
148
|
# If parsing produces a warning, throw away the result so we can parse
|
|
@@ -31,7 +31,7 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
|
|
|
31
31
|
if parent.is_a?(Sass::Tree::AtRootNode) && parent.resolved_value
|
|
32
32
|
old_parents = @parents
|
|
33
33
|
@parents = @parents.reject {|p| parent.exclude_node?(p)}
|
|
34
|
-
@parent =
|
|
34
|
+
@parent = @parents.reverse.each_with_index.
|
|
35
35
|
find {|p, i| !transparent_parent?(p, @parents[-i - 2])}.first
|
|
36
36
|
|
|
37
37
|
begin
|
|
@@ -203,8 +203,7 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
|
203
203
|
|
|
204
204
|
unless node.args.empty? && node.keywords.empty? && node.splat.nil?
|
|
205
205
|
args = node.args.map(&arg_to_sass)
|
|
206
|
-
keywords =
|
|
207
|
-
map {|k, v| "$#{dasherize(k)}: #{arg_to_sass[v]}"}
|
|
206
|
+
keywords = node.keywords.as_stored.to_a.map {|k, v| "$#{dasherize(k)}: #{arg_to_sass[v]}"}
|
|
208
207
|
|
|
209
208
|
if node.splat
|
|
210
209
|
splat = "#{arg_to_sass[node.splat]}..."
|
|
@@ -281,7 +280,7 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
|
281
280
|
# Visit rule-level nodes and return their conversion with appropriate
|
|
282
281
|
# whitespace added.
|
|
283
282
|
def visit_rule_level(nodes)
|
|
284
|
-
|
|
283
|
+
(nodes + [nil]).each_cons(2).map do |child, nxt|
|
|
285
284
|
visit(child) +
|
|
286
285
|
if nxt &&
|
|
287
286
|
(child.is_a?(Sass::Tree::CommentNode) && child.line + child.lines + 1 == nxt.line) ||
|
|
@@ -56,8 +56,7 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
|
56
56
|
@parents.pop
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
#
|
|
60
|
-
# and that it's at the top of the document.
|
|
59
|
+
# Converts the entire document to CSS.
|
|
61
60
|
#
|
|
62
61
|
# @return [(Tree::Node, Sass::Util::SubsetMap)] The resulting tree of static nodes
|
|
63
62
|
# *and* the extensions defined for this tree
|
|
@@ -65,14 +64,6 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
|
65
64
|
yield
|
|
66
65
|
|
|
67
66
|
if parent.nil?
|
|
68
|
-
# In Ruby 1.9 we can make all @charset nodes invisible
|
|
69
|
-
# and infer the final @charset from the encoding of the final string.
|
|
70
|
-
if Sass::Util.ruby1_8?
|
|
71
|
-
charset = node.children.find {|c| c.is_a?(Sass::Tree::CharsetNode)}
|
|
72
|
-
node.children.reject! {|c| c.is_a?(Sass::Tree::CharsetNode)}
|
|
73
|
-
node.children.unshift charset if charset
|
|
74
|
-
end
|
|
75
|
-
|
|
76
67
|
imports_to_move = []
|
|
77
68
|
import_limit = nil
|
|
78
69
|
i = -1
|
|
@@ -115,11 +106,9 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
|
115
106
|
# @attr node [Sass::Tree::ExtendNode] The node that produced this extend.
|
|
116
107
|
# @attr directives [Array<Sass::Tree::DirectiveNode>]
|
|
117
108
|
# The directives containing the `@extend`.
|
|
118
|
-
# @attr
|
|
119
|
-
#
|
|
120
|
-
|
|
121
|
-
# unified with the extender), or `:succeeded`.
|
|
122
|
-
Extend = Struct.new(:extender, :target, :node, :directives, :result)
|
|
109
|
+
# @attr success [Boolean]
|
|
110
|
+
# Whether this extend successfully matched a selector.
|
|
111
|
+
Extend = Struct.new(:extender, :target, :node, :directives, :success)
|
|
123
112
|
|
|
124
113
|
# Registers an extension in the `@extends` subset map.
|
|
125
114
|
def visit_extend(node)
|
|
@@ -61,7 +61,7 @@ class Sass::Tree::Visitors::DeepCopy < Sass::Tree::Visitors::Base
|
|
|
61
61
|
|
|
62
62
|
def visit_prop(node)
|
|
63
63
|
node.name = node.name.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.deep_copy : c}
|
|
64
|
-
node.value = node.value.deep_copy
|
|
64
|
+
node.value = node.value.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.deep_copy : c}
|
|
65
65
|
yield
|
|
66
66
|
end
|
|
67
67
|
|
|
@@ -49,19 +49,13 @@ class Sass::Tree::Visitors::Extend < Sass::Tree::Visitors::Base
|
|
|
49
49
|
|
|
50
50
|
def check_extends_fired!(extends)
|
|
51
51
|
extends.each_value do |ex|
|
|
52
|
-
next if ex.
|
|
52
|
+
next if ex.success || ex.node.optional?
|
|
53
53
|
message = "\"#{ex.extender}\" failed to @extend \"#{ex.target.join}\"."
|
|
54
|
-
reason =
|
|
55
|
-
if ex.result == :not_found
|
|
56
|
-
"The selector \"#{ex.target.join}\" was not found."
|
|
57
|
-
else
|
|
58
|
-
"No selectors matching \"#{ex.target.join}\" could be unified with \"#{ex.extender}\"."
|
|
59
|
-
end
|
|
60
54
|
|
|
61
55
|
# TODO(nweiz): this should use the Sass stack trace of the extend node.
|
|
62
56
|
raise Sass::SyntaxError.new(<<MESSAGE, :filename => ex.node.filename, :line => ex.node.line)
|
|
63
57
|
#{message}
|
|
64
|
-
#{
|
|
58
|
+
The selector "#{ex.target.join}" was not found.
|
|
65
59
|
Use "@extend #{ex.target.join} !optional" if the extend should be able to fail.
|
|
66
60
|
MESSAGE
|
|
67
61
|
end
|
|
@@ -11,8 +11,6 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
# @api private
|
|
14
|
-
# @comment
|
|
15
|
-
# rubocop:disable MethodLength
|
|
16
14
|
def perform_arguments(callable, args, splat, environment)
|
|
17
15
|
desc = "#{callable.type.capitalize} #{callable.name}"
|
|
18
16
|
downcase_desc = "#{callable.type} #{callable.name}"
|
|
@@ -145,8 +143,6 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
|
145
143
|
end
|
|
146
144
|
end
|
|
147
145
|
end
|
|
148
|
-
# @comment
|
|
149
|
-
# rubocop:enable MethodLength
|
|
150
146
|
|
|
151
147
|
protected
|
|
152
148
|
|
|
@@ -290,7 +286,7 @@ WARNING
|
|
|
290
286
|
|
|
291
287
|
@environment.set_local_function(node.name,
|
|
292
288
|
Sass::Callable.new(node.name, node.args, node.splat, env,
|
|
293
|
-
node.children, false, "function"))
|
|
289
|
+
node.children, false, "function", :stylesheet))
|
|
294
290
|
[]
|
|
295
291
|
end
|
|
296
292
|
|
|
@@ -341,7 +337,7 @@ WARNING
|
|
|
341
337
|
env = Sass::Environment.new(@environment, node.options)
|
|
342
338
|
@environment.set_local_mixin(node.name,
|
|
343
339
|
Sass::Callable.new(node.name, node.args, node.splat, env,
|
|
344
|
-
node.children, node.has_content, "mixin"))
|
|
340
|
+
node.children, node.has_content, "mixin", :stylesheet))
|
|
345
341
|
[]
|
|
346
342
|
end
|
|
347
343
|
|
|
@@ -351,7 +347,7 @@ WARNING
|
|
|
351
347
|
mixin = @environment.mixin(node.name)
|
|
352
348
|
raise Sass::SyntaxError.new("Undefined mixin '#{node.name}'.") unless mixin
|
|
353
349
|
|
|
354
|
-
if node.
|
|
350
|
+
if node.has_children && !mixin.has_content
|
|
355
351
|
raise Sass::SyntaxError.new(%(Mixin "#{node.name}" does not accept a content block.))
|
|
356
352
|
end
|
|
357
353
|
|
|
@@ -395,9 +391,19 @@ WARNING
|
|
|
395
391
|
# Runs any SassScript that may be embedded in a property.
|
|
396
392
|
def visit_prop(node)
|
|
397
393
|
node.resolved_name = run_interp(node.name)
|
|
398
|
-
|
|
399
|
-
node
|
|
400
|
-
|
|
394
|
+
|
|
395
|
+
# If the node's value is just a variable or similar, we may get a useful
|
|
396
|
+
# source range from evaluating it.
|
|
397
|
+
if node.value.length == 1 && node.value.first.is_a?(Sass::Script::Tree::Node)
|
|
398
|
+
result = node.value.first.perform(@environment)
|
|
399
|
+
node.resolved_value = result.to_s
|
|
400
|
+
node.value_source_range = result.source_range if result.source_range
|
|
401
|
+
elsif node.custom_property?
|
|
402
|
+
node.resolved_value = run_interp_no_strip(node.value)
|
|
403
|
+
else
|
|
404
|
+
node.resolved_value = run_interp(node.value)
|
|
405
|
+
end
|
|
406
|
+
|
|
401
407
|
yield
|
|
402
408
|
end
|
|
403
409
|
|
|
@@ -483,9 +489,11 @@ WARNING
|
|
|
483
489
|
def visit_warn(node)
|
|
484
490
|
res = node.expr.perform(@environment)
|
|
485
491
|
res = res.value if res.is_a?(Sass::Script::Value::String)
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
492
|
+
@environment.stack.with_directive(node.filename, node.line, "@warn") do
|
|
493
|
+
msg = "WARNING: #{res}\n "
|
|
494
|
+
msg << @environment.stack.to_s.gsub("\n", "\n ") << "\n"
|
|
495
|
+
Sass::Util.sass_warn msg
|
|
496
|
+
end
|
|
489
497
|
[]
|
|
490
498
|
end
|
|
491
499
|
|
|
@@ -545,7 +553,7 @@ WARNING
|
|
|
545
553
|
end
|
|
546
554
|
|
|
547
555
|
def run_interp(text)
|
|
548
|
-
run_interp_no_strip(text)
|
|
556
|
+
Sass::Util.strip_except_escapes(run_interp_no_strip(text))
|
|
549
557
|
end
|
|
550
558
|
|
|
551
559
|
def handle_import_loop!(node)
|
|
@@ -556,7 +564,7 @@ WARNING
|
|
|
556
564
|
end
|
|
557
565
|
|
|
558
566
|
files << node.filename << node.imported_file.options[:filename]
|
|
559
|
-
msg << "\n" <<
|
|
567
|
+
msg << "\n" << files.each_cons(2).map do |m1, m2|
|
|
560
568
|
" #{m1} imports #{m2}"
|
|
561
569
|
end.join("\n")
|
|
562
570
|
raise Sass::SyntaxError.new(msg)
|