sass 3.7.4 → 4.0.0.alpha.1
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 +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
data/lib/sass/error.rb
CHANGED
@@ -69,14 +69,14 @@ module Sass
|
|
69
69
|
# The name of the mixin in which the error occurred.
|
70
70
|
# This could be `nil` if the error occurred outside a mixin.
|
71
71
|
#
|
72
|
-
# @return [
|
72
|
+
# @return [Fixnum]
|
73
73
|
def sass_mixin
|
74
74
|
sass_backtrace.first[:mixin]
|
75
75
|
end
|
76
76
|
|
77
77
|
# The line of the Sass template on which the error occurred.
|
78
78
|
#
|
79
|
-
# @return [
|
79
|
+
# @return [Fixnum]
|
80
80
|
def sass_line
|
81
81
|
sass_backtrace.first[:line]
|
82
82
|
end
|
@@ -86,7 +86,7 @@ module Sass
|
|
86
86
|
# @param attrs [{Symbol => Object}] The information in the backtrace entry.
|
87
87
|
# See \{#sass\_backtrace}
|
88
88
|
def add_backtrace(attrs)
|
89
|
-
sass_backtrace << attrs.reject {|
|
89
|
+
sass_backtrace << attrs.reject {|k, v| v.nil?}
|
90
90
|
end
|
91
91
|
|
92
92
|
# Modify the top Sass backtrace entries
|
@@ -104,12 +104,12 @@ module Sass
|
|
104
104
|
# @param attrs [{Symbol => Object}] The information to add to the backtrace entry.
|
105
105
|
# See \{#sass\_backtrace}
|
106
106
|
def modify_backtrace(attrs)
|
107
|
-
attrs = attrs.reject {|
|
107
|
+
attrs = attrs.reject {|k, v| v.nil?}
|
108
108
|
# Move backwards through the backtrace
|
109
|
-
(0...sass_backtrace.size).to_a.
|
109
|
+
(0...sass_backtrace.size).to_a.reverse.each do |i|
|
110
110
|
entry = sass_backtrace[i]
|
111
111
|
sass_backtrace[i] = attrs.merge(entry)
|
112
|
-
attrs.reject! {|k,
|
112
|
+
attrs.reject! {|k, v| entry.include?(k)}
|
113
113
|
break if attrs.empty?
|
114
114
|
end
|
115
115
|
end
|
@@ -127,7 +127,7 @@ module Sass
|
|
127
127
|
return nil if super.nil?
|
128
128
|
return super if sass_backtrace.all? {|h| h.empty?}
|
129
129
|
sass_backtrace.map do |h|
|
130
|
-
"#{h[:filename] ||
|
130
|
+
"#{h[:filename] || "(sass)"}:#{h[:line]}" +
|
131
131
|
(h[:mixin] ? ":in `#{h[:mixin]}'" : "")
|
132
132
|
end + super
|
133
133
|
end
|
@@ -142,8 +142,8 @@ module Sass
|
|
142
142
|
msg = lines[0] + lines[1..-1].
|
143
143
|
map {|l| "\n" + (" " * "Error: ".size) + l}.join
|
144
144
|
"Error: #{msg}" +
|
145
|
-
sass_backtrace.
|
146
|
-
"\n #{i == 0 ?
|
145
|
+
Sass::Util.enum_with_index(sass_backtrace).map do |entry, i|
|
146
|
+
"\n #{i == 0 ? "on" : "from"} line #{entry[:line]}" +
|
147
147
|
" of #{entry[:filename] || default_filename}" +
|
148
148
|
(entry[:mixin] ? ", in `#{entry[:mixin]}'" : "")
|
149
149
|
end.join
|
@@ -153,7 +153,7 @@ module Sass
|
|
153
153
|
# Returns an error report for an exception in CSS format.
|
154
154
|
#
|
155
155
|
# @param e [Exception]
|
156
|
-
# @param line_offset [
|
156
|
+
# @param line_offset [Fixnum] The number of the first line of the Sass template.
|
157
157
|
# @return [String] The error report
|
158
158
|
# @raise [Exception] `e`, if the
|
159
159
|
# {file:SASS_REFERENCE.md#full_exception-option `:full_exception`} option
|
@@ -163,9 +163,9 @@ module Sass
|
|
163
163
|
|
164
164
|
<<END
|
165
165
|
/*
|
166
|
-
#{header.gsub(
|
166
|
+
#{header.gsub("*/", "*\\/")}
|
167
167
|
|
168
|
-
Backtrace:\n#{e.backtrace.join("\n").gsub(
|
168
|
+
Backtrace:\n#{e.backtrace.join("\n").gsub("*/", "*\\/")}
|
169
169
|
*/
|
170
170
|
body:before {
|
171
171
|
white-space: pre;
|
@@ -183,10 +183,10 @@ END
|
|
183
183
|
|
184
184
|
line_num = e.sass_line + 1 - line_offset
|
185
185
|
min = [line_num - 6, 0].max
|
186
|
-
section = e.sass_template.rstrip.split("\n")[min...line_num + 5]
|
186
|
+
section = e.sass_template.rstrip.split("\n")[min ... line_num + 5]
|
187
187
|
return e.sass_backtrace_str if section.nil? || section.empty?
|
188
188
|
|
189
|
-
e.sass_backtrace_str + "\n\n" + section.
|
189
|
+
e.sass_backtrace_str + "\n\n" + Sass::Util.enum_with_index(section).
|
190
190
|
map {|line, i| "#{line_offset + min + i}: #{line}"}.join("\n")
|
191
191
|
end
|
192
192
|
end
|
data/lib/sass/exec/base.rb
CHANGED
@@ -14,6 +14,7 @@ module Sass::Exec
|
|
14
14
|
#
|
15
15
|
# @see #parse
|
16
16
|
def parse!
|
17
|
+
# rubocop:disable RescueException
|
17
18
|
begin
|
18
19
|
parse
|
19
20
|
rescue Exception => e
|
@@ -22,7 +23,7 @@ module Sass::Exec
|
|
22
23
|
# at_exit is a bit of a hack, but it allows us to rethrow when --trace
|
23
24
|
# is active and get both the built-in exception formatting and the
|
24
25
|
# correct exit code.
|
25
|
-
at_exit {exit
|
26
|
+
at_exit {exit 65} if e.is_a?(Sass::SyntaxError)
|
26
27
|
|
27
28
|
raise e if @options[:trace] || e.is_a?(SystemExit)
|
28
29
|
|
@@ -37,6 +38,7 @@ module Sass::Exec
|
|
37
38
|
exit 1
|
38
39
|
end
|
39
40
|
exit 0
|
41
|
+
# rubocop:enable RescueException
|
40
42
|
end
|
41
43
|
|
42
44
|
# Parses the command-line arguments and runs the executable.
|
@@ -88,9 +90,18 @@ module Sass::Exec
|
|
88
90
|
#
|
89
91
|
# @param opts [OptionParser]
|
90
92
|
def encoding_option(opts)
|
91
|
-
encoding_desc =
|
93
|
+
encoding_desc = if Sass::Util.ruby1_8?
|
94
|
+
'Does not work in Ruby 1.8.'
|
95
|
+
else
|
96
|
+
'Specify the default encoding for input files.'
|
97
|
+
end
|
92
98
|
opts.on('-E', '--default-encoding ENCODING', encoding_desc) do |encoding|
|
93
|
-
|
99
|
+
if Sass::Util.ruby1_8?
|
100
|
+
$stderr.puts "Specifying the encoding is not supported in ruby 1.8."
|
101
|
+
exit 1
|
102
|
+
else
|
103
|
+
Encoding.default_external = encoding
|
104
|
+
end
|
94
105
|
end
|
95
106
|
end
|
96
107
|
|
@@ -108,11 +108,10 @@ END
|
|
108
108
|
@options[:for_tree][:dasherize] = true
|
109
109
|
end
|
110
110
|
|
111
|
-
opts.on(
|
112
|
-
'--indent NUM',
|
111
|
+
opts.on('--indent NUM',
|
113
112
|
'How many spaces to use for each level of indentation. Defaults to 2.',
|
114
|
-
'"t" means use hard tabs.'
|
115
|
-
|
113
|
+
'"t" means use hard tabs.') do |indent|
|
114
|
+
|
116
115
|
if indent == 't'
|
117
116
|
@options[:for_tree][:indent] = "\t"
|
118
117
|
else
|
@@ -157,18 +156,13 @@ END
|
|
157
156
|
@options[:for_engine][:read_cache] = false
|
158
157
|
end
|
159
158
|
|
160
|
-
opts.on('-q', '--quiet', 'Silence warnings and status messages during conversion.') do |bool|
|
161
|
-
@options[:for_engine][:quiet] = bool
|
162
|
-
end
|
163
|
-
|
164
159
|
opts.on('--trace', :NONE, 'Show a full Ruby stack trace on error') do
|
165
160
|
@options[:trace] = true
|
166
161
|
end
|
167
162
|
end
|
168
163
|
|
169
164
|
def process_directory
|
170
|
-
@options[:input] = @args.shift
|
171
|
-
unless @options[:input]
|
165
|
+
unless @options[:input] = @args.shift
|
172
166
|
raise "Error: directory required when using --recursive."
|
173
167
|
end
|
174
168
|
|
@@ -247,12 +241,12 @@ END
|
|
247
241
|
Sass::Util.silence_sass_warnings do
|
248
242
|
if @options[:from] == :css
|
249
243
|
require 'sass/css'
|
250
|
-
Sass::CSS.new(read
|
244
|
+
Sass::CSS.new(input.read, @options[:for_tree]).render(@options[:to])
|
251
245
|
else
|
252
246
|
if input_path
|
253
247
|
Sass::Engine.for_file(input_path, @options[:for_engine])
|
254
248
|
else
|
255
|
-
Sass::Engine.new(read
|
249
|
+
Sass::Engine.new(input.read, @options[:for_engine])
|
256
250
|
end.to_tree.send("to_#{@options[:to]}", @options[:for_tree])
|
257
251
|
end
|
258
252
|
end
|
@@ -271,13 +265,5 @@ END
|
|
271
265
|
return file.path if file.is_a?(File)
|
272
266
|
return file if file.is_a?(String)
|
273
267
|
end
|
274
|
-
|
275
|
-
def read(file)
|
276
|
-
if file.respond_to?(:read)
|
277
|
-
file.read
|
278
|
-
else
|
279
|
-
open(file, 'rb') {|f| f.read}
|
280
|
-
end
|
281
|
-
end
|
282
268
|
end
|
283
269
|
end
|
data/lib/sass/exec/sass_scss.rb
CHANGED
@@ -92,7 +92,7 @@ END
|
|
92
92
|
end
|
93
93
|
|
94
94
|
opts.on("-v", "--version", "Print the Sass version.") do
|
95
|
-
puts("
|
95
|
+
puts("Sass #{Sass.version[:string]}")
|
96
96
|
exit
|
97
97
|
end
|
98
98
|
end
|
@@ -156,7 +156,7 @@ END
|
|
156
156
|
' file: always absolute file URIs',
|
157
157
|
' inline: include the source text in the sourcemap',
|
158
158
|
' none: no sourcemaps') do |type|
|
159
|
-
if type && !%w
|
159
|
+
if type && !%w[auto file inline none].include?(type)
|
160
160
|
$stderr.puts "Unknown sourcemap type #{type}.\n\n"
|
161
161
|
$stderr.puts opts
|
162
162
|
exit
|
@@ -256,6 +256,8 @@ MESSAGE
|
|
256
256
|
Sass::Repl.new(@options).run
|
257
257
|
end
|
258
258
|
|
259
|
+
# @comment
|
260
|
+
# rubocop:disable MethodLength
|
259
261
|
def watch_or_update
|
260
262
|
require 'sass/plugin'
|
261
263
|
Sass::Plugin.options.merge! @options[:for_engine]
|
@@ -288,6 +290,27 @@ File #{@args[1]} #{err}.
|
|
288
290
|
MSG
|
289
291
|
end
|
290
292
|
|
293
|
+
# Watch the working directory for changes without adding it to the load
|
294
|
+
# path. This preserves the pre-3.4 behavior when the working directory was
|
295
|
+
# on the load path. We should remove this when we can look for directories
|
296
|
+
# to watch by traversing the import graph.
|
297
|
+
class << Sass::Plugin.compiler
|
298
|
+
# We have to use a class var to make this visible to #watched_file? and
|
299
|
+
# #watched_paths.
|
300
|
+
# rubocop:disable ClassVars
|
301
|
+
@@working_directory = Sass::Util.realpath('.').to_s
|
302
|
+
# rubocop:ensable ClassVars
|
303
|
+
|
304
|
+
def watched_file?(file)
|
305
|
+
super(file) ||
|
306
|
+
(file =~ /\.s[ac]ss$/ && file.start_with?(@@working_directory + File::SEPARATOR))
|
307
|
+
end
|
308
|
+
|
309
|
+
def watched_paths
|
310
|
+
@watched_paths ||= super + [@@working_directory]
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
291
314
|
dirs, files = @args.map {|name| split_colon_path(name)}.
|
292
315
|
partition {|i, _| File.directory? i}
|
293
316
|
|
@@ -357,6 +380,8 @@ WARNING
|
|
357
380
|
|
358
381
|
Sass::Plugin.watch(files)
|
359
382
|
end
|
383
|
+
# @comment
|
384
|
+
# rubocop:enable MethodLength
|
360
385
|
|
361
386
|
def run
|
362
387
|
input = @options[:input]
|
@@ -386,8 +411,7 @@ WARNING
|
|
386
411
|
@options[:sourcemap_filename], Sass::Util.pathname(@options[:output_filename]).dirname)
|
387
412
|
rendered, mapping = engine.render_with_sourcemap(relative_sourcemap_path.to_s)
|
388
413
|
write_output(rendered, output)
|
389
|
-
write_output(
|
390
|
-
mapping.to_json(
|
414
|
+
write_output(mapping.to_json(
|
391
415
|
:type => @options[:sourcemap],
|
392
416
|
:css_path => @options[:output_filename],
|
393
417
|
:sourcemap_path => @options[:sourcemap_filename]) + "\n",
|
@@ -409,7 +433,7 @@ WARNING
|
|
409
433
|
def split_colon_path(path)
|
410
434
|
one, two = path.split(':', 2)
|
411
435
|
if one && two && Sass::Util.windows? &&
|
412
|
-
one =~ /\A[A-Za-z]\Z/ && two =~
|
436
|
+
one =~ /\A[A-Za-z]\Z/ && two =~ /\A[\/\\]/
|
413
437
|
# If we're on Windows and we were passed a drive letter path,
|
414
438
|
# don't split on that colon.
|
415
439
|
one2, two = two.split(':', 2)
|
data/lib/sass/features.rb
CHANGED
@@ -7,13 +7,12 @@ module Sass
|
|
7
7
|
#
|
8
8
|
# When this is updated, the documentation of `feature-exists()` should be
|
9
9
|
# updated as well.
|
10
|
-
KNOWN_FEATURES = Set[*%w
|
10
|
+
KNOWN_FEATURES = Set[*%w{
|
11
11
|
global-variable-shadowing
|
12
12
|
extend-selector-pseudoclass
|
13
13
|
units-level-3
|
14
14
|
at-error
|
15
|
-
|
16
|
-
)]
|
15
|
+
}]
|
17
16
|
|
18
17
|
# Check if a feature exists by name. This is used to implement
|
19
18
|
# the Sass function `feature-exists($feature)`
|
@@ -67,7 +67,7 @@ module Sass
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def public_url(name, sourcemap_directory)
|
70
|
-
file_pathname = Sass::Util.cleanpath(
|
70
|
+
file_pathname = Sass::Util.cleanpath(Sass::Util.absolute_path(name, @root))
|
71
71
|
return Sass::Util.file_uri_from_path(file_pathname) if sourcemap_directory.nil?
|
72
72
|
|
73
73
|
sourcemap_pathname = Sass::Util.cleanpath(sourcemap_directory)
|
@@ -122,7 +122,7 @@ module Sass
|
|
122
122
|
end
|
123
123
|
|
124
124
|
# JRuby chokes when trying to import files from JARs when the path starts with './'.
|
125
|
-
ret.map {|f, s| [f.sub(
|
125
|
+
ret.map {|f, s| [f.sub(/^\.\//, ''), s]}
|
126
126
|
end
|
127
127
|
|
128
128
|
def escape_glob_characters(name)
|
@@ -144,19 +144,14 @@ module Sass
|
|
144
144
|
name = name.gsub(File::ALT_SEPARATOR, File::SEPARATOR) unless File::ALT_SEPARATOR.nil?
|
145
145
|
|
146
146
|
found = possible_files(remove_root(name)).map do |f, s|
|
147
|
-
path =
|
148
|
-
|
149
|
-
else
|
150
|
-
"#{escape_glob_characters(dir)}/#{f}"
|
151
|
-
end
|
147
|
+
path = (dir == "." || Sass::Util.pathname(f).absolute?) ? f :
|
148
|
+
"#{escape_glob_characters(dir)}/#{f}"
|
152
149
|
Dir[path].map do |full_path|
|
153
150
|
full_path.gsub!(REDUNDANT_DIRECTORY, File::SEPARATOR)
|
154
151
|
[Sass::Util.cleanpath(full_path).to_s, s]
|
155
152
|
end
|
156
153
|
end.flatten(1)
|
157
|
-
if found.empty?
|
158
|
-
return find_real_file("#{dir}/#{name}", "index", options)
|
159
|
-
end
|
154
|
+
return if found.empty?
|
160
155
|
|
161
156
|
if found.size > 1 && !@same_name_warnings.include?(found.first.first)
|
162
157
|
found.each {|(f, _)| @same_name_warnings << f}
|
@@ -204,7 +199,7 @@ WARNING
|
|
204
199
|
|
205
200
|
def _find(dir, name, options)
|
206
201
|
full_filename, syntax = Sass::Util.destructure(find_real_file(dir, name, options))
|
207
|
-
return unless full_filename && File.
|
202
|
+
return unless full_filename && File.readable?(full_filename)
|
208
203
|
|
209
204
|
# TODO: this preserves historical behavior, but it's possible
|
210
205
|
# :filename should be either normalized to the native format
|
data/lib/sass/logger.rb
CHANGED
@@ -2,16 +2,11 @@ module Sass::Logger; end
|
|
2
2
|
|
3
3
|
require "sass/logger/log_level"
|
4
4
|
require "sass/logger/base"
|
5
|
-
require "sass/logger/delayed"
|
6
5
|
|
7
6
|
module Sass
|
8
7
|
class << self
|
9
|
-
|
10
|
-
Thread.current[:sass_logger] = l
|
11
|
-
end
|
12
|
-
|
13
|
-
def logger
|
14
|
-
Thread.current[:sass_logger] ||= Sass::Logger::Base.new
|
15
|
-
end
|
8
|
+
attr_accessor :logger
|
16
9
|
end
|
10
|
+
|
11
|
+
self.logger = Sass::Logger::Base.new
|
17
12
|
end
|
data/lib/sass/logger/base.rb
CHANGED
@@ -5,7 +5,6 @@ class Sass::Logger::Base
|
|
5
5
|
|
6
6
|
attr_accessor :log_level
|
7
7
|
attr_accessor :disabled
|
8
|
-
attr_accessor :io
|
9
8
|
|
10
9
|
log_level :trace
|
11
10
|
log_level :debug
|
@@ -13,35 +12,19 @@ class Sass::Logger::Base
|
|
13
12
|
log_level :warn
|
14
13
|
log_level :error
|
15
14
|
|
16
|
-
def initialize(log_level = :debug
|
15
|
+
def initialize(log_level = :debug)
|
17
16
|
self.log_level = log_level
|
18
|
-
self.io = io
|
19
17
|
end
|
20
18
|
|
21
19
|
def logging_level?(level)
|
22
20
|
!disabled && self.class.log_level?(level, log_level)
|
23
21
|
end
|
24
22
|
|
25
|
-
# Captures all logger messages emitted during a block and returns them as a
|
26
|
-
# string.
|
27
|
-
def capture
|
28
|
-
old_io = io
|
29
|
-
self.io = StringIO.new
|
30
|
-
yield
|
31
|
-
io.string
|
32
|
-
ensure
|
33
|
-
self.io = old_io
|
34
|
-
end
|
35
|
-
|
36
23
|
def log(level, message)
|
37
24
|
_log(level, message) if logging_level?(level)
|
38
25
|
end
|
39
26
|
|
40
27
|
def _log(level, message)
|
41
|
-
|
42
|
-
io.puts(message)
|
43
|
-
else
|
44
|
-
Kernel.warn(message)
|
45
|
-
end
|
28
|
+
Kernel.warn(message)
|
46
29
|
end
|
47
30
|
end
|
data/lib/sass/plugin.rb
CHANGED
@@ -12,7 +12,7 @@ module Sass
|
|
12
12
|
# when it's used as a plugin for various frameworks.
|
13
13
|
# All Rack-enabled frameworks are supported out of the box.
|
14
14
|
# The plugin is
|
15
|
-
# {file:SASS_REFERENCE.md#
|
15
|
+
# {file:SASS_REFERENCE.md#rails_merb_plugin automatically activated for Rails and Merb}.
|
16
16
|
# Other frameworks must enable it explicitly; see {Sass::Plugin::Rack}.
|
17
17
|
#
|
18
18
|
# This module has a large set of callbacks available
|
@@ -93,8 +93,7 @@ module Sass
|
|
93
93
|
# the second is the location of the CSS file that it should be compiled to.
|
94
94
|
# @see #update_stylesheets
|
95
95
|
def force_update_stylesheets(individual_files = [])
|
96
|
-
Compiler.new(
|
97
|
-
options.dup.merge(
|
96
|
+
Compiler.new(options.dup.merge(
|
98
97
|
:never_update => false,
|
99
98
|
:always_update => true,
|
100
99
|
:cache => false)).update_stylesheets(individual_files)
|
data/lib/sass/plugin/compiler.rb
CHANGED
@@ -31,7 +31,7 @@ module Sass::Plugin
|
|
31
31
|
# Creates a new compiler.
|
32
32
|
#
|
33
33
|
# @param opts [{Symbol => Object}]
|
34
|
-
# See {file:SASS_REFERENCE.md#
|
34
|
+
# See {file:SASS_REFERENCE.md#options the Sass options documentation}.
|
35
35
|
def initialize(opts = {})
|
36
36
|
@watched_files = Set.new
|
37
37
|
options.merge!(opts)
|
@@ -289,7 +289,6 @@ module Sass::Plugin
|
|
289
289
|
# @option options [Boolean] :skip_initial_update
|
290
290
|
# Don't do an initial update when starting the watcher when true
|
291
291
|
def watch(individual_files = [], options = {})
|
292
|
-
@inferred_directories = []
|
293
292
|
options, individual_files = individual_files, [] if individual_files.is_a?(Hash)
|
294
293
|
update_stylesheets(individual_files) unless options[:skip_initial_update]
|
295
294
|
|
@@ -297,36 +296,46 @@ module Sass::Plugin
|
|
297
296
|
individual_files.each do |(source, _, _)|
|
298
297
|
source = File.expand_path(source)
|
299
298
|
@watched_files << Sass::Util.realpath(source).to_s
|
300
|
-
|
299
|
+
directories << File.dirname(source)
|
301
300
|
end
|
302
|
-
|
303
|
-
directories += @inferred_directories
|
304
301
|
directories = remove_redundant_directories(directories)
|
305
302
|
|
303
|
+
# A Listen version prior to 2.0 will write a test file to a directory to
|
304
|
+
# see if a watcher supports watching that directory. That breaks horribly
|
305
|
+
# on read-only directories, so we filter those out.
|
306
|
+
unless Sass::Util.listen_geq_2?
|
307
|
+
directories = directories.select {|d| File.directory?(d) && File.writable?(d)}
|
308
|
+
end
|
309
|
+
|
306
310
|
# TODO: Keep better track of what depends on what
|
307
311
|
# so we don't have to run a global update every time anything changes.
|
308
312
|
# XXX The :additional_watch_paths option exists for Compass to use until
|
309
313
|
# a deprecated feature is removed. It may be removed without warning.
|
310
|
-
directories
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
314
|
+
listener_args = directories +
|
315
|
+
Array(options[:additional_watch_paths]) +
|
316
|
+
[{:relative_paths => false}]
|
317
|
+
|
318
|
+
# The native windows listener is much slower than the polling option, according to
|
319
|
+
# https://github.com/nex3/sass/commit/a3031856b22bc834a5417dedecb038b7be9b9e3e
|
320
|
+
poll = @options[:poll] || Sass::Util.windows?
|
321
|
+
if poll && Sass::Util.listen_geq_2?
|
322
|
+
# In Listen 2.0.0 and on, :force_polling is an option. In earlier
|
323
|
+
# versions, it's a method on the listener (called below).
|
324
|
+
listener_args.last[:force_polling] = true
|
325
|
+
end
|
318
326
|
|
319
|
-
listener = create_listener(*
|
327
|
+
listener = create_listener(*listener_args) do |modified, added, removed|
|
320
328
|
on_file_changed(individual_files, modified, added, removed)
|
321
329
|
yield(modified, added, removed) if block_given?
|
322
330
|
end
|
323
331
|
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
# Squelch Interrupt for clean exit from Listen::Listener
|
332
|
+
if poll && !Sass::Util.listen_geq_2?
|
333
|
+
# In Listen 2.0.0 and on, :force_polling is an option (set above). In
|
334
|
+
# earlier versions, it's a method on the listener.
|
335
|
+
listener.force_polling(true)
|
329
336
|
end
|
337
|
+
|
338
|
+
listen_to(listener)
|
330
339
|
end
|
331
340
|
|
332
341
|
# Non-destructively modifies \{#options} so that default values are properly set,
|
@@ -375,10 +384,28 @@ module Sass::Plugin
|
|
375
384
|
|
376
385
|
private
|
377
386
|
|
378
|
-
# This is mocked out in compiler_test.rb.
|
379
387
|
def create_listener(*args, &block)
|
380
|
-
|
381
|
-
|
388
|
+
Sass::Util.load_listen!
|
389
|
+
if Sass::Util.listen_geq_2?
|
390
|
+
# Work around guard/listen#243.
|
391
|
+
options = args.pop if args.last.is_a?(Hash)
|
392
|
+
args.map do |dir|
|
393
|
+
Listen.to(dir, options, &block)
|
394
|
+
end
|
395
|
+
else
|
396
|
+
Listen::Listener.new(*args, &block)
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
def listen_to(listener)
|
401
|
+
if Sass::Util.listen_geq_2?
|
402
|
+
listener.map {|l| l.start}
|
403
|
+
sleep
|
404
|
+
else
|
405
|
+
listener.start!
|
406
|
+
end
|
407
|
+
rescue Interrupt
|
408
|
+
# Squelch Interrupt for clean exit from Listen::Listener
|
382
409
|
end
|
383
410
|
|
384
411
|
def remove_redundant_directories(directories)
|
@@ -427,20 +454,21 @@ module Sass::Plugin
|
|
427
454
|
# And try to remove the css file that corresponds to it
|
428
455
|
template_location_array.each do |(sass_dir, css_dir)|
|
429
456
|
sass_dir = File.expand_path(sass_dir)
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
457
|
+
if child_of_directory?(sass_dir, f)
|
458
|
+
remainder = f[(sass_dir.size + 1)..-1]
|
459
|
+
try_delete_css(css_filename(remainder, css_dir))
|
460
|
+
break
|
461
|
+
end
|
434
462
|
end
|
435
463
|
end
|
436
464
|
end
|
437
465
|
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
466
|
+
if recompile_required
|
467
|
+
# In case a file we're watching is removed and then recreated we
|
468
|
+
# prune out the non-existent files here.
|
469
|
+
watched_files_remaining = individual_files.select {|(source, _, _)| File.exist?(source)}
|
470
|
+
update_stylesheets(watched_files_remaining)
|
471
|
+
end
|
444
472
|
end
|
445
473
|
|
446
474
|
def update_stylesheet(filename, css, sourcemap)
|
@@ -472,9 +500,7 @@ module Sass::Plugin
|
|
472
500
|
|
473
501
|
write_file(css, rendered)
|
474
502
|
if mapping
|
475
|
-
write_file(
|
476
|
-
sourcemap,
|
477
|
-
mapping.to_json(
|
503
|
+
write_file(sourcemap, mapping.to_json(
|
478
504
|
:css_path => css, :sourcemap_path => sourcemap, :type => options[:sourcemap]))
|
479
505
|
end
|
480
506
|
run_updated_stylesheet(filename, css, sourcemap) unless compilation_error_occurred
|
@@ -484,7 +510,7 @@ module Sass::Plugin
|
|
484
510
|
flag = 'w'
|
485
511
|
flag = 'wb' if Sass::Util.windows? && options[:unix_newlines]
|
486
512
|
File.open(fileName, flag) do |file|
|
487
|
-
file.set_encoding(content.encoding)
|
513
|
+
file.set_encoding(content.encoding) unless Sass::Util.ruby1_8?
|
488
514
|
file.print(content)
|
489
515
|
end
|
490
516
|
end
|
@@ -495,21 +521,14 @@ module Sass::Plugin
|
|
495
521
|
File.delete css
|
496
522
|
end
|
497
523
|
map = Sass::Util.sourcemap_name(css)
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
File.delete map
|
524
|
+
if File.exist?(map)
|
525
|
+
run_deleting_sourcemap map
|
526
|
+
File.delete map
|
527
|
+
end
|
503
528
|
end
|
504
529
|
|
505
530
|
def watched_file?(file)
|
506
|
-
@watched_files.include?(file) ||
|
507
|
-
normalized_load_paths.any? {|lp| lp.watched_file?(file)} ||
|
508
|
-
@inferred_directories.any? {|d| sass_file_in_directory?(d, file)}
|
509
|
-
end
|
510
|
-
|
511
|
-
def sass_file_in_directory?(directory, filename)
|
512
|
-
filename =~ /\.s[ac]ss$/ && filename.start_with?(directory + File::SEPARATOR)
|
531
|
+
@watched_files.include?(file) || normalized_load_paths.any? {|lp| lp.watched_file?(file)}
|
513
532
|
end
|
514
533
|
|
515
534
|
def watched_paths
|