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
@@ -56,7 +56,8 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
56
56
|
@parents.pop
|
57
57
|
end
|
58
58
|
|
59
|
-
#
|
59
|
+
# In Ruby 1.8, ensures that there's only one `@charset` directive
|
60
|
+
# and that it's at the top of the document.
|
60
61
|
#
|
61
62
|
# @return [(Tree::Node, Sass::Util::SubsetMap)] The resulting tree of static nodes
|
62
63
|
# *and* the extensions defined for this tree
|
@@ -64,6 +65,14 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
64
65
|
yield
|
65
66
|
|
66
67
|
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
|
+
|
67
76
|
imports_to_move = []
|
68
77
|
import_limit = nil
|
69
78
|
i = -1
|
@@ -106,9 +115,11 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
106
115
|
# @attr node [Sass::Tree::ExtendNode] The node that produced this extend.
|
107
116
|
# @attr directives [Array<Sass::Tree::DirectiveNode>]
|
108
117
|
# The directives containing the `@extend`.
|
109
|
-
# @attr
|
110
|
-
#
|
111
|
-
|
118
|
+
# @attr result [Symbol]
|
119
|
+
# The result of this extend. One of `:not_found` (the target doesn't exist
|
120
|
+
# in the document), `:failed_to_unify` (the target exists but cannot be
|
121
|
+
# unified with the extender), or `:succeeded`.
|
122
|
+
Extend = Struct.new(:extender, :target, :node, :directives, :result)
|
112
123
|
|
113
124
|
# Registers an extension in the `@extends` subset map.
|
114
125
|
def visit_extend(node)
|
@@ -55,13 +55,13 @@ class Sass::Tree::Visitors::DeepCopy < Sass::Tree::Visitors::Base
|
|
55
55
|
|
56
56
|
def visit_mixin(node)
|
57
57
|
node.args = node.args.map {|a| a.deep_copy}
|
58
|
-
node.keywords =
|
58
|
+
node.keywords = Hash[node.keywords.map {|k, v| [k, v.deep_copy]}]
|
59
59
|
yield
|
60
60
|
end
|
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.
|
64
|
+
node.value = node.value.deep_copy
|
65
65
|
yield
|
66
66
|
end
|
67
67
|
|
@@ -44,21 +44,25 @@ class Sass::Tree::Visitors::Extend < Sass::Tree::Visitors::Base
|
|
44
44
|
node.resolved_rules = node.resolved_rules.do_extend(@extends, @parent_directives)
|
45
45
|
end
|
46
46
|
|
47
|
-
|
48
|
-
private
|
47
|
+
private
|
49
48
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
49
|
+
def self.check_extends_fired!(extends)
|
50
|
+
extends.each_value do |ex|
|
51
|
+
next if ex.result == :succeeded || ex.node.optional?
|
52
|
+
message = "\"#{ex.extender}\" failed to @extend \"#{ex.target.join}\"."
|
53
|
+
reason =
|
54
|
+
if ex.result == :not_found
|
55
|
+
"The selector \"#{ex.target.join}\" was not found."
|
56
|
+
else
|
57
|
+
"No selectors matching \"#{ex.target.join}\" could be unified with \"#{ex.extender}\"."
|
58
|
+
end
|
54
59
|
|
55
|
-
|
56
|
-
|
60
|
+
# TODO(nweiz): this should use the Sass stack trace of the extend node.
|
61
|
+
raise Sass::SyntaxError.new(<<MESSAGE, :filename => ex.node.filename, :line => ex.node.line)
|
57
62
|
#{message}
|
58
|
-
|
63
|
+
#{reason}
|
59
64
|
Use "@extend #{ex.target.join} !optional" if the extend should be able to fail.
|
60
65
|
MESSAGE
|
61
|
-
end
|
62
66
|
end
|
63
67
|
end
|
64
68
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# A visitor for converting a dynamic Sass tree into a static Sass tree.
|
2
2
|
class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
3
|
-
@@function_name_deprecation = Sass::Deprecation.new
|
4
|
-
|
5
3
|
class << self
|
6
4
|
# @param root [Tree::Node] The root node of the tree to visit.
|
7
5
|
# @param environment [Sass::Environment] The lexical environment.
|
@@ -11,6 +9,8 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
11
9
|
end
|
12
10
|
|
13
11
|
# @api private
|
12
|
+
# @comment
|
13
|
+
# rubocop:disable MethodLength
|
14
14
|
def perform_arguments(callable, args, splat, environment)
|
15
15
|
desc = "#{callable.type.capitalize} #{callable.name}"
|
16
16
|
downcase_desc = "#{callable.type} #{callable.name}"
|
@@ -143,13 +143,13 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
143
143
|
end
|
144
144
|
end
|
145
145
|
end
|
146
|
+
# @comment
|
147
|
+
# rubocop:enable MethodLength
|
146
148
|
|
147
149
|
protected
|
148
150
|
|
149
151
|
def initialize(env)
|
150
152
|
@environment = env
|
151
|
-
@in_keyframes = false
|
152
|
-
@at_root_without_rule = false
|
153
153
|
end
|
154
154
|
|
155
155
|
# If an exception is raised, this adds proper metadata to the backtrace.
|
@@ -278,7 +278,8 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
278
278
|
|
279
279
|
if node.normalized_name == 'calc' || node.normalized_name == 'element' ||
|
280
280
|
node.name == 'expression' || node.name == 'url'
|
281
|
-
|
281
|
+
Sass::Util.sass_warn <<WARNING
|
282
|
+
DEPRECATION WARNING on line #{node.line}#{" of #{node.filename}" if node.filename}:
|
282
283
|
Naming a function "#{node.name}" is disallowed and will be an error in future versions of Sass.
|
283
284
|
This name conflicts with an existing CSS function with special parse rules.
|
284
285
|
WARNING
|
@@ -286,7 +287,7 @@ WARNING
|
|
286
287
|
|
287
288
|
@environment.set_local_function(node.name,
|
288
289
|
Sass::Callable.new(node.name, node.args, node.splat, env,
|
289
|
-
node.children,
|
290
|
+
node.children, !:has_content, "function"))
|
290
291
|
[]
|
291
292
|
end
|
292
293
|
|
@@ -337,7 +338,7 @@ WARNING
|
|
337
338
|
env = Sass::Environment.new(@environment, node.options)
|
338
339
|
@environment.set_local_mixin(node.name,
|
339
340
|
Sass::Callable.new(node.name, node.args, node.splat, env,
|
340
|
-
node.children, node.has_content, "mixin"
|
341
|
+
node.children, node.has_content, "mixin"))
|
341
342
|
[]
|
342
343
|
end
|
343
344
|
|
@@ -347,8 +348,8 @@ WARNING
|
|
347
348
|
mixin = @environment.mixin(node.name)
|
348
349
|
raise Sass::SyntaxError.new("Undefined mixin '#{node.name}'.") unless mixin
|
349
350
|
|
350
|
-
if node.
|
351
|
-
raise Sass::SyntaxError.new(%
|
351
|
+
if node.children.any? && !mixin.has_content
|
352
|
+
raise Sass::SyntaxError.new(%Q{Mixin "#{node.name}" does not accept a content block.})
|
352
353
|
end
|
353
354
|
|
354
355
|
args = node.args.map {|a| a.perform(@environment)}
|
@@ -391,19 +392,9 @@ WARNING
|
|
391
392
|
# Runs any SassScript that may be embedded in a property.
|
392
393
|
def visit_prop(node)
|
393
394
|
node.resolved_name = run_interp(node.name)
|
394
|
-
|
395
|
-
|
396
|
-
|
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
|
-
|
395
|
+
val = node.value.perform(@environment)
|
396
|
+
node.resolved_value = val.to_s
|
397
|
+
node.value_source_range = val.source_range if val.source_range
|
407
398
|
yield
|
408
399
|
end
|
409
400
|
|
@@ -489,11 +480,9 @@ WARNING
|
|
489
480
|
def visit_warn(node)
|
490
481
|
res = node.expr.perform(@environment)
|
491
482
|
res = res.value if res.is_a?(Sass::Script::Value::String)
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
Sass::Util.sass_warn msg
|
496
|
-
end
|
483
|
+
msg = "WARNING: #{res}\n "
|
484
|
+
msg << @environment.stack.to_s.gsub("\n", "\n ") << "\n"
|
485
|
+
Sass::Util.sass_warn msg
|
497
486
|
[]
|
498
487
|
end
|
499
488
|
|
@@ -553,7 +542,7 @@ WARNING
|
|
553
542
|
end
|
554
543
|
|
555
544
|
def run_interp(text)
|
556
|
-
|
545
|
+
run_interp_no_strip(text).strip
|
557
546
|
end
|
558
547
|
|
559
548
|
def handle_import_loop!(node)
|
@@ -564,7 +553,7 @@ WARNING
|
|
564
553
|
end
|
565
554
|
|
566
555
|
files << node.filename << node.imported_file.options[:filename]
|
567
|
-
msg << "\n" <<
|
556
|
+
msg << "\n" << Sass::Util.enum_cons(files, 2).map do |m1, m2|
|
568
557
|
" #{m1} imports #{m2}"
|
569
558
|
end.join("\n")
|
570
559
|
raise Sass::SyntaxError.new(msg)
|
@@ -80,7 +80,7 @@ class Sass::Tree::Visitors::SetOptions < Sass::Tree::Visitors::Base
|
|
80
80
|
|
81
81
|
def visit_mixin(node)
|
82
82
|
node.args.each {|a| a.options = @options}
|
83
|
-
node.keywords.each {|
|
83
|
+
node.keywords.each {|k, v| v.options = @options}
|
84
84
|
node.splat.options = @options if node.splat
|
85
85
|
node.kwarg_splat.options = @options if node.kwarg_splat
|
86
86
|
yield
|
@@ -88,7 +88,7 @@ class Sass::Tree::Visitors::SetOptions < Sass::Tree::Visitors::Base
|
|
88
88
|
|
89
89
|
def visit_prop(node)
|
90
90
|
node.name.each {|c| c.options = @options if c.is_a?(Sass::Script::Tree::Node)}
|
91
|
-
node.value.
|
91
|
+
node.value.options = @options
|
92
92
|
yield
|
93
93
|
end
|
94
94
|
|
@@ -12,10 +12,8 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
12
12
|
@tabs = 0
|
13
13
|
@line = 1
|
14
14
|
@offset = 1
|
15
|
-
@result =
|
16
|
-
@source_mapping =
|
17
|
-
@lstrip = nil
|
18
|
-
@in_directive = false
|
15
|
+
@result = ""
|
16
|
+
@source_mapping = Sass::Source::Map.new if build_source_mapping
|
19
17
|
end
|
20
18
|
|
21
19
|
# Runs the visitor on `node`.
|
@@ -53,8 +51,8 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
53
51
|
@source_mapping.add(source_range, target_range)
|
54
52
|
end
|
55
53
|
|
56
|
-
def
|
57
|
-
|
54
|
+
def ends_with?(str)
|
55
|
+
@result.end_with?(str)
|
58
56
|
end
|
59
57
|
|
60
58
|
# Move the output cursor back `chars` characters.
|
@@ -104,7 +102,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
104
102
|
@lstrip = true
|
105
103
|
yield
|
106
104
|
ensure
|
107
|
-
@lstrip
|
105
|
+
@lstrip = @lstrip && old_lstrip
|
108
106
|
end
|
109
107
|
|
110
108
|
# Prepend `prefix` to the output string.
|
@@ -122,20 +120,22 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
122
120
|
node.children.each do |child|
|
123
121
|
next if child.invisible?
|
124
122
|
visit(child)
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
123
|
+
unless node.style == :compressed
|
124
|
+
output "\n"
|
125
|
+
if child.is_a?(Sass::Tree::DirectiveNode) && child.has_children && !child.bubbles?
|
126
|
+
output "\n"
|
127
|
+
end
|
128
|
+
end
|
129
129
|
end
|
130
130
|
rstrip!
|
131
|
-
if node.style == :compressed &&
|
131
|
+
if node.style == :compressed && ends_with?(";")
|
132
132
|
erase! 1
|
133
133
|
end
|
134
134
|
return "" if @result.empty?
|
135
135
|
|
136
136
|
output "\n"
|
137
137
|
|
138
|
-
unless @result.ascii_only?
|
138
|
+
unless Sass::Util.ruby1_8? || @result.ascii_only?
|
139
139
|
if node.style == :compressed
|
140
140
|
# A byte order mark is sufficient to tell browsers that this
|
141
141
|
# file is UTF-8 encoded, and will override any other detection
|
@@ -163,14 +163,16 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
163
163
|
|
164
164
|
content = node.resolved_value.split("\n").join("\n" + spaces)
|
165
165
|
if node.type == :silent
|
166
|
-
content.gsub!(%r{^(\s*)//(.*)$}) {"#{$1}/*#{$2} */"}
|
166
|
+
content.gsub!(%r{^(\s*)//(.*)$}) {|md| "#{$1}/*#{$2} */"}
|
167
167
|
end
|
168
168
|
if (node.style == :compact || node.style == :compressed) && node.type != :loud
|
169
|
-
content.gsub!(
|
169
|
+
content.gsub!(/\n +(\* *(?!\/))?/, ' ')
|
170
170
|
end
|
171
171
|
for_node(node) {output(content)}
|
172
172
|
end
|
173
173
|
|
174
|
+
# @comment
|
175
|
+
# rubocop:disable MethodLength
|
174
176
|
def visit_directive(node)
|
175
177
|
was_in_directive = @in_directive
|
176
178
|
tab_str = ' ' * @tabs
|
@@ -185,7 +187,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
185
187
|
return
|
186
188
|
end
|
187
189
|
|
188
|
-
@in_directive
|
190
|
+
@in_directive = @in_directive || !node.is_a?(Sass::Tree::MediaNode)
|
189
191
|
output(tab_str) if node.style != :compressed
|
190
192
|
for_node(node) {output(node.resolved_value)}
|
191
193
|
output(node.style == :compressed ? "{" : " {")
|
@@ -220,7 +222,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
220
222
|
first = false
|
221
223
|
elsif node.style == :compressed
|
222
224
|
unless had_children
|
223
|
-
output(";") unless
|
225
|
+
output(";") unless ends_with?(";")
|
224
226
|
end
|
225
227
|
with_tabs(0) {visit(child)}
|
226
228
|
had_children = child.has_children
|
@@ -230,7 +232,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
230
232
|
end
|
231
233
|
end
|
232
234
|
rstrip!
|
233
|
-
if node.style == :compressed &&
|
235
|
+
if node.style == :compressed && ends_with?(";")
|
234
236
|
erase! 1
|
235
237
|
end
|
236
238
|
if node.style == :expanded
|
@@ -242,6 +244,8 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
242
244
|
ensure
|
243
245
|
@in_directive = was_in_directive
|
244
246
|
end
|
247
|
+
# @comment
|
248
|
+
# rubocop:enable MethodLength
|
245
249
|
|
246
250
|
def visit_media(node)
|
247
251
|
with_tabs(@tabs + node.tabs) {visit_directive(node)}
|
@@ -257,22 +261,22 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
257
261
|
end
|
258
262
|
|
259
263
|
def visit_prop(node)
|
260
|
-
return if node.resolved_value.empty?
|
264
|
+
return if node.resolved_value.empty?
|
261
265
|
tab_str = ' ' * (@tabs + node.tabs)
|
262
266
|
output(tab_str)
|
263
267
|
for_node(node, :name) {output(node.resolved_name)}
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
end)
|
268
|
+
if node.style == :compressed
|
269
|
+
output(":")
|
270
|
+
for_node(node, :value) {output(node.resolved_value)}
|
271
|
+
else
|
272
|
+
output(": ")
|
273
|
+
for_node(node, :value) {output(node.resolved_value)}
|
274
|
+
output(";")
|
272
275
|
end
|
273
|
-
output(";") unless node.style == :compressed
|
274
276
|
end
|
275
277
|
|
278
|
+
# @comment
|
279
|
+
# rubocop:disable MethodLength
|
276
280
|
def visit_rule(node)
|
277
281
|
with_tabs(@tabs + node.tabs) do
|
278
282
|
rule_separator = node.style == :compressed ? ',' : ', '
|
@@ -290,15 +294,12 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
290
294
|
end
|
291
295
|
|
292
296
|
joined_rules = node.resolved_rules.members.map do |seq|
|
293
|
-
next if seq.
|
294
|
-
rule_part = seq.to_s
|
297
|
+
next if seq.has_placeholder?
|
298
|
+
rule_part = seq.to_s
|
295
299
|
if node.style == :compressed
|
296
300
|
rule_part.gsub!(/([^,])\s*\n\s*/m, '\1 ')
|
297
|
-
rule_part.gsub!(/\s*([
|
298
|
-
rule_part.
|
299
|
-
match.tr(" \t\n", "")
|
300
|
-
end
|
301
|
-
rule_part = Sass::Util.strip_except_escapes(rule_part)
|
301
|
+
rule_part.gsub!(/\s*([-,+>])\s*/m, '\1')
|
302
|
+
rule_part.strip!
|
302
303
|
end
|
303
304
|
rule_part
|
304
305
|
end.compact.join(rule_separator)
|
@@ -336,7 +337,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
336
337
|
end
|
337
338
|
end
|
338
339
|
|
339
|
-
end_props, trailer, tabs
|
340
|
+
end_props, trailer, tabs = '', '', 0
|
340
341
|
if node.style == :compact
|
341
342
|
separator, end_props, bracket = ' ', ' ', ' { '
|
342
343
|
trailer = "\n" if node.group_end
|
@@ -355,7 +356,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
355
356
|
with_tabs(tabs) do
|
356
357
|
node.children.each_with_index do |child, i|
|
357
358
|
if i > 0
|
358
|
-
if separator.start_with?(";") &&
|
359
|
+
if separator.start_with?(";") && ends_with?(";")
|
359
360
|
erase! 1
|
360
361
|
end
|
361
362
|
output(separator)
|
@@ -363,7 +364,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
363
364
|
visit(child)
|
364
365
|
end
|
365
366
|
end
|
366
|
-
if node.style == :compressed &&
|
367
|
+
if node.style == :compressed && ends_with?(";")
|
367
368
|
erase! 1
|
368
369
|
end
|
369
370
|
|
@@ -371,6 +372,8 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
371
372
|
output("}" + trailer)
|
372
373
|
end
|
373
374
|
end
|
375
|
+
# @comment
|
376
|
+
# rubocop:enable MethodLength
|
374
377
|
|
375
378
|
def visit_keyframerule(node)
|
376
379
|
visit_directive(node)
|
@@ -378,51 +381,18 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
378
381
|
|
379
382
|
private
|
380
383
|
|
381
|
-
# Reformats the value of `node` so that it's nicely indented, preserving its
|
382
|
-
# existing relative indentation.
|
383
|
-
#
|
384
|
-
# @param node [Sass::Script::Tree::PropNode] A custom property node.
|
385
|
-
# @return [String]
|
386
|
-
def format_custom_property_value(node)
|
387
|
-
value = node.resolved_value.sub(/\n[ \t\r\f\n]*\Z/, ' ')
|
388
|
-
if node.style == :compact || node.style == :compressed || !value.include?("\n")
|
389
|
-
# Folding not involving newlines was done in the parser. We can safely
|
390
|
-
# fold newlines here because tokens like strings can't contain literal
|
391
|
-
# newlines, so we know any adjacent whitespace is tokenized as whitespace.
|
392
|
-
return node.resolved_value.gsub(/[ \t\r\f]*\n[ \t\r\f\n]*/, ' ')
|
393
|
-
end
|
394
|
-
|
395
|
-
# Find the smallest amount of indentation in the custom property and use
|
396
|
-
# that as the base indentation level.
|
397
|
-
lines = value.split("\n")
|
398
|
-
indented_lines = lines[1..-1]
|
399
|
-
min_indentation = indented_lines.
|
400
|
-
map {|line| line[/^[ \t]*/]}.
|
401
|
-
reject {|line| line.empty?}.
|
402
|
-
min_by {|line| line.length}
|
403
|
-
|
404
|
-
# Limit the base indentation to the same indentation level as the node name
|
405
|
-
# so that if *every* line is indented relative to the property name that's
|
406
|
-
# preserved.
|
407
|
-
if node.name_source_range
|
408
|
-
base_indentation = min_indentation[0...node.name_source_range.start_pos.offset - 1]
|
409
|
-
end
|
410
|
-
|
411
|
-
lines.first + "\n" + indented_lines.join("\n").gsub(/^#{base_indentation}/, ' ' * @tabs)
|
412
|
-
end
|
413
|
-
|
414
384
|
def debug_info_rule(debug_info, options)
|
415
385
|
node = Sass::Tree::DirectiveNode.resolved("@media -sass-debug-info")
|
416
|
-
debug_info.map {|k, v| [k.to_s, v.to_s]}.
|
386
|
+
Sass::Util.hash_to_a(debug_info.map {|k, v| [k.to_s, v.to_s]}).each do |k, v|
|
417
387
|
rule = Sass::Tree::RuleNode.new([""])
|
418
388
|
rule.resolved_rules = Sass::Selector::CommaSequence.new(
|
419
389
|
[Sass::Selector::Sequence.new(
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
390
|
+
[Sass::Selector::SimpleSequence.new(
|
391
|
+
[Sass::Selector::Element.new(k.to_s.gsub(/[^\w-]/, "\\\\\\0"), nil)],
|
392
|
+
false)
|
393
|
+
])
|
424
394
|
])
|
425
|
-
prop = Sass::Tree::PropNode.new([""],
|
395
|
+
prop = Sass::Tree::PropNode.new([""], Sass::Script::Value::String.new(''), :new)
|
426
396
|
prop.resolved_name = "font-family"
|
427
397
|
prop.resolved_value = Sass::SCSS::RX.escape_ident(v.to_s)
|
428
398
|
rule << prop
|