sass 3.1.0 → 3.3.0
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 +7 -0
- data/CONTRIBUTING +1 -1
- data/MIT-LICENSE +2 -2
- data/README.md +29 -17
- data/Rakefile +43 -9
- data/VERSION +1 -1
- data/VERSION_DATE +1 -0
- data/VERSION_NAME +1 -1
- data/bin/sass +6 -1
- data/bin/sass-convert +6 -1
- data/bin/scss +6 -1
- data/ext/mkrf_conf.rb +27 -0
- data/lib/sass/cache_stores/base.rb +7 -3
- data/lib/sass/cache_stores/chain.rb +3 -2
- data/lib/sass/cache_stores/filesystem.rb +5 -7
- data/lib/sass/cache_stores/memory.rb +1 -1
- data/lib/sass/cache_stores/null.rb +2 -2
- data/lib/sass/callbacks.rb +2 -1
- data/lib/sass/css.rb +168 -53
- data/lib/sass/engine.rb +502 -174
- data/lib/sass/environment.rb +151 -111
- data/lib/sass/error.rb +7 -7
- data/lib/sass/exec.rb +176 -60
- data/lib/sass/features.rb +40 -0
- data/lib/sass/importers/base.rb +46 -7
- data/lib/sass/importers/deprecated_path.rb +51 -0
- data/lib/sass/importers/filesystem.rb +113 -30
- data/lib/sass/importers.rb +1 -0
- data/lib/sass/logger/base.rb +30 -0
- data/lib/sass/logger/log_level.rb +45 -0
- data/lib/sass/logger.rb +12 -0
- data/lib/sass/media.rb +213 -0
- data/lib/sass/plugin/compiler.rb +194 -104
- data/lib/sass/plugin/configuration.rb +18 -25
- data/lib/sass/plugin/merb.rb +1 -1
- data/lib/sass/plugin/staleness_checker.rb +37 -11
- data/lib/sass/plugin.rb +10 -13
- data/lib/sass/railtie.rb +2 -1
- data/lib/sass/repl.rb +5 -6
- data/lib/sass/script/css_lexer.rb +8 -4
- data/lib/sass/script/css_parser.rb +5 -2
- data/lib/sass/script/functions.rb +1547 -618
- data/lib/sass/script/lexer.rb +122 -72
- data/lib/sass/script/parser.rb +304 -135
- data/lib/sass/script/tree/funcall.rb +306 -0
- data/lib/sass/script/{interpolation.rb → tree/interpolation.rb} +43 -13
- data/lib/sass/script/tree/list_literal.rb +77 -0
- data/lib/sass/script/tree/literal.rb +45 -0
- data/lib/sass/script/tree/map_literal.rb +64 -0
- data/lib/sass/script/{node.rb → tree/node.rb} +30 -12
- data/lib/sass/script/{operation.rb → tree/operation.rb} +33 -21
- data/lib/sass/script/{string_interpolation.rb → tree/string_interpolation.rb} +14 -4
- data/lib/sass/script/{unary_operation.rb → tree/unary_operation.rb} +21 -9
- data/lib/sass/script/tree/variable.rb +57 -0
- data/lib/sass/script/tree.rb +15 -0
- data/lib/sass/script/value/arg_list.rb +36 -0
- data/lib/sass/script/value/base.rb +238 -0
- data/lib/sass/script/value/bool.rb +40 -0
- data/lib/sass/script/{color.rb → value/color.rb} +256 -74
- data/lib/sass/script/value/deprecated_false.rb +55 -0
- data/lib/sass/script/value/helpers.rb +155 -0
- data/lib/sass/script/value/list.rb +128 -0
- data/lib/sass/script/value/map.rb +70 -0
- data/lib/sass/script/value/null.rb +49 -0
- data/lib/sass/script/{number.rb → value/number.rb} +115 -62
- data/lib/sass/script/{string.rb → value/string.rb} +9 -11
- data/lib/sass/script/value.rb +12 -0
- data/lib/sass/script.rb +35 -9
- data/lib/sass/scss/css_parser.rb +2 -12
- data/lib/sass/scss/parser.rb +657 -230
- data/lib/sass/scss/rx.rb +17 -12
- data/lib/sass/scss/static_parser.rb +37 -6
- data/lib/sass/scss.rb +0 -1
- data/lib/sass/selector/abstract_sequence.rb +35 -3
- data/lib/sass/selector/comma_sequence.rb +29 -14
- data/lib/sass/selector/sequence.rb +371 -74
- data/lib/sass/selector/simple.rb +28 -13
- data/lib/sass/selector/simple_sequence.rb +163 -36
- data/lib/sass/selector.rb +138 -36
- data/lib/sass/shared.rb +3 -5
- data/lib/sass/source/map.rb +196 -0
- data/lib/sass/source/position.rb +39 -0
- data/lib/sass/source/range.rb +41 -0
- data/lib/sass/stack.rb +126 -0
- data/lib/sass/supports.rb +228 -0
- data/lib/sass/tree/at_root_node.rb +82 -0
- data/lib/sass/tree/comment_node.rb +34 -29
- data/lib/sass/tree/content_node.rb +9 -0
- data/lib/sass/tree/css_import_node.rb +60 -0
- data/lib/sass/tree/debug_node.rb +3 -3
- data/lib/sass/tree/directive_node.rb +33 -3
- data/lib/sass/tree/each_node.rb +9 -9
- data/lib/sass/tree/extend_node.rb +20 -6
- data/lib/sass/tree/for_node.rb +6 -6
- data/lib/sass/tree/function_node.rb +12 -4
- data/lib/sass/tree/if_node.rb +2 -15
- data/lib/sass/tree/import_node.rb +11 -5
- data/lib/sass/tree/media_node.rb +27 -11
- data/lib/sass/tree/mixin_def_node.rb +15 -4
- data/lib/sass/tree/mixin_node.rb +27 -7
- data/lib/sass/tree/node.rb +69 -35
- data/lib/sass/tree/prop_node.rb +47 -31
- data/lib/sass/tree/return_node.rb +4 -3
- data/lib/sass/tree/root_node.rb +20 -4
- data/lib/sass/tree/rule_node.rb +37 -26
- data/lib/sass/tree/supports_node.rb +38 -0
- data/lib/sass/tree/trace_node.rb +33 -0
- data/lib/sass/tree/variable_node.rb +10 -4
- data/lib/sass/tree/visitors/base.rb +5 -8
- data/lib/sass/tree/visitors/check_nesting.rb +67 -52
- data/lib/sass/tree/visitors/convert.rb +134 -53
- data/lib/sass/tree/visitors/cssize.rb +245 -51
- data/lib/sass/tree/visitors/deep_copy.rb +102 -0
- data/lib/sass/tree/visitors/extend.rb +68 -0
- data/lib/sass/tree/visitors/perform.rb +331 -105
- data/lib/sass/tree/visitors/set_options.rb +125 -0
- data/lib/sass/tree/visitors/to_css.rb +259 -95
- data/lib/sass/tree/warn_node.rb +3 -3
- data/lib/sass/tree/while_node.rb +3 -3
- data/lib/sass/util/cross_platform_random.rb +19 -0
- data/lib/sass/util/multibyte_string_scanner.rb +157 -0
- data/lib/sass/util/normalized_map.rb +130 -0
- data/lib/sass/util/ordered_hash.rb +192 -0
- data/lib/sass/util/subset_map.rb +11 -2
- data/lib/sass/util/test.rb +9 -0
- data/lib/sass/util.rb +565 -39
- data/lib/sass/version.rb +27 -15
- data/lib/sass.rb +39 -4
- data/test/sass/cache_test.rb +15 -0
- data/test/sass/compiler_test.rb +223 -0
- data/test/sass/conversion_test.rb +901 -107
- data/test/sass/css2sass_test.rb +94 -0
- data/test/sass/engine_test.rb +1059 -164
- data/test/sass/exec_test.rb +86 -0
- data/test/sass/extend_test.rb +933 -837
- 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 +995 -136
- data/test/sass/importer_test.rb +338 -18
- data/test/sass/logger_test.rb +58 -0
- data/test/sass/more_results/more_import.css +2 -2
- data/test/sass/plugin_test.rb +114 -30
- data/test/sass/results/cached_import_option.css +3 -0
- data/test/sass/results/filename_fn.css +3 -0
- data/test/sass/results/import.css +2 -2
- data/test/sass/results/import_charset.css +1 -0
- data/test/sass/results/import_charset_1_8.css +1 -0
- data/test/sass/results/import_charset_ibm866.css +1 -0
- data/test/sass/results/import_content.css +1 -0
- data/test/sass/results/script.css +1 -1
- data/test/sass/results/scss_import.css +2 -2
- data/test/sass/results/units.css +2 -2
- data/test/sass/script_conversion_test.rb +43 -1
- data/test/sass/script_test.rb +380 -36
- data/test/sass/scss/css_test.rb +257 -75
- data/test/sass/scss/scss_test.rb +2322 -110
- data/test/sass/source_map_test.rb +887 -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_content.sass +3 -0
- data/test/sass/templates/_same_name_different_partiality.scss +1 -0
- data/test/sass/templates/bork5.sass +3 -0
- data/test/sass/templates/cached_import_option.scss +3 -0
- data/test/sass/templates/double_import_loop1.sass +1 -0
- data/test/sass/templates/filename_fn.scss +18 -0
- data/test/sass/templates/import_charset.sass +2 -0
- data/test/sass/templates/import_charset_1_8.sass +2 -0
- data/test/sass/templates/import_charset_ibm866.sass +2 -0
- data/test/sass/templates/import_content.sass +4 -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/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/test_helper.rb +1 -1
- 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_test.rb +183 -0
- data/test/sass/value_helpers_test.rb +181 -0
- data/test/test_helper.rb +45 -5
- data/vendor/listen/CHANGELOG.md +228 -0
- data/vendor/listen/CONTRIBUTING.md +38 -0
- data/vendor/listen/Gemfile +30 -0
- data/vendor/listen/Guardfile +8 -0
- data/vendor/{fssm → listen}/LICENSE +1 -1
- data/vendor/listen/README.md +315 -0
- data/vendor/listen/Rakefile +47 -0
- data/vendor/listen/Vagrantfile +96 -0
- data/vendor/listen/lib/listen/adapter.rb +214 -0
- data/vendor/listen/lib/listen/adapters/bsd.rb +112 -0
- data/vendor/listen/lib/listen/adapters/darwin.rb +85 -0
- data/vendor/listen/lib/listen/adapters/linux.rb +113 -0
- data/vendor/listen/lib/listen/adapters/polling.rb +67 -0
- data/vendor/listen/lib/listen/adapters/windows.rb +87 -0
- data/vendor/listen/lib/listen/dependency_manager.rb +126 -0
- data/vendor/listen/lib/listen/directory_record.rb +371 -0
- data/vendor/listen/lib/listen/listener.rb +225 -0
- data/vendor/listen/lib/listen/multi_listener.rb +143 -0
- data/vendor/listen/lib/listen/turnstile.rb +28 -0
- data/vendor/listen/lib/listen/version.rb +3 -0
- data/vendor/listen/lib/listen.rb +40 -0
- data/vendor/listen/listen.gemspec +22 -0
- data/vendor/listen/spec/listen/adapter_spec.rb +183 -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/dependency_manager_spec.rb +107 -0
- data/vendor/listen/spec/listen/directory_record_spec.rb +1225 -0
- data/vendor/listen/spec/listen/listener_spec.rb +169 -0
- data/vendor/listen/spec/listen/multi_listener_spec.rb +174 -0
- data/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
- data/vendor/listen/spec/listen_spec.rb +73 -0
- data/vendor/listen/spec/spec_helper.rb +21 -0
- data/vendor/listen/spec/support/adapter_helper.rb +629 -0
- data/vendor/listen/spec/support/directory_record_helper.rb +55 -0
- data/vendor/listen/spec/support/fixtures_helper.rb +29 -0
- data/vendor/listen/spec/support/listeners_helper.rb +156 -0
- data/vendor/listen/spec/support/platform_helper.rb +15 -0
- metadata +344 -271
- data/lib/sass/less.rb +0 -382
- data/lib/sass/script/bool.rb +0 -18
- data/lib/sass/script/funcall.rb +0 -162
- data/lib/sass/script/list.rb +0 -76
- data/lib/sass/script/literal.rb +0 -245
- data/lib/sass/script/variable.rb +0 -54
- data/lib/sass/scss/sass_parser.rb +0 -11
- data/test/sass/less_conversion_test.rb +0 -653
- data/vendor/fssm/README.markdown +0 -55
- data/vendor/fssm/Rakefile +0 -59
- data/vendor/fssm/VERSION.yml +0 -5
- data/vendor/fssm/example.rb +0 -9
- data/vendor/fssm/fssm.gemspec +0 -77
- data/vendor/fssm/lib/fssm/backends/fsevents.rb +0 -36
- data/vendor/fssm/lib/fssm/backends/inotify.rb +0 -26
- data/vendor/fssm/lib/fssm/backends/polling.rb +0 -25
- data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +0 -131
- data/vendor/fssm/lib/fssm/monitor.rb +0 -26
- data/vendor/fssm/lib/fssm/path.rb +0 -91
- data/vendor/fssm/lib/fssm/pathname.rb +0 -502
- data/vendor/fssm/lib/fssm/state/directory.rb +0 -57
- data/vendor/fssm/lib/fssm/state/file.rb +0 -24
- data/vendor/fssm/lib/fssm/support.rb +0 -63
- data/vendor/fssm/lib/fssm/tree.rb +0 -176
- data/vendor/fssm/lib/fssm.rb +0 -33
- data/vendor/fssm/profile/prof-cache.rb +0 -40
- data/vendor/fssm/profile/prof-fssm-pathname.html +0 -1231
- data/vendor/fssm/profile/prof-pathname.rb +0 -68
- data/vendor/fssm/profile/prof-plain-pathname.html +0 -988
- data/vendor/fssm/profile/prof.html +0 -2379
- data/vendor/fssm/spec/path_spec.rb +0 -75
- data/vendor/fssm/spec/root/duck/quack.txt +0 -0
- data/vendor/fssm/spec/root/file.css +0 -0
- data/vendor/fssm/spec/root/file.rb +0 -0
- data/vendor/fssm/spec/root/file.yml +0 -0
- data/vendor/fssm/spec/root/moo/cow.txt +0 -0
- data/vendor/fssm/spec/spec_helper.rb +0 -14
@@ -0,0 +1,125 @@
|
|
1
|
+
# A visitor for setting options on the Sass tree
|
2
|
+
class Sass::Tree::Visitors::SetOptions < Sass::Tree::Visitors::Base
|
3
|
+
# @param root [Tree::Node] The root node of the tree to visit.
|
4
|
+
# @param options [{Symbol => Object}] The options has to set.
|
5
|
+
def self.visit(root, options); new(options).send(:visit, root); end
|
6
|
+
|
7
|
+
protected
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
@options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def visit(node)
|
14
|
+
node.instance_variable_set('@options', @options)
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def visit_debug(node)
|
19
|
+
node.expr.options = @options
|
20
|
+
yield
|
21
|
+
end
|
22
|
+
|
23
|
+
def visit_each(node)
|
24
|
+
node.list.options = @options
|
25
|
+
yield
|
26
|
+
end
|
27
|
+
|
28
|
+
def visit_extend(node)
|
29
|
+
node.selector.each {|c| c.options = @options if c.is_a?(Sass::Script::Tree::Node)}
|
30
|
+
yield
|
31
|
+
end
|
32
|
+
|
33
|
+
def visit_for(node)
|
34
|
+
node.from.options = @options
|
35
|
+
node.to.options = @options
|
36
|
+
yield
|
37
|
+
end
|
38
|
+
|
39
|
+
def visit_function(node)
|
40
|
+
node.args.each do |k, v|
|
41
|
+
k.options = @options
|
42
|
+
v.options = @options if v
|
43
|
+
end
|
44
|
+
yield
|
45
|
+
end
|
46
|
+
|
47
|
+
def visit_if(node)
|
48
|
+
node.expr.options = @options if node.expr
|
49
|
+
visit(node.else) if node.else
|
50
|
+
yield
|
51
|
+
end
|
52
|
+
|
53
|
+
def visit_import(node)
|
54
|
+
# We have no good way of propagating the new options through an Engine
|
55
|
+
# instance, so we just null it out. This also lets us avoid caching an
|
56
|
+
# imported Engine along with the importing source tree.
|
57
|
+
node.imported_file = nil
|
58
|
+
yield
|
59
|
+
end
|
60
|
+
|
61
|
+
def visit_mixindef(node)
|
62
|
+
node.args.each do |k, v|
|
63
|
+
k.options = @options
|
64
|
+
v.options = @options if v
|
65
|
+
end
|
66
|
+
yield
|
67
|
+
end
|
68
|
+
|
69
|
+
def visit_mixin(node)
|
70
|
+
node.args.each {|a| a.options = @options}
|
71
|
+
node.keywords.each {|k, v| v.options = @options}
|
72
|
+
yield
|
73
|
+
end
|
74
|
+
|
75
|
+
def visit_prop(node)
|
76
|
+
node.name.each {|c| c.options = @options if c.is_a?(Sass::Script::Tree::Node)}
|
77
|
+
node.value.options = @options
|
78
|
+
yield
|
79
|
+
end
|
80
|
+
|
81
|
+
def visit_return(node)
|
82
|
+
node.expr.options = @options
|
83
|
+
yield
|
84
|
+
end
|
85
|
+
|
86
|
+
def visit_rule(node)
|
87
|
+
node.rule.each {|c| c.options = @options if c.is_a?(Sass::Script::Tree::Node)}
|
88
|
+
yield
|
89
|
+
end
|
90
|
+
|
91
|
+
def visit_variable(node)
|
92
|
+
node.expr.options = @options
|
93
|
+
yield
|
94
|
+
end
|
95
|
+
|
96
|
+
def visit_warn(node)
|
97
|
+
node.expr.options = @options
|
98
|
+
yield
|
99
|
+
end
|
100
|
+
|
101
|
+
def visit_while(node)
|
102
|
+
node.expr.options = @options
|
103
|
+
yield
|
104
|
+
end
|
105
|
+
|
106
|
+
def visit_directive(node)
|
107
|
+
node.value.each {|c| c.options = @options if c.is_a?(Sass::Script::Tree::Node)}
|
108
|
+
yield
|
109
|
+
end
|
110
|
+
|
111
|
+
def visit_media(node)
|
112
|
+
node.query.each {|c| c.options = @options if c.is_a?(Sass::Script::Tree::Node)}
|
113
|
+
yield
|
114
|
+
end
|
115
|
+
|
116
|
+
def visit_cssimport(node)
|
117
|
+
node.query.each {|c| c.options = @options if c.is_a?(Sass::Script::Tree::Node)} if node.query
|
118
|
+
yield
|
119
|
+
end
|
120
|
+
|
121
|
+
def visit_supports(node)
|
122
|
+
node.condition.options = @options
|
123
|
+
yield
|
124
|
+
end
|
125
|
+
end
|
@@ -1,11 +1,25 @@
|
|
1
1
|
# A visitor for converting a Sass tree into CSS.
|
2
2
|
class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
3
|
-
|
3
|
+
# The source mapping for the generated CSS file. This is only set if
|
4
|
+
# `build_source_mapping` is passed to the constructor and \{Sass::Engine#render} has been
|
5
|
+
# run.
|
6
|
+
attr_reader :source_mapping
|
4
7
|
|
5
|
-
|
8
|
+
# @param build_source_mapping [Boolean] Whether to build a
|
9
|
+
# \{Sass::Source::Map} while creating the CSS output. The mapping will
|
10
|
+
# be available from \{#source\_mapping} after the visitor has completed.
|
11
|
+
def initialize(build_source_mapping = false)
|
6
12
|
@tabs = 0
|
13
|
+
@line = 1
|
14
|
+
@offset = 1
|
15
|
+
@result = ""
|
16
|
+
@source_mapping = Sass::Source::Map.new if build_source_mapping
|
7
17
|
end
|
8
18
|
|
19
|
+
# Runs the visitor on `node`.
|
20
|
+
#
|
21
|
+
# @param node [Sass::Tree::Node] The root node of the tree to convert to CSS>
|
22
|
+
# @return [String] The CSS output.
|
9
23
|
def visit(node)
|
10
24
|
super
|
11
25
|
rescue Sass::SyntaxError => e
|
@@ -13,6 +27,8 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
13
27
|
raise e
|
14
28
|
end
|
15
29
|
|
30
|
+
protected
|
31
|
+
|
16
32
|
def with_tabs(tabs)
|
17
33
|
old_tabs, @tabs = @tabs, tabs
|
18
34
|
yield
|
@@ -20,197 +36,345 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
20
36
|
@tabs = old_tabs
|
21
37
|
end
|
22
38
|
|
39
|
+
# Associate all output produced in a block with a given node. Used for source
|
40
|
+
# mapping.
|
41
|
+
def for_node(node, attr_prefix = nil)
|
42
|
+
return yield unless @source_mapping
|
43
|
+
start_pos = Sass::Source::Position.new(@line, @offset)
|
44
|
+
yield
|
45
|
+
|
46
|
+
range_attr = attr_prefix ? :"#{attr_prefix}_source_range" : :source_range
|
47
|
+
return if node.invisible? || !node.send(range_attr)
|
48
|
+
source_range = node.send(range_attr)
|
49
|
+
target_end_pos = Sass::Source::Position.new(@line, @offset)
|
50
|
+
target_range = Sass::Source::Range.new(start_pos, target_end_pos, nil)
|
51
|
+
@source_mapping.add(source_range, target_range)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Move the output cursor back `chars` characters.
|
55
|
+
def erase!(chars)
|
56
|
+
return if chars == 0
|
57
|
+
str = @result.slice!(-chars..-1)
|
58
|
+
newlines = str.count("\n")
|
59
|
+
if newlines > 0
|
60
|
+
@line -= newlines
|
61
|
+
@offset = @result[@result.rindex("\n") || 0..-1].size
|
62
|
+
else
|
63
|
+
@offset -= chars
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Avoid allocating lots of new strings for `#output`. This is important
|
68
|
+
# because `#output` is called all the time.
|
69
|
+
NEWLINE = "\n"
|
70
|
+
|
71
|
+
# Add `s` to the output string and update the line and offset information
|
72
|
+
# accordingly.
|
73
|
+
def output(s)
|
74
|
+
if @lstrip
|
75
|
+
s = s.gsub(/\A\s+/, "")
|
76
|
+
@lstrip = false
|
77
|
+
end
|
78
|
+
|
79
|
+
newlines = s.count(NEWLINE)
|
80
|
+
if newlines > 0
|
81
|
+
@line += newlines
|
82
|
+
@offset = s[s.rindex(NEWLINE)..-1].size
|
83
|
+
else
|
84
|
+
@offset += s.size
|
85
|
+
end
|
86
|
+
|
87
|
+
@result << s
|
88
|
+
end
|
89
|
+
|
90
|
+
# Strip all trailing whitespace from the output string.
|
91
|
+
def rstrip!
|
92
|
+
erase! @result.length - 1 - (@result.rindex(/[^\s]/) || -1)
|
93
|
+
end
|
94
|
+
|
95
|
+
# lstrip the first output in the given block.
|
96
|
+
def lstrip
|
97
|
+
old_lstrip = @lstrip
|
98
|
+
@lstrip = true
|
99
|
+
yield
|
100
|
+
ensure
|
101
|
+
@lstrip = @lstrip && old_lstrip
|
102
|
+
end
|
103
|
+
|
104
|
+
# Prepend `prefix` to the output string.
|
105
|
+
def prepend!(prefix)
|
106
|
+
@result.insert 0, prefix
|
107
|
+
return unless @source_mapping
|
108
|
+
|
109
|
+
line_delta = prefix.count("\n")
|
110
|
+
offset_delta = prefix.gsub(/.*\n/, '').size
|
111
|
+
@source_mapping.shift_output_offsets(offset_delta)
|
112
|
+
@source_mapping.shift_output_lines(line_delta)
|
113
|
+
end
|
114
|
+
|
23
115
|
def visit_root(node)
|
24
|
-
result = String.new
|
25
116
|
node.children.each do |child|
|
26
117
|
next if child.invisible?
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
result << "\n"
|
33
|
-
unless Sass::Util.ruby1_8? || result.ascii_only?
|
34
|
-
if node.children.first.is_a?(Sass::Tree::CharsetNode)
|
35
|
-
begin
|
36
|
-
encoding = node.children.first.name
|
37
|
-
# Default to big-endian encoding, because we have to decide somehow
|
38
|
-
encoding << 'BE' if encoding =~ /\Autf-(16|32)\Z/i
|
39
|
-
result = result.encode(Encoding.find(encoding))
|
40
|
-
rescue EncodingError
|
118
|
+
visit(child)
|
119
|
+
unless node.style == :compressed
|
120
|
+
output "\n"
|
121
|
+
if child.is_a?(Sass::Tree::DirectiveNode) && child.has_children && !child.bubbles?
|
122
|
+
output "\n"
|
41
123
|
end
|
42
124
|
end
|
125
|
+
end
|
126
|
+
rstrip!
|
127
|
+
return "" if @result.empty?
|
43
128
|
|
44
|
-
|
45
|
-
|
46
|
-
|
129
|
+
output "\n"
|
130
|
+
return @result if Sass::Util.ruby1_8? || @result.ascii_only?
|
131
|
+
|
132
|
+
if node.children.first.is_a?(Sass::Tree::CharsetNode)
|
133
|
+
begin
|
134
|
+
encoding = node.children.first.name
|
135
|
+
# Default to big-endian encoding, because we have to decide somehow
|
136
|
+
encoding << 'BE' if encoding =~ /\Autf-(16|32)\Z/i
|
137
|
+
@result = @result.encode(Encoding.find(encoding))
|
138
|
+
rescue EncodingError
|
139
|
+
end
|
47
140
|
end
|
48
|
-
|
141
|
+
|
142
|
+
prepend! "@charset \"#{@result.encoding.name}\";#{
|
143
|
+
node.style == :compressed ? '' : "\n"
|
144
|
+
}".encode(@result.encoding)
|
145
|
+
@result
|
49
146
|
rescue Sass::SyntaxError => e
|
50
147
|
e.sass_template ||= node.template
|
51
148
|
raise e
|
52
149
|
end
|
53
150
|
|
54
151
|
def visit_charset(node)
|
55
|
-
"@charset \"#{node.name}\";"
|
56
|
-
end
|
152
|
+
for_node(node) {output("@charset \"#{node.name}\";")}
|
153
|
+
end
|
57
154
|
|
58
155
|
def visit_comment(node)
|
59
156
|
return if node.invisible?
|
60
|
-
spaces = (' ' * [@tabs - node.
|
157
|
+
spaces = (' ' * [@tabs - node.resolved_value[/^ */].size, 0].max)
|
61
158
|
|
62
|
-
content = node.
|
63
|
-
|
159
|
+
content = node.resolved_value.gsub(/^/, spaces)
|
160
|
+
if node.type == :silent
|
161
|
+
content.gsub!(%r{^(\s*)//(.*)$}) {|md| "#{$1}/*#{$2} */"}
|
64
162
|
end
|
65
|
-
if
|
66
|
-
|
67
|
-
WARNING:
|
68
|
-
On line #{node.line}#{" of '#{node.filename}'" if node.filename}
|
69
|
-
Comments will evaluate the contents of interpolations (\#{ ... }) in Sass 3.2.
|
70
|
-
Please escape the interpolation by adding a backslash before the hash sign.
|
71
|
-
MESSAGE
|
72
|
-
elsif content =~ /\\\#\{.*\}/
|
73
|
-
content.gsub!(/\\(\#\{.*\})/, '\1')
|
163
|
+
if (node.style == :compact || node.style == :compressed) && node.type != :loud
|
164
|
+
content.gsub!(/\n +(\* *(?!\/))?/, ' ')
|
74
165
|
end
|
75
|
-
|
76
|
-
content
|
166
|
+
for_node(node) {output(content)}
|
77
167
|
end
|
78
168
|
|
169
|
+
# @comment
|
170
|
+
# rubocop:disable MethodLength
|
79
171
|
def visit_directive(node)
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
172
|
+
was_in_directive = @in_directive
|
173
|
+
tab_str = ' ' * @tabs
|
174
|
+
if !node.has_children || node.children.empty?
|
175
|
+
output(tab_str)
|
176
|
+
for_node(node) {output(node.resolved_value)}
|
177
|
+
output(!node.has_children ? ";" : " {}")
|
178
|
+
return
|
179
|
+
end
|
180
|
+
|
181
|
+
@in_directive = @in_directive || !node.is_a?(Sass::Tree::MediaNode)
|
182
|
+
output(tab_str) if node.style != :compressed
|
183
|
+
for_node(node) {output(node.resolved_value)}
|
184
|
+
output(node.style == :compressed ? "{" : " {")
|
185
|
+
output(node.style == :compact ? ' ' : "\n") if node.style != :compressed
|
186
|
+
|
87
187
|
was_prop = false
|
88
188
|
first = true
|
89
189
|
node.children.each do |child|
|
90
190
|
next if child.invisible?
|
91
191
|
if node.style == :compact
|
92
192
|
if child.is_a?(Sass::Tree::PropNode)
|
93
|
-
with_tabs(first || was_prop ? 0 : @tabs + 1)
|
193
|
+
with_tabs(first || was_prop ? 0 : @tabs + 1) do
|
194
|
+
visit(child)
|
195
|
+
output(' ')
|
196
|
+
end
|
94
197
|
else
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
198
|
+
if was_prop
|
199
|
+
erase! 1
|
200
|
+
output "\n"
|
201
|
+
end
|
202
|
+
|
203
|
+
if first
|
204
|
+
lstrip {with_tabs(@tabs + 1) {visit(child)}}
|
205
|
+
else
|
206
|
+
with_tabs(@tabs + 1) {visit(child)}
|
207
|
+
end
|
208
|
+
|
209
|
+
rstrip!
|
210
|
+
output "\n"
|
99
211
|
end
|
100
212
|
was_prop = child.is_a?(Sass::Tree::PropNode)
|
101
213
|
first = false
|
102
214
|
elsif node.style == :compressed
|
103
|
-
|
215
|
+
output(was_prop ? ";" : "")
|
216
|
+
with_tabs(0) {visit(child)}
|
104
217
|
was_prop = child.is_a?(Sass::Tree::PropNode)
|
105
218
|
else
|
106
|
-
|
219
|
+
with_tabs(@tabs + 1) {visit(child)}
|
220
|
+
output "\n"
|
107
221
|
end
|
108
222
|
end
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
223
|
+
rstrip!
|
224
|
+
if node.style == :expanded
|
225
|
+
output("\n#{tab_str}")
|
226
|
+
elsif node.style != :compressed
|
227
|
+
output(" ")
|
228
|
+
end
|
229
|
+
output("}")
|
230
|
+
ensure
|
231
|
+
@in_directive = was_in_directive
|
114
232
|
end
|
233
|
+
# @comment
|
234
|
+
# rubocop:enable MethodLength
|
115
235
|
|
116
236
|
def visit_media(node)
|
117
|
-
|
118
|
-
|
119
|
-
|
237
|
+
with_tabs(@tabs + node.tabs) {visit_directive(node)}
|
238
|
+
output("\n") if node.group_end
|
239
|
+
end
|
240
|
+
|
241
|
+
def visit_supports(node)
|
242
|
+
visit_media(node)
|
243
|
+
end
|
244
|
+
|
245
|
+
def visit_cssimport(node)
|
246
|
+
visit_directive(node)
|
120
247
|
end
|
121
248
|
|
122
249
|
def visit_prop(node)
|
250
|
+
return if node.resolved_value.empty?
|
123
251
|
tab_str = ' ' * (@tabs + node.tabs)
|
252
|
+
output(tab_str)
|
253
|
+
for_node(node, :name) {output(node.resolved_name)}
|
124
254
|
if node.style == :compressed
|
125
|
-
"
|
255
|
+
output(":")
|
256
|
+
for_node(node, :value) {output(node.resolved_value)}
|
126
257
|
else
|
127
|
-
"
|
258
|
+
output(": ")
|
259
|
+
for_node(node, :value) {output(node.resolved_value)}
|
260
|
+
output(";")
|
128
261
|
end
|
129
262
|
end
|
130
263
|
|
264
|
+
# @comment
|
265
|
+
# rubocop:disable MethodLength
|
131
266
|
def visit_rule(node)
|
132
267
|
with_tabs(@tabs + node.tabs) do
|
133
268
|
rule_separator = node.style == :compressed ? ',' : ', '
|
134
269
|
line_separator =
|
135
270
|
case node.style
|
136
|
-
|
137
|
-
|
138
|
-
|
271
|
+
when :nested, :expanded; "\n"
|
272
|
+
when :compressed; ""
|
273
|
+
else; " "
|
139
274
|
end
|
140
275
|
rule_indent = ' ' * @tabs
|
141
|
-
per_rule_indent, total_indent = [:nested, :expanded].include?(node.style)
|
276
|
+
per_rule_indent, total_indent = if [:nested, :expanded].include?(node.style)
|
277
|
+
[rule_indent, '']
|
278
|
+
else
|
279
|
+
['', rule_indent]
|
280
|
+
end
|
142
281
|
|
143
282
|
joined_rules = node.resolved_rules.members.map do |seq|
|
283
|
+
next if seq.has_placeholder?
|
144
284
|
rule_part = seq.to_a.join
|
145
|
-
|
285
|
+
if node.style == :compressed
|
286
|
+
rule_part.gsub!(/([^,])\s*\n\s*/m, '\1 ')
|
287
|
+
rule_part.gsub!(/\s*([,+>])\s*/m, '\1')
|
288
|
+
rule_part.strip!
|
289
|
+
end
|
146
290
|
rule_part
|
147
|
-
end.join(rule_separator)
|
291
|
+
end.compact.join(rule_separator)
|
148
292
|
|
149
|
-
joined_rules.
|
293
|
+
joined_rules.lstrip!
|
150
294
|
joined_rules.gsub!(/\s*\n\s*/, "#{line_separator}#{per_rule_indent}")
|
151
|
-
total_rule = total_indent << joined_rules
|
152
295
|
|
153
|
-
to_return = ''
|
154
296
|
old_spaces = ' ' * @tabs
|
155
|
-
spaces = ' ' * (@tabs + 1)
|
156
297
|
if node.style != :compressed
|
157
|
-
if node.options[:debug_info]
|
158
|
-
|
298
|
+
if node.options[:debug_info] && !@in_directive
|
299
|
+
visit(debug_info_rule(node.debug_info, node.options))
|
300
|
+
output "\n"
|
301
|
+
elsif node.options[:trace_selectors]
|
302
|
+
output("#{old_spaces}/* ")
|
303
|
+
output(node.stack_trace.gsub("\n", "\n #{old_spaces}"))
|
304
|
+
output(" */\n")
|
159
305
|
elsif node.options[:line_comments]
|
160
|
-
|
306
|
+
output("#{old_spaces}/* line #{node.line}")
|
161
307
|
|
162
308
|
if node.filename
|
163
|
-
relative_filename =
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
309
|
+
relative_filename =
|
310
|
+
if node.options[:css_filename]
|
311
|
+
begin
|
312
|
+
Sass::Util.pathname(node.filename).relative_path_from(
|
313
|
+
Sass::Util.pathname(File.dirname(node.options[:css_filename]))).to_s
|
314
|
+
rescue ArgumentError
|
315
|
+
nil
|
316
|
+
end
|
169
317
|
end
|
170
|
-
end
|
171
318
|
relative_filename ||= node.filename
|
172
|
-
|
319
|
+
output(", #{relative_filename}")
|
173
320
|
end
|
174
321
|
|
175
|
-
|
322
|
+
output(" */\n")
|
176
323
|
end
|
177
324
|
end
|
178
325
|
|
326
|
+
end_props, trailer, tabs = '', '', 0
|
179
327
|
if node.style == :compact
|
180
|
-
|
181
|
-
|
328
|
+
separator, end_props, bracket = ' ', ' ', ' { '
|
329
|
+
trailer = "\n" if node.group_end
|
182
330
|
elsif node.style == :compressed
|
183
|
-
|
184
|
-
to_return << "#{total_rule}{#{properties}}"
|
331
|
+
separator, bracket = ';', '{'
|
185
332
|
else
|
186
|
-
|
333
|
+
tabs = @tabs + 1
|
334
|
+
separator, bracket = "\n", " {\n"
|
335
|
+
trailer = "\n" if node.group_end
|
187
336
|
end_props = (node.style == :expanded ? "\n" + old_spaces : ' ')
|
188
|
-
|
337
|
+
end
|
338
|
+
output(total_indent + per_rule_indent)
|
339
|
+
for_node(node, :selector) {output(joined_rules)}
|
340
|
+
output(bracket)
|
341
|
+
|
342
|
+
with_tabs(tabs) do
|
343
|
+
node.children.each_with_index do |child, i|
|
344
|
+
output(separator) if i > 0
|
345
|
+
visit(child)
|
346
|
+
end
|
189
347
|
end
|
190
348
|
|
191
|
-
|
349
|
+
output(end_props)
|
350
|
+
output("}" + trailer)
|
192
351
|
end
|
193
352
|
end
|
353
|
+
# @comment
|
354
|
+
# rubocop:enable MethodLength
|
194
355
|
|
195
356
|
private
|
196
357
|
|
197
358
|
def debug_info_rule(debug_info, options)
|
198
|
-
node = Sass::Tree::DirectiveNode.
|
199
|
-
debug_info.map {|k, v| [k.to_s, v.to_s]}.
|
359
|
+
node = Sass::Tree::DirectiveNode.resolved("@media -sass-debug-info")
|
360
|
+
Sass::Util.hash_to_a(debug_info.map {|k, v| [k.to_s, v.to_s]}).each do |k, v|
|
200
361
|
rule = Sass::Tree::RuleNode.new([""])
|
201
362
|
rule.resolved_rules = Sass::Selector::CommaSequence.new(
|
202
363
|
[Sass::Selector::Sequence.new(
|
203
364
|
[Sass::Selector::SimpleSequence.new(
|
204
|
-
[Sass::Selector::Element.new(k.to_s.gsub(/[^\w-]/, "\\\\\\0"), nil)]
|
365
|
+
[Sass::Selector::Element.new(k.to_s.gsub(/[^\w-]/, "\\\\\\0"), nil)],
|
366
|
+
false)
|
205
367
|
])
|
206
368
|
])
|
207
|
-
prop = Sass::Tree::PropNode.new([""],
|
369
|
+
prop = Sass::Tree::PropNode.new([""], Sass::Script::Value::String.new(''), :new)
|
208
370
|
prop.resolved_name = "font-family"
|
209
371
|
prop.resolved_value = Sass::SCSS::RX.escape_ident(v.to_s)
|
210
372
|
rule << prop
|
211
373
|
node << rule
|
212
374
|
end
|
213
|
-
node.options = options.merge(:debug_info => false,
|
375
|
+
node.options = options.merge(:debug_info => false,
|
376
|
+
:line_comments => false,
|
377
|
+
:style => :compressed)
|
214
378
|
node
|
215
379
|
end
|
216
380
|
end
|
data/lib/sass/tree/warn_node.rb
CHANGED
@@ -5,10 +5,10 @@ module Sass
|
|
5
5
|
# @see Sass::Tree
|
6
6
|
class WarnNode < Node
|
7
7
|
# The expression to print.
|
8
|
-
# @return [Script::Node]
|
9
|
-
|
8
|
+
# @return [Script::Tree::Node]
|
9
|
+
attr_accessor :expr
|
10
10
|
|
11
|
-
# @param expr [Script::Node] The expression to print
|
11
|
+
# @param expr [Script::Tree::Node] The expression to print
|
12
12
|
def initialize(expr)
|
13
13
|
@expr = expr
|
14
14
|
super()
|
data/lib/sass/tree/while_node.rb
CHANGED
@@ -6,10 +6,10 @@ module Sass::Tree
|
|
6
6
|
# @see Sass::Tree
|
7
7
|
class WhileNode < Node
|
8
8
|
# The parse tree for the continuation expression.
|
9
|
-
# @return [Script::Node]
|
10
|
-
|
9
|
+
# @return [Script::Tree::Node]
|
10
|
+
attr_accessor :expr
|
11
11
|
|
12
|
-
# @param expr [Script::Node] See \{#expr}
|
12
|
+
# @param expr [Script::Tree::Node] See \{#expr}
|
13
13
|
def initialize(expr)
|
14
14
|
@expr = expr
|
15
15
|
super()
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Sass
|
2
|
+
module Util
|
3
|
+
# Ruby 1.8 doesn't support an actual Random class with a settable seed.
|
4
|
+
class CrossPlatformRandom
|
5
|
+
def initialize(seed = nil)
|
6
|
+
if Sass::Util.ruby1_8?
|
7
|
+
srand(seed) if seed
|
8
|
+
else
|
9
|
+
@random = seed ? ::Random.new(seed) : ::Random.new
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def rand(*args)
|
14
|
+
return @random.rand(*args) if @random
|
15
|
+
Kernel.rand(*args)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|