sass 3.1.21 → 3.2.0.alpha.3
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.
- data/README.md +5 -4
- data/REVISION +1 -1
- data/Rakefile +6 -15
- data/VERSION +1 -1
- data/VERSION_NAME +1 -1
- data/lib/sass.rb +0 -1
- data/lib/sass/cache_stores/base.rb +1 -3
- data/lib/sass/cache_stores/filesystem.rb +0 -3
- data/lib/sass/css.rb +49 -145
- data/lib/sass/engine.rb +23 -47
- data/lib/sass/environment.rb +5 -30
- data/lib/sass/exec.rb +7 -30
- data/lib/sass/importers/base.rb +1 -2
- data/lib/sass/importers/filesystem.rb +13 -18
- data/lib/sass/less.rb +1 -1
- data/lib/sass/plugin.rb +8 -4
- data/lib/sass/plugin/compiler.rb +67 -93
- data/lib/sass/plugin/configuration.rb +2 -0
- data/lib/sass/plugin/staleness_checker.rb +4 -14
- data/lib/sass/repl.rb +3 -2
- data/lib/sass/script.rb +1 -0
- data/lib/sass/script/color.rb +9 -4
- data/lib/sass/script/funcall.rb +3 -16
- data/lib/sass/script/functions.rb +55 -98
- data/lib/sass/script/interpolation.rb +0 -9
- data/lib/sass/script/lexer.rb +4 -2
- data/lib/sass/script/list.rb +0 -8
- data/lib/sass/script/literal.rb +20 -5
- data/lib/sass/script/node.rb +0 -8
- data/lib/sass/script/number.rb +11 -35
- data/lib/sass/script/operation.rb +0 -16
- data/lib/sass/script/parser.rb +5 -12
- data/lib/sass/script/string_interpolation.rb +0 -9
- data/lib/sass/script/unary_operation.rb +0 -7
- data/lib/sass/script/variable.rb +1 -5
- data/lib/sass/scss/parser.rb +54 -191
- data/lib/sass/scss/rx.rb +3 -15
- data/lib/sass/scss/static_parser.rb +3 -3
- data/lib/sass/selector.rb +3 -15
- data/lib/sass/selector/abstract_sequence.rb +2 -11
- data/lib/sass/selector/comma_sequence.rb +3 -8
- data/lib/sass/selector/sequence.rb +11 -74
- data/lib/sass/selector/simple.rb +1 -7
- data/lib/sass/selector/simple_sequence.rb +8 -28
- data/lib/sass/shared.rb +5 -3
- data/lib/sass/tree/comment_node.rb +12 -25
- data/lib/sass/tree/debug_node.rb +1 -1
- data/lib/sass/tree/directive_node.rb +0 -5
- data/lib/sass/tree/each_node.rb +1 -1
- data/lib/sass/tree/extend_node.rb +1 -1
- data/lib/sass/tree/for_node.rb +2 -2
- data/lib/sass/tree/function_node.rb +1 -1
- data/lib/sass/tree/if_node.rb +14 -1
- data/lib/sass/tree/media_node.rb +4 -4
- data/lib/sass/tree/mixin_def_node.rb +1 -1
- data/lib/sass/tree/mixin_node.rb +2 -2
- data/lib/sass/tree/node.rb +26 -10
- data/lib/sass/tree/return_node.rb +1 -1
- data/lib/sass/tree/root_node.rb +1 -1
- data/lib/sass/tree/rule_node.rb +11 -9
- data/lib/sass/tree/variable_node.rb +1 -1
- data/lib/sass/tree/visitors/base.rb +1 -1
- data/lib/sass/tree/visitors/check_nesting.rb +36 -29
- data/lib/sass/tree/visitors/convert.rb +9 -16
- data/lib/sass/tree/visitors/cssize.rb +9 -40
- data/lib/sass/tree/visitors/perform.rb +23 -79
- data/lib/sass/tree/visitors/to_css.rb +21 -23
- data/lib/sass/tree/warn_node.rb +1 -1
- data/lib/sass/tree/while_node.rb +1 -1
- data/lib/sass/util.rb +9 -147
- data/lib/sass/version.rb +0 -14
- data/test/sass/cache_test.rb +0 -15
- data/test/sass/conversion_test.rb +8 -50
- data/test/sass/css2sass_test.rb +0 -33
- data/test/sass/engine_test.rb +32 -283
- data/test/sass/extend_test.rb +0 -315
- data/test/sass/functions_test.rb +23 -60
- data/test/sass/importer_test.rb +0 -110
- data/test/sass/more_results/more_import.css +2 -2
- data/test/sass/plugin_test.rb +13 -40
- data/test/sass/results/import.css +2 -2
- data/test/sass/results/import_charset.css +0 -1
- data/test/sass/results/import_charset_1_8.css +0 -1
- data/test/sass/results/import_charset_ibm866.css +0 -1
- data/test/sass/results/scss_import.css +2 -2
- data/test/sass/results/units.css +1 -1
- data/test/sass/script_conversion_test.rb +0 -2
- data/test/sass/script_test.rb +4 -28
- data/test/sass/scss/css_test.rb +1 -79
- data/test/sass/scss/scss_test.rb +16 -96
- data/test/sass/templates/import_charset.sass +0 -2
- data/test/sass/templates/import_charset_1_8.sass +0 -2
- data/test/sass/templates/import_charset_ibm866.sass +0 -2
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util_test.rb +0 -28
- data/test/test_helper.rb +0 -2
- data/vendor/{listen → fssm}/LICENSE +1 -1
- data/vendor/fssm/README.markdown +55 -0
- data/vendor/fssm/Rakefile +59 -0
- data/vendor/fssm/VERSION.yml +5 -0
- data/vendor/fssm/example.rb +9 -0
- data/vendor/fssm/fssm.gemspec +77 -0
- data/vendor/fssm/lib/fssm.rb +33 -0
- data/vendor/fssm/lib/fssm/backends/fsevents.rb +36 -0
- data/vendor/fssm/lib/fssm/backends/inotify.rb +26 -0
- data/vendor/fssm/lib/fssm/backends/polling.rb +25 -0
- data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +131 -0
- data/vendor/fssm/lib/fssm/monitor.rb +26 -0
- data/vendor/fssm/lib/fssm/path.rb +91 -0
- data/vendor/fssm/lib/fssm/pathname.rb +502 -0
- data/vendor/fssm/lib/fssm/state/directory.rb +57 -0
- data/vendor/fssm/lib/fssm/state/file.rb +24 -0
- data/vendor/fssm/lib/fssm/support.rb +63 -0
- data/vendor/fssm/lib/fssm/tree.rb +176 -0
- data/vendor/fssm/profile/prof-cache.rb +40 -0
- data/vendor/fssm/profile/prof-fssm-pathname.html +1231 -0
- data/vendor/fssm/profile/prof-pathname.rb +68 -0
- data/vendor/fssm/profile/prof-plain-pathname.html +988 -0
- data/vendor/fssm/profile/prof.html +2379 -0
- data/vendor/fssm/spec/path_spec.rb +75 -0
- 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 +14 -0
- metadata +246 -281
- data/VERSION_DATE +0 -1
- data/lib/sass/logger.rb +0 -15
- data/lib/sass/logger/base.rb +0 -32
- data/lib/sass/logger/log_level.rb +0 -49
- data/lib/sass/tree/visitors/deep_copy.rb +0 -87
- data/lib/sass/tree/visitors/extend.rb +0 -42
- data/lib/sass/tree/visitors/set_options.rb +0 -97
- data/lib/sass/util/multibyte_string_scanner.rb +0 -134
- data/test/Gemfile +0 -4
- data/test/Gemfile.lock +0 -19
- data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
- data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
- data/test/sass/logger_test.rb +0 -58
- data/test/sass/templates/_double_import_loop2.sass +0 -1
- data/test/sass/templates/bork5.sass +0 -3
- data/test/sass/templates/double_import_loop1.sass +0 -1
- data/test/sass/templates/nested_bork5.sass +0 -2
- data/test/sass/templates/single_import_loop.sass +0 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +0 -147
- data/vendor/listen/CHANGELOG.md +0 -147
- data/vendor/listen/Gemfile +0 -23
- data/vendor/listen/Guardfile +0 -8
- data/vendor/listen/README.md +0 -312
- data/vendor/listen/Rakefile +0 -47
- data/vendor/listen/Vagrantfile +0 -96
- data/vendor/listen/lib/listen.rb +0 -38
- data/vendor/listen/lib/listen/adapter.rb +0 -167
- data/vendor/listen/lib/listen/adapters/darwin.rb +0 -84
- data/vendor/listen/lib/listen/adapters/linux.rb +0 -110
- data/vendor/listen/lib/listen/adapters/polling.rb +0 -66
- data/vendor/listen/lib/listen/adapters/windows.rb +0 -81
- data/vendor/listen/lib/listen/directory_record.rb +0 -318
- data/vendor/listen/lib/listen/listener.rb +0 -203
- data/vendor/listen/lib/listen/multi_listener.rb +0 -121
- data/vendor/listen/lib/listen/turnstile.rb +0 -28
- data/vendor/listen/lib/listen/version.rb +0 -3
- data/vendor/listen/listen.gemspec +0 -26
- data/vendor/listen/spec/listen/adapter_spec.rb +0 -142
- data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -31
- data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -41
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
- data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -24
- data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1138
- data/vendor/listen/spec/listen/listener_spec.rb +0 -155
- data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -156
- data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
- data/vendor/listen/spec/listen_spec.rb +0 -73
- data/vendor/listen/spec/spec_helper.rb +0 -18
- data/vendor/listen/spec/support/adapter_helper.rb +0 -716
- data/vendor/listen/spec/support/directory_record_helper.rb +0 -55
- data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
- data/vendor/listen/spec/support/listeners_helper.rb +0 -144
- data/vendor/listen/spec/support/platform_helper.rb +0 -11
@@ -12,13 +12,12 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
12
12
|
attr_reader :parent
|
13
13
|
|
14
14
|
def initialize
|
15
|
-
@parent_directives = []
|
16
15
|
@extends = Sass::Util::SubsetMap.new
|
17
16
|
end
|
18
17
|
|
19
18
|
# If an exception is raised, this adds proper metadata to the backtrace.
|
20
19
|
def visit(node)
|
21
|
-
super(node)
|
20
|
+
super(node.dup)
|
22
21
|
rescue Sass::SyntaxError => e
|
23
22
|
e.modify_backtrace(:filename => node.filename, :line => node.line)
|
24
23
|
raise e
|
@@ -39,11 +38,9 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
39
38
|
# @yield A block in which the parent is set to `parent`.
|
40
39
|
# @return [Object] The return value of the block.
|
41
40
|
def with_parent(parent)
|
42
|
-
@parent_directives.push parent if parent.is_a?(Sass::Tree::DirectiveNode)
|
43
41
|
old_parent, @parent = @parent, parent
|
44
42
|
yield
|
45
43
|
ensure
|
46
|
-
@parent_directives.pop if parent.is_a?(Sass::Tree::DirectiveNode)
|
47
44
|
@parent = old_parent
|
48
45
|
end
|
49
46
|
|
@@ -55,26 +52,12 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
55
52
|
def visit_root(node)
|
56
53
|
yield
|
57
54
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
node.children.unshift charset if charset
|
65
|
-
end
|
66
|
-
|
67
|
-
imports = Sass::Util.extract!(node.children) do |c|
|
68
|
-
c.is_a?(Sass::Tree::DirectiveNode) && c.value =~ /^@import /i
|
69
|
-
end
|
70
|
-
charset_and_index = Sass::Util.ruby1_8? &&
|
71
|
-
node.children.each_with_index.find {|c, _| c.is_a?(Sass::Tree::CharsetNode)}
|
72
|
-
if charset_and_index
|
73
|
-
index = charset_and_index.last
|
74
|
-
node.children = node.children[0..index] + imports + node.children[index+1..-1]
|
75
|
-
else
|
76
|
-
node.children = imports + node.children
|
77
|
-
end
|
55
|
+
# In Ruby 1.9 we can make all @charset nodes invisible
|
56
|
+
# and infer the final @charset from the encoding of the final string.
|
57
|
+
if Sass::Util.ruby1_8? && parent.nil?
|
58
|
+
charset = node.children.find {|c| c.is_a?(Sass::Tree::CharsetNode)}
|
59
|
+
node.children.reject! {|c| c.is_a?(Sass::Tree::CharsetNode)}
|
60
|
+
node.children.unshift charset if charset
|
78
61
|
end
|
79
62
|
|
80
63
|
return node, @extends
|
@@ -83,18 +66,6 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
83
66
|
raise e
|
84
67
|
end
|
85
68
|
|
86
|
-
# A simple struct wrapping up information about a single `@extend` instance. A
|
87
|
-
# single [ExtendNode] can have multiple Extends if either the parent node or
|
88
|
-
# the extended selector is a comma sequence.
|
89
|
-
#
|
90
|
-
# @attr extender [Array<Sass::Selector::SimpleSequence, String>]
|
91
|
-
# The selector of the CSS rule containing the `@extend`.
|
92
|
-
# @attr target [Array<Sass::Selector::Simple>] The selector being `@extend`ed.
|
93
|
-
# @attr node [Sass::Tree::ExtendNode] The node that produced this extend.
|
94
|
-
# @attr directives [Array<Sass::Tree::DirectiveNode>]
|
95
|
-
# The directives containing the `@extend`.
|
96
|
-
Extend = Struct.new(:extender, :target, :node, :directives)
|
97
|
-
|
98
69
|
# Registers an extension in the `@extends` subset map.
|
99
70
|
def visit_extend(node)
|
100
71
|
node.resolved_selector.members.each do |seq|
|
@@ -113,7 +84,7 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
113
84
|
raise Sass::SyntaxError.new("#{seq} can't extend: invalid selector")
|
114
85
|
end
|
115
86
|
|
116
|
-
@extends[sel] =
|
87
|
+
@extends[sel] = seq
|
117
88
|
end
|
118
89
|
end
|
119
90
|
|
@@ -146,9 +117,7 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
146
117
|
|
147
118
|
media = node.children.select {|c| c.is_a?(Sass::Tree::MediaNode)}
|
148
119
|
node.children.reject! {|c| c.is_a?(Sass::Tree::MediaNode)}
|
149
|
-
media.each
|
150
|
-
n.query = node.query.map {|pq| n.query.map {|cq| "#{pq} and #{cq}"}}.flatten
|
151
|
-
end
|
120
|
+
media.each {|n| n.query = "#{node.query} and #{n.query}"}
|
152
121
|
(node.children.empty? ? [] : [node]) + media
|
153
122
|
end
|
154
123
|
|
@@ -53,10 +53,12 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
53
53
|
# Removes this node from the tree if it's a silent comment.
|
54
54
|
def visit_comment(node)
|
55
55
|
return [] if node.invisible?
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
if node.evaluated?
|
57
|
+
node.value.gsub!(/(^|[^\\])\#\{([^}]*)\}/) do |md|
|
58
|
+
$1+Sass::Script.parse($2, node.line, 0, node.options).perform(@environment).to_s
|
59
|
+
end
|
60
|
+
node.value = run_interp([Sass::Script::String.new(node.value)])
|
61
|
+
end
|
60
62
|
node
|
61
63
|
end
|
62
64
|
|
@@ -87,8 +89,8 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
87
89
|
# Runs SassScript interpolation in the selector,
|
88
90
|
# and then parses the result into a {Sass::Selector::CommaSequence}.
|
89
91
|
def visit_extend(node)
|
90
|
-
parser = Sass::SCSS::CssParser.new(run_interp(node.selector), node.
|
91
|
-
node.resolved_selector = parser.parse_selector
|
92
|
+
parser = Sass::SCSS::CssParser.new(run_interp(node.selector), node.line)
|
93
|
+
node.resolved_selector = parser.parse_selector(node.filename)
|
92
94
|
node
|
93
95
|
end
|
94
96
|
|
@@ -137,12 +139,9 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
137
139
|
if path = node.css_import?
|
138
140
|
return Sass::Tree::DirectiveNode.new("@import url(#{path})")
|
139
141
|
end
|
140
|
-
file = node.imported_file
|
141
|
-
handle_import_loop!(node) if @environment.files_in_use.include?(file.options[:filename])
|
142
142
|
|
143
143
|
@environment.push_frame(:filename => node.filename, :line => node.line)
|
144
|
-
root =
|
145
|
-
Sass::Tree::Visitors::CheckNesting.visit(root)
|
144
|
+
root = node.imported_file.to_tree
|
146
145
|
node.children = root.children.map {|c| visit(c)}.flatten
|
147
146
|
node
|
148
147
|
rescue Sass::SyntaxError => e
|
@@ -226,15 +225,8 @@ END
|
|
226
225
|
# Runs SassScript interpolation in the selector,
|
227
226
|
# and then parses the result into a {Sass::Selector::CommaSequence}.
|
228
227
|
def visit_rule(node)
|
229
|
-
|
230
|
-
|
231
|
-
parser = Sass::SCSS::StaticParser.new(run_interp(node.rule), node.filename, node.line)
|
232
|
-
node.parsed_rules ||= parser.parse_selector
|
233
|
-
if node.options[:trace_selectors]
|
234
|
-
@environment.push_frame(:filename => node.filename, :line => node.line)
|
235
|
-
node.stack_trace = @environment.stack_trace
|
236
|
-
@environment.pop_frame
|
237
|
-
end
|
228
|
+
parser = Sass::SCSS::StaticParser.new(run_interp(node.rule), node.line)
|
229
|
+
node.parsed_rules ||= parser.parse_selector(node.filename)
|
238
230
|
yield
|
239
231
|
end
|
240
232
|
|
@@ -251,10 +243,13 @@ END
|
|
251
243
|
@environment.push_frame(:filename => node.filename, :line => node.line)
|
252
244
|
res = node.expr.perform(@environment)
|
253
245
|
res = res.value if res.is_a?(Sass::Script::String)
|
254
|
-
msg = "WARNING: #{res}\n
|
255
|
-
|
256
|
-
|
257
|
-
|
246
|
+
msg = "WARNING: #{res}\n"
|
247
|
+
@environment.stack.reverse.each_with_index do |entry, i|
|
248
|
+
msg << " #{i == 0 ? "on" : "from"} line #{entry[:line]}" <<
|
249
|
+
" of #{entry[:filename] || "an unknown file"}"
|
250
|
+
msg << ", in `#{entry[:mixin]}'" if entry[:mixin]
|
251
|
+
msg << "\n"
|
252
|
+
end
|
258
253
|
Sass::Util.sass_warn msg
|
259
254
|
[]
|
260
255
|
ensure
|
@@ -272,15 +267,6 @@ END
|
|
272
267
|
|
273
268
|
def visit_directive(node)
|
274
269
|
if node.value['#{']
|
275
|
-
if node.value =~ /^@import (?!url\()/
|
276
|
-
Sass::Util.sass_warn <<WARNING
|
277
|
-
DEPRECATION WARNING on line #{node.line}#{" of #{node.filename}" if node.filename}:
|
278
|
-
@import directives using \#{} interpolation will need to use url() in Sass 3.2.
|
279
|
-
For example:
|
280
|
-
|
281
|
-
@import url("http://\#{$url}/style.css");
|
282
|
-
WARNING
|
283
|
-
end
|
284
270
|
node.value = run_interp(Sass::Engine.parse_interp(node.value, node.line, 0, node.options))
|
285
271
|
end
|
286
272
|
yield
|
@@ -289,24 +275,22 @@ WARNING
|
|
289
275
|
|
290
276
|
private
|
291
277
|
|
292
|
-
def
|
278
|
+
def run_interp(text)
|
293
279
|
text.map do |r|
|
294
280
|
next r if r.is_a?(String)
|
295
281
|
val = r.perform(@environment)
|
296
282
|
# Interpolated strings should never render with quotes
|
297
283
|
next val.value if val.is_a?(Sass::Script::String)
|
298
284
|
val.to_s
|
299
|
-
end.join
|
300
|
-
end
|
301
|
-
|
302
|
-
def run_interp(text)
|
303
|
-
run_interp_no_strip(text).strip
|
285
|
+
end.join.strip
|
304
286
|
end
|
305
287
|
|
306
288
|
def handle_include_loop!(node)
|
307
289
|
msg = "An @include loop has been found:"
|
308
290
|
mixins = @environment.stack.map {|s| s[:mixin]}.compact
|
309
|
-
|
291
|
+
if mixins.size == 2 && mixins[0] == mixins[1]
|
292
|
+
raise Sass::SyntaxError.new("#{msg} #{node.name} includes itself")
|
293
|
+
end
|
310
294
|
|
311
295
|
mixins << node.name
|
312
296
|
msg << "\n" << Sass::Util.enum_cons(mixins, 2).map do |m1, m2|
|
@@ -314,44 +298,4 @@ WARNING
|
|
314
298
|
end.join("\n")
|
315
299
|
raise Sass::SyntaxError.new(msg)
|
316
300
|
end
|
317
|
-
|
318
|
-
def handle_import_loop!(node)
|
319
|
-
msg = "An @import loop has been found:"
|
320
|
-
files = @environment.stack.map {|s| s[:filename]}.compact
|
321
|
-
if node.filename == node.imported_file.options[:filename]
|
322
|
-
raise Sass::SyntaxError.new("#{msg} #{node.filename} imports itself")
|
323
|
-
end
|
324
|
-
|
325
|
-
files << node.filename << node.imported_file.options[:filename]
|
326
|
-
msg << "\n" << Sass::Util.enum_cons(files, 2).map do |m1, m2|
|
327
|
-
" #{m1} imports #{m2}"
|
328
|
-
end.join("\n")
|
329
|
-
raise Sass::SyntaxError.new(msg)
|
330
|
-
end
|
331
|
-
|
332
|
-
def check_for_loud_silent_comment(node)
|
333
|
-
return unless node.loud && node.silent
|
334
|
-
Sass::Util.sass_warn <<MESSAGE
|
335
|
-
WARNING:
|
336
|
-
On line #{node.line}#{" of '#{node.filename}'" if node.filename}
|
337
|
-
`//` comments will no longer be allowed to use the `!` flag in Sass 3.2.
|
338
|
-
Please change to `/*` comments.
|
339
|
-
MESSAGE
|
340
|
-
end
|
341
|
-
|
342
|
-
def check_for_comment_interp(node)
|
343
|
-
return if node.loud
|
344
|
-
node.value.each do |e|
|
345
|
-
next unless e.is_a?(String)
|
346
|
-
e.scan(/(\\*)#\{/) do |esc|
|
347
|
-
Sass::Util.sass_warn <<MESSAGE if esc.first.size.even?
|
348
|
-
WARNING:
|
349
|
-
On line #{node.line}#{" of '#{node.filename}'" if node.filename}
|
350
|
-
Comments will evaluate the contents of interpolations (\#{ ... }) in Sass 3.2.
|
351
|
-
Please escape the interpolation by adding a backslash before the `#`.
|
352
|
-
MESSAGE
|
353
|
-
return
|
354
|
-
end
|
355
|
-
end
|
356
|
-
end
|
357
301
|
end
|
@@ -57,24 +57,32 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
57
57
|
|
58
58
|
def visit_comment(node)
|
59
59
|
return if node.invisible?
|
60
|
-
spaces = (' ' * [@tabs - node.
|
60
|
+
spaces = (' ' * [@tabs - node.value[/^ */].size, 0].max)
|
61
61
|
|
62
|
-
content = node.
|
63
|
-
|
62
|
+
content = node.value.gsub(/^/, spaces).gsub(%r{^(\s*)//(.*)$}) do |md|
|
63
|
+
"#{$1}/*#{$2} */"
|
64
|
+
end
|
65
|
+
if content =~ /[^\\]\#\{.*\}/
|
66
|
+
Sass::Util.sass_warn <<MESSAGE
|
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')
|
74
|
+
end
|
64
75
|
content.gsub!(/\n +(\* *(?!\/))?/, ' ') if (node.style == :compact || node.style == :compressed) && !node.loud
|
65
76
|
content
|
66
77
|
end
|
67
78
|
|
68
79
|
def visit_directive(node)
|
69
|
-
|
70
|
-
|
71
|
-
return tab_str + node.value + ";" unless node.has_children
|
72
|
-
return tab_str + node.value + " {}" if node.children.empty?
|
73
|
-
@in_directive = @in_directive || !node.is_a?(Sass::Tree::MediaNode)
|
80
|
+
return node.value + ";" unless node.has_children
|
81
|
+
return node.value + " {}" if node.children.empty?
|
74
82
|
result = if node.style == :compressed
|
75
83
|
"#{node.value}{"
|
76
84
|
else
|
77
|
-
"#{
|
85
|
+
"#{' ' * @tabs}#{node.value} {" + (node.style == :compact ? ' ' : "\n")
|
78
86
|
end
|
79
87
|
was_prop = false
|
80
88
|
first = true
|
@@ -103,8 +111,6 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
103
111
|
else
|
104
112
|
(node.style == :expanded ? "\n" : " ") + "}\n"
|
105
113
|
end
|
106
|
-
ensure
|
107
|
-
@in_directive = was_in_directive
|
108
114
|
end
|
109
115
|
|
110
116
|
def visit_media(node)
|
@@ -136,11 +142,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
136
142
|
|
137
143
|
joined_rules = node.resolved_rules.members.map do |seq|
|
138
144
|
rule_part = seq.to_a.join
|
139
|
-
if node.style == :compressed
|
140
|
-
rule_part.gsub!(/([^,])\s*\n\s*/m, '\1 ')
|
141
|
-
rule_part.gsub!(/\s*([,+>])\s*/m, '\1')
|
142
|
-
rule_part.strip!
|
143
|
-
end
|
145
|
+
rule_part.gsub!(/\s*([^,])\s*\n\s*/m, '\1 ') if node.style == :compressed
|
144
146
|
rule_part
|
145
147
|
end.join(rule_separator)
|
146
148
|
|
@@ -152,12 +154,8 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
152
154
|
old_spaces = ' ' * @tabs
|
153
155
|
spaces = ' ' * (@tabs + 1)
|
154
156
|
if node.style != :compressed
|
155
|
-
if node.options[:debug_info]
|
157
|
+
if node.options[:debug_info]
|
156
158
|
to_return << visit(debug_info_rule(node.debug_info, node.options)) << "\n"
|
157
|
-
elsif node.options[:trace_selectors]
|
158
|
-
to_return << "#{old_spaces}/* "
|
159
|
-
to_return << node.stack_trace.join("\n #{old_spaces}")
|
160
|
-
to_return << " */\n"
|
161
159
|
elsif node.options[:line_comments]
|
162
160
|
to_return << "#{old_spaces}/* line #{node.line}"
|
163
161
|
|
@@ -198,7 +196,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
198
196
|
|
199
197
|
def debug_info_rule(debug_info, options)
|
200
198
|
node = Sass::Tree::DirectiveNode.new("@media -sass-debug-info")
|
201
|
-
|
199
|
+
debug_info.map {|k, v| [k.to_s, v.to_s]}.sort.each do |k, v|
|
202
200
|
rule = Sass::Tree::RuleNode.new([""])
|
203
201
|
rule.resolved_rules = Sass::Selector::CommaSequence.new(
|
204
202
|
[Sass::Selector::Sequence.new(
|
@@ -206,7 +204,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
|
|
206
204
|
[Sass::Selector::Element.new(k.to_s.gsub(/[^\w-]/, "\\\\\\0"), nil)])
|
207
205
|
])
|
208
206
|
])
|
209
|
-
prop = Sass::Tree::PropNode.new([""],
|
207
|
+
prop = Sass::Tree::PropNode.new([""], "", :new)
|
210
208
|
prop.resolved_name = "font-family"
|
211
209
|
prop.resolved_value = Sass::SCSS::RX.escape_ident(v.to_s)
|
212
210
|
rule << prop
|
data/lib/sass/tree/warn_node.rb
CHANGED
data/lib/sass/tree/while_node.rb
CHANGED
data/lib/sass/util.rb
CHANGED
@@ -2,6 +2,7 @@ require 'erb'
|
|
2
2
|
require 'set'
|
3
3
|
require 'enumerator'
|
4
4
|
require 'stringio'
|
5
|
+
require 'strscan'
|
5
6
|
require 'rbconfig'
|
6
7
|
|
7
8
|
require 'sass/root'
|
@@ -85,9 +86,8 @@ module Sass
|
|
85
86
|
# @return [Hash] The mapped hash
|
86
87
|
# @see #map_keys
|
87
88
|
# @see #map_vals
|
88
|
-
def map_hash(hash)
|
89
|
-
|
90
|
-
to_hash(hash.map {|k, v| yield k, v})
|
89
|
+
def map_hash(hash, &block)
|
90
|
+
to_hash(hash.map(&block))
|
91
91
|
end
|
92
92
|
|
93
93
|
# Computes the powerset of the given array.
|
@@ -219,57 +219,6 @@ module Sass
|
|
219
219
|
lcs_backtrace(lcs_table(x, y, &block), x, y, x.size-1, y.size-1, &block)
|
220
220
|
end
|
221
221
|
|
222
|
-
# Converts a Hash to an Array. This is usually identical to `Hash#to_a`,
|
223
|
-
# with the following exceptions:
|
224
|
-
#
|
225
|
-
# * In Ruby 1.8, `Hash#to_a` is not deterministically ordered, but this is.
|
226
|
-
# * In Ruby 1.9 when running tests, this is ordered in the same way it would
|
227
|
-
# be under Ruby 1.8 (sorted key order rather than insertion order).
|
228
|
-
#
|
229
|
-
# @param hash [Hash]
|
230
|
-
# @return [Array]
|
231
|
-
def hash_to_a(hash)
|
232
|
-
return hash.to_a unless ruby1_8? || defined?(Test::Unit)
|
233
|
-
return hash.sort_by {|k, v| k}
|
234
|
-
end
|
235
|
-
|
236
|
-
# Asserts that `value` falls within `range` (inclusive), leaving
|
237
|
-
# room for slight floating-point errors.
|
238
|
-
#
|
239
|
-
# @param name [String] The name of the value. Used in the error message.
|
240
|
-
# @param range [Range] The allowed range of values.
|
241
|
-
# @param value [Numeric, Sass::Script::Number] The value to check.
|
242
|
-
# @param unit [String] The unit of the value. Used in error reporting.
|
243
|
-
# @return [Numeric] `value` adjusted to fall within range, if it
|
244
|
-
# was outside by a floating-point margin.
|
245
|
-
def check_range(name, range, value, unit='')
|
246
|
-
grace = (-0.00001..0.00001)
|
247
|
-
str = value.to_s
|
248
|
-
value = value.value if value.is_a?(Sass::Script::Number)
|
249
|
-
return value if range.include?(value)
|
250
|
-
return range.first if grace.include?(value - range.first)
|
251
|
-
return range.last if grace.include?(value - range.last)
|
252
|
-
raise ArgumentError.new(
|
253
|
-
"#{name} #{str} must be between #{range.first}#{unit} and #{range.last}#{unit}")
|
254
|
-
end
|
255
|
-
|
256
|
-
# Returns whether or not `seq1` is a subsequence of `seq2`. That is, whether
|
257
|
-
# or not `seq2` contains every element in `seq1` in the same order (and
|
258
|
-
# possibly more elements besides).
|
259
|
-
#
|
260
|
-
# @param seq1 [Array]
|
261
|
-
# @param seq2 [Array]
|
262
|
-
# @return [Boolean]
|
263
|
-
def subsequence?(seq1, seq2)
|
264
|
-
i = j = 0
|
265
|
-
loop do
|
266
|
-
return true if i == seq1.size
|
267
|
-
return false if j == seq2.size
|
268
|
-
i += 1 if seq1[i] == seq2[j]
|
269
|
-
j += 1
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
222
|
# Returns information about the caller of the previous method.
|
274
223
|
#
|
275
224
|
# @param entry [String] An entry in the `#caller` list, or a similarly formatted string
|
@@ -344,17 +293,19 @@ module Sass
|
|
344
293
|
#
|
345
294
|
# @yield A block in which no Sass warnings will be printed
|
346
295
|
def silence_sass_warnings
|
347
|
-
|
296
|
+
old_silence_warnings = @@silence_warnings
|
297
|
+
@@silence_warnings = true
|
348
298
|
yield
|
349
299
|
ensure
|
350
|
-
|
300
|
+
@@silence_warnings = old_silence_warnings
|
351
301
|
end
|
352
302
|
|
353
303
|
# The same as `Kernel#warn`, but is silenced by \{#silence\_sass\_warnings}.
|
354
304
|
#
|
355
305
|
# @param msg [String]
|
356
306
|
def sass_warn(msg)
|
357
|
-
|
307
|
+
return if @@silence_warnings
|
308
|
+
warn(msg)
|
358
309
|
end
|
359
310
|
|
360
311
|
## Cross Rails Version Compatibility
|
@@ -436,14 +387,6 @@ module Sass
|
|
436
387
|
RUBY_ENGINE == "ironruby"
|
437
388
|
end
|
438
389
|
|
439
|
-
# Like `Dir.glob`, but works with backslash-separated paths on Windows.
|
440
|
-
#
|
441
|
-
# @param path [String]
|
442
|
-
def glob(path, &block)
|
443
|
-
path = path.gsub('\\', '/') if windows?
|
444
|
-
Dir.glob(path, &block)
|
445
|
-
end
|
446
|
-
|
447
390
|
## Cross-Ruby-Version Compatibility
|
448
391
|
|
449
392
|
# Whether or not this is running under Ruby 1.8 or lower.
|
@@ -466,13 +409,6 @@ module Sass
|
|
466
409
|
ruby1_8? && Sass::Util::RUBY_VERSION[2] < 7
|
467
410
|
end
|
468
411
|
|
469
|
-
# Whether or not this is running under MacRuby.
|
470
|
-
#
|
471
|
-
# @return [Boolean]
|
472
|
-
def macruby?
|
473
|
-
RUBY_ENGINE == 'macruby'
|
474
|
-
end
|
475
|
-
|
476
412
|
# Checks that the encoding of a string is valid in Ruby 1.9
|
477
413
|
# and cleans up potential encoding gotchas like the UTF-8 BOM.
|
478
414
|
# If it's not, yields an error string describing the invalid character
|
@@ -533,8 +469,7 @@ MSG
|
|
533
469
|
# We allow any printable ASCII characters but double quotes in the charset decl
|
534
470
|
bin = str.dup.force_encoding("BINARY")
|
535
471
|
encoding = Sass::Util::ENCODINGS_TO_CHECK.find do |enc|
|
536
|
-
|
537
|
-
re && bin =~ re
|
472
|
+
bin =~ Sass::Util::CHARSET_REGEXPS[enc]
|
538
473
|
end
|
539
474
|
charset, bom = $1, $2
|
540
475
|
if charset
|
@@ -575,8 +510,6 @@ MSG
|
|
575
510
|
Regexp.new(/\A(?:#{_enc("\uFEFF", e)})?#{
|
576
511
|
_enc('@charset "', e)}(.*?)#{_enc('"', e)}|\A(#{
|
577
512
|
_enc("\uFEFF", e)})/)
|
578
|
-
rescue Encoding::ConverterNotFoundError => _
|
579
|
-
nil # JRuby on Java 5 doesn't support UTF-32
|
580
513
|
rescue
|
581
514
|
# /\A@charset "(.*?)"/
|
582
515
|
Regexp.new(/\A#{_enc('@charset "', e)}(.*?)#{_enc('"', e)}/)
|
@@ -628,24 +561,6 @@ MSG
|
|
628
561
|
ruby1_8? ? enum.enum_slice(n) : enum.each_slice(n)
|
629
562
|
end
|
630
563
|
|
631
|
-
# Destructively removes all elements from an array that match a block, and
|
632
|
-
# returns the removed elements.
|
633
|
-
#
|
634
|
-
# @param array [Array] The array from which to remove elements.
|
635
|
-
# @yield [el] Called for each element.
|
636
|
-
# @yieldparam el [*] The element to test.
|
637
|
-
# @yieldreturn [Boolean] Whether or not to extract the element.
|
638
|
-
# @return [Array] The extracted elements.
|
639
|
-
def extract!(array)
|
640
|
-
out = []
|
641
|
-
array.reject! do |e|
|
642
|
-
next false unless yield e
|
643
|
-
out << e
|
644
|
-
true
|
645
|
-
end
|
646
|
-
out
|
647
|
-
end
|
648
|
-
|
649
564
|
# Returns the ASCII code of the given character.
|
650
565
|
#
|
651
566
|
# @param c [String] All characters but the first are ignored.
|
@@ -699,57 +614,6 @@ MSG
|
|
699
614
|
'"' + obj.gsub(/[\x00-\x7F]+/) {|s| s.inspect[1...-1]} + '"'
|
700
615
|
end
|
701
616
|
|
702
|
-
# Extracts the non-string vlaues from an array containing both strings and non-strings.
|
703
|
-
# These values are replaced with escape sequences.
|
704
|
-
# This can be undone using \{#inject\_values}.
|
705
|
-
#
|
706
|
-
# This is useful e.g. when we want to do string manipulation
|
707
|
-
# on an interpolated string.
|
708
|
-
#
|
709
|
-
# The precise format of the resulting string is not guaranteed.
|
710
|
-
# However, it is guaranteed that newlines and whitespace won't be affected.
|
711
|
-
#
|
712
|
-
# @param arr [Array] The array from which values are extracted.
|
713
|
-
# @return [(String, Array)] The resulting string, and an array of extracted values.
|
714
|
-
def extract_values(arr)
|
715
|
-
values = []
|
716
|
-
return arr.map do |e|
|
717
|
-
next e.gsub('{', '{{') if e.is_a?(String)
|
718
|
-
values << e
|
719
|
-
next "{#{values.count - 1}}"
|
720
|
-
end.join, values
|
721
|
-
end
|
722
|
-
|
723
|
-
# Undoes \{#extract\_values} by transforming a string with escape sequences
|
724
|
-
# into an array of strings and non-string values.
|
725
|
-
#
|
726
|
-
# @param str [String] The string with escape sequences.
|
727
|
-
# @param values [Array] The array of values to inject.
|
728
|
-
# @return [Array] The array of strings and values.
|
729
|
-
def inject_values(str, values)
|
730
|
-
return [str.gsub('{{', '{')] if values.empty?
|
731
|
-
# Add an extra { so that we process the tail end of the string
|
732
|
-
result = (str + '{{').scan(/(.*?)(?:(\{\{)|\{(\d+)\})/m).map do |(pre, esc, n)|
|
733
|
-
[pre, esc ? '{' : '', n ? values[n.to_i] : '']
|
734
|
-
end.flatten(1)
|
735
|
-
result[-2] = '' # Get rid of the extra {
|
736
|
-
merge_adjacent_strings(result).reject {|s| s == ''}
|
737
|
-
end
|
738
|
-
|
739
|
-
# Allows modifications to be performed on the string form
|
740
|
-
# of an array containing both strings and non-strings.
|
741
|
-
#
|
742
|
-
# @param arr [Array] The array from which values are extracted.
|
743
|
-
# @yield [str] A block in which string manipulation can be done to the array.
|
744
|
-
# @yieldparam str [String] The string form of `arr`.
|
745
|
-
# @yieldreturn [String] The modified string.
|
746
|
-
# @return [Array] The modified, interpolated array.
|
747
|
-
def with_extracted_values(arr)
|
748
|
-
str, vals = extract_values(arr)
|
749
|
-
str = yield str
|
750
|
-
inject_values(str, vals)
|
751
|
-
end
|
752
|
-
|
753
617
|
## Static Method Stuff
|
754
618
|
|
755
619
|
# The context in which the ERB for \{#def\_static\_method} will be run.
|
@@ -803,5 +667,3 @@ MSG
|
|
803
667
|
end
|
804
668
|
end
|
805
669
|
end
|
806
|
-
|
807
|
-
require 'sass/util/multibyte_string_scanner'
|