sass 3.4.25 → 3.5.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 +4 -4
- data/README.md +1 -1
- data/Rakefile +2 -117
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/lib/sass/cache_stores/filesystem.rb +1 -1
- data/lib/sass/css.rb +1 -2
- data/lib/sass/engine.rb +38 -20
- data/lib/sass/environment.rb +26 -5
- data/lib/sass/error.rb +2 -2
- data/lib/sass/exec/base.rb +2 -11
- data/lib/sass/features.rb +1 -0
- data/lib/sass/importers/filesystem.rb +2 -2
- data/lib/sass/plugin/compiler.rb +20 -50
- data/lib/sass/plugin/configuration.rb +2 -2
- data/lib/sass/railtie.rb +1 -1
- data/lib/sass/script/functions.rb +235 -43
- data/lib/sass/script/lexer.rb +13 -2
- data/lib/sass/script/parser.rb +69 -67
- data/lib/sass/script/tree/funcall.rb +35 -30
- data/lib/sass/script/tree/list_literal.rb +23 -8
- data/lib/sass/script/tree/map_literal.rb +2 -2
- data/lib/sass/script/tree/node.rb +0 -8
- data/lib/sass/script/tree/operation.rb +0 -7
- data/lib/sass/script/value/arg_list.rb +1 -1
- data/lib/sass/script/value/base.rb +17 -0
- data/lib/sass/script/value/callable.rb +25 -0
- data/lib/sass/script/value/color.rb +5 -0
- data/lib/sass/script/value/function.rb +19 -0
- data/lib/sass/script/value/helpers.rb +29 -9
- data/lib/sass/script/value/list.rb +35 -14
- data/lib/sass/script/value/map.rb +2 -2
- data/lib/sass/script/value/number.rb +1 -1
- data/lib/sass/script/value.rb +2 -0
- data/lib/sass/scss/parser.rb +99 -40
- data/lib/sass/scss/rx.rb +4 -10
- data/lib/sass/scss/static_parser.rb +5 -24
- data/lib/sass/selector/abstract_sequence.rb +7 -6
- data/lib/sass/selector/comma_sequence.rb +7 -4
- data/lib/sass/selector/pseudo.rb +19 -2
- data/lib/sass/selector/sequence.rb +35 -6
- data/lib/sass/selector/simple.rb +9 -2
- data/lib/sass/selector/simple_sequence.rb +8 -4
- data/lib/sass/selector.rb +4 -0
- data/lib/sass/source/map.rb +2 -2
- data/lib/sass/stack.rb +21 -1
- data/lib/sass/tree/charset_node.rb +1 -1
- data/lib/sass/tree/prop_node.rb +45 -53
- data/lib/sass/tree/rule_node.rb +3 -2
- data/lib/sass/tree/visitors/check_nesting.rb +1 -1
- data/lib/sass/tree/visitors/convert.rb +2 -3
- data/lib/sass/tree/visitors/cssize.rb +4 -15
- data/lib/sass/tree/visitors/deep_copy.rb +1 -1
- data/lib/sass/tree/visitors/extend.rb +2 -8
- data/lib/sass/tree/visitors/perform.rb +21 -9
- data/lib/sass/tree/visitors/set_options.rb +1 -1
- data/lib/sass/tree/visitors/to_css.rb +47 -13
- data/lib/sass/util/multibyte_string_scanner.rb +127 -131
- data/lib/sass/util/normalized_map.rb +1 -8
- data/lib/sass/util.rb +12 -290
- data/lib/sass/version.rb +0 -2
- data/lib/sass.rb +0 -7
- data/test/sass/cache_test.rb +0 -1
- data/test/sass/callbacks_test.rb +0 -1
- data/test/sass/compiler_test.rb +4 -15
- data/test/sass/conversion_test.rb +113 -163
- data/test/sass/css2sass_test.rb +16 -19
- data/test/sass/css_variable_test.rb +176 -71
- data/test/sass/encoding_test.rb +2 -33
- data/test/sass/engine_test.rb +71 -19
- data/test/sass/exec_test.rb +0 -1
- data/test/sass/extend_test.rb +37 -92
- data/test/sass/functions_test.rb +58 -14
- data/test/sass/importer_test.rb +2 -3
- data/test/sass/logger_test.rb +0 -1
- data/test/sass/plugin_test.rb +6 -10
- data/test/sass/results/script.css +1 -1
- data/test/sass/results/units.css +2 -2
- data/test/sass/script_conversion_test.rb +10 -2
- data/test/sass/script_test.rb +22 -24
- data/test/sass/scss/css_test.rb +3 -18
- data/test/sass/scss/rx_test.rb +0 -1
- data/test/sass/scss/scss_test.rb +49 -16
- data/test/sass/source_map_test.rb +13 -16
- data/test/sass/superselector_test.rb +0 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +121 -124
- data/test/sass/util/normalized_map_test.rb +0 -1
- data/test/sass/util/subset_map_test.rb +0 -1
- data/test/sass/util_test.rb +4 -39
- data/test/sass/value_helpers_test.rb +0 -1
- data/test/sass-spec.yml +1 -1
- data/test/test_helper.rb +39 -0
- metadata +19 -44
- data/lib/sass/script/css_variable_warning.rb +0 -52
- data/lib/sass/util/cross_platform_random.rb +0 -19
- data/lib/sass/util/ordered_hash.rb +0 -192
- data/test/sass/results/import_charset_1_8.css +0 -5
- data/test/sass/templates/import_charset_1_8.sass +0 -6
- data/vendor/listen/CHANGELOG.md +0 -1
- data/vendor/listen/CONTRIBUTING.md +0 -38
- data/vendor/listen/Gemfile +0 -20
- data/vendor/listen/Guardfile +0 -8
- data/vendor/listen/LICENSE +0 -20
- data/vendor/listen/README.md +0 -349
- data/vendor/listen/Rakefile +0 -5
- data/vendor/listen/Vagrantfile +0 -96
- data/vendor/listen/lib/listen/adapter.rb +0 -327
- data/vendor/listen/lib/listen/adapters/bsd.rb +0 -75
- data/vendor/listen/lib/listen/adapters/darwin.rb +0 -48
- data/vendor/listen/lib/listen/adapters/linux.rb +0 -81
- data/vendor/listen/lib/listen/adapters/polling.rb +0 -58
- data/vendor/listen/lib/listen/adapters/windows.rb +0 -91
- data/vendor/listen/lib/listen/directory_record.rb +0 -406
- data/vendor/listen/lib/listen/listener.rb +0 -323
- data/vendor/listen/lib/listen/turnstile.rb +0 -32
- data/vendor/listen/lib/listen/version.rb +0 -3
- data/vendor/listen/lib/listen.rb +0 -54
- data/vendor/listen/listen.gemspec +0 -28
- data/vendor/listen/spec/listen/adapter_spec.rb +0 -149
- data/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
- data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -37
- data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -47
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
- data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -30
- data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1250
- data/vendor/listen/spec/listen/listener_spec.rb +0 -258
- data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
- data/vendor/listen/spec/listen_spec.rb +0 -67
- data/vendor/listen/spec/spec_helper.rb +0 -25
- data/vendor/listen/spec/support/adapter_helper.rb +0 -666
- data/vendor/listen/spec/support/directory_record_helper.rb +0 -57
- data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
- data/vendor/listen/spec/support/listeners_helper.rb +0 -179
- data/vendor/listen/spec/support/platform_helper.rb +0 -15
data/lib/sass/script/parser.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require 'sass/script/lexer'
|
|
2
|
-
require 'sass/script/css_variable_warning'
|
|
3
2
|
|
|
4
3
|
module Sass
|
|
5
4
|
module Script
|
|
@@ -35,7 +34,6 @@ module Sass
|
|
|
35
34
|
@allow_extra_text = options.delete(:allow_extra_text)
|
|
36
35
|
@lexer = lexer_class.new(str, line, offset, options)
|
|
37
36
|
@stop_at = nil
|
|
38
|
-
@css_variable_warning = nil
|
|
39
37
|
end
|
|
40
38
|
|
|
41
39
|
# Parses a SassScript expression within an interpolated segment (`#{}`).
|
|
@@ -64,23 +62,13 @@ module Sass
|
|
|
64
62
|
|
|
65
63
|
# Parses a SassScript expression.
|
|
66
64
|
#
|
|
67
|
-
# @param css_variable [Boolean] Whether this is the value of a CSS variable.
|
|
68
65
|
# @return [Script::Tree::Node] The root node of the parse tree
|
|
69
66
|
# @raise [Sass::SyntaxError] if the expression isn't valid SassScript
|
|
70
|
-
def parse
|
|
71
|
-
if css_variable
|
|
72
|
-
@css_variable_warning = CssVariableWarning.new
|
|
73
|
-
end
|
|
74
|
-
|
|
67
|
+
def parse
|
|
75
68
|
expr = assert_expr :expr
|
|
76
69
|
assert_done
|
|
77
70
|
expr.options = @options
|
|
78
71
|
check_for_interpolation expr
|
|
79
|
-
|
|
80
|
-
if css_variable
|
|
81
|
-
@css_variable_warning.value = expr
|
|
82
|
-
end
|
|
83
|
-
|
|
84
72
|
expr
|
|
85
73
|
rescue Sass::SyntaxError => e
|
|
86
74
|
e.modify_backtrace :line => @lexer.line, :filename => @options[:filename]
|
|
@@ -127,7 +115,7 @@ module Sass
|
|
|
127
115
|
a.options = @options
|
|
128
116
|
end
|
|
129
117
|
|
|
130
|
-
keywords.each do |
|
|
118
|
+
keywords.each do |_, v|
|
|
131
119
|
check_for_interpolation v
|
|
132
120
|
v.options = @options
|
|
133
121
|
end
|
|
@@ -232,12 +220,12 @@ module Sass
|
|
|
232
220
|
|
|
233
221
|
# Parses a SassScript expression.
|
|
234
222
|
#
|
|
223
|
+
# @overload parse(str, line, offset, filename = nil)
|
|
235
224
|
# @return [Script::Tree::Node] The root node of the parse tree
|
|
236
225
|
# @see Parser#initialize
|
|
237
226
|
# @see Parser#parse
|
|
238
|
-
def self.parse(
|
|
239
|
-
|
|
240
|
-
new(value, line, offset, options).parse(css_variable)
|
|
227
|
+
def self.parse(*args)
|
|
228
|
+
new(*args).parse
|
|
241
229
|
end
|
|
242
230
|
|
|
243
231
|
PRECEDENCE = [
|
|
@@ -250,8 +238,6 @@ module Sass
|
|
|
250
238
|
|
|
251
239
|
ASSOCIATIVE = [:plus, :times]
|
|
252
240
|
|
|
253
|
-
VALID_CSS_OPS = [:comma, :single_eq, :space, :div]
|
|
254
|
-
|
|
255
241
|
class << self
|
|
256
242
|
# Returns an integer representing the precedence
|
|
257
243
|
# of the given operator.
|
|
@@ -291,10 +277,6 @@ module Sass
|
|
|
291
277
|
return other_interp
|
|
292
278
|
end
|
|
293
279
|
|
|
294
|
-
if @css_variable_warning && !VALID_CSS_OPS.include?(tok.type)
|
|
295
|
-
@css_variable_warning.warn!
|
|
296
|
-
end
|
|
297
|
-
|
|
298
280
|
e = node(Tree::Operation.new(e, assert_expr(#{sub.inspect}), tok.type),
|
|
299
281
|
e.source_range.start_pos)
|
|
300
282
|
end
|
|
@@ -310,8 +292,6 @@ RUBY
|
|
|
310
292
|
interp = try_op_before_interp(tok)
|
|
311
293
|
return interp if interp
|
|
312
294
|
start_pos = source_position
|
|
313
|
-
|
|
314
|
-
@css_variable_warning.warn! if @css_variable_warning
|
|
315
295
|
node(Tree::UnaryOperation.new(assert_expr(:unary_#{op}), :#{op}), start_pos)
|
|
316
296
|
end
|
|
317
297
|
RUBY
|
|
@@ -338,7 +318,6 @@ RUBY
|
|
|
338
318
|
return list e, start_pos unless @lexer.peek && @lexer.peek.type == :colon
|
|
339
319
|
|
|
340
320
|
pair = map_pair(e)
|
|
341
|
-
@css_variable_warning.warn! if @css_variable_warning
|
|
342
321
|
map = node(Sass::Script::Tree::MapLiteral.new([pair]), start_pos)
|
|
343
322
|
while try_tok(:comma)
|
|
344
323
|
pair = map_pair
|
|
@@ -364,7 +343,7 @@ RUBY
|
|
|
364
343
|
def list(first, start_pos)
|
|
365
344
|
return first unless @lexer.peek && @lexer.peek.type == :comma
|
|
366
345
|
|
|
367
|
-
list = node(Sass::Script::Tree::ListLiteral.new([first], :comma), start_pos)
|
|
346
|
+
list = node(Sass::Script::Tree::ListLiteral.new([first], separator: :comma), start_pos)
|
|
368
347
|
while (tok = try_tok(:comma))
|
|
369
348
|
element_before_interp = list.elements.length == 1 ? list.elements.first : list
|
|
370
349
|
if (interp = try_op_before_interp(tok, element_before_interp))
|
|
@@ -401,7 +380,7 @@ RUBY
|
|
|
401
380
|
Script::Tree::Interpolation.new(
|
|
402
381
|
prev, str, nil, wb, false, :originally_text => true, :deprecation => deprecation),
|
|
403
382
|
(prev || str).source_range.start_pos)
|
|
404
|
-
interpolation(interp)
|
|
383
|
+
interpolation(first: interp)
|
|
405
384
|
end
|
|
406
385
|
|
|
407
386
|
def try_ops_after_interp(ops, name, prev = nil)
|
|
@@ -431,17 +410,17 @@ RUBY
|
|
|
431
410
|
interp
|
|
432
411
|
end
|
|
433
412
|
|
|
434
|
-
def interpolation(first
|
|
435
|
-
e = first
|
|
413
|
+
def interpolation(first: nil, inner: :space)
|
|
414
|
+
e = first || send(inner)
|
|
436
415
|
while (interp = try_tok(:begin_interpolation))
|
|
437
416
|
wb = @lexer.whitespace?(interp)
|
|
438
417
|
char_before = @lexer.char(interp.pos - 1)
|
|
439
|
-
mid =
|
|
418
|
+
mid = assert_expr :expr
|
|
440
419
|
assert_tok :end_interpolation
|
|
441
420
|
wa = @lexer.whitespace?
|
|
442
421
|
char_after = @lexer.char
|
|
443
422
|
|
|
444
|
-
after =
|
|
423
|
+
after = send(inner)
|
|
445
424
|
before_deprecation = e.is_a?(Script::Tree::Interpolation) ? e.deprecation : :none
|
|
446
425
|
after_deprecation = after.is_a?(Script::Tree::Interpolation) ? after.deprecation : :none
|
|
447
426
|
|
|
@@ -500,7 +479,7 @@ RUBY
|
|
|
500
479
|
if arr.size == 1
|
|
501
480
|
arr.first
|
|
502
481
|
else
|
|
503
|
-
node(Sass::Script::Tree::ListLiteral.new(arr, :space), start_pos)
|
|
482
|
+
node(Sass::Script::Tree::ListLiteral.new(arr, separator: :space), start_pos)
|
|
504
483
|
end
|
|
505
484
|
end
|
|
506
485
|
|
|
@@ -549,12 +528,12 @@ RUBY
|
|
|
549
528
|
else
|
|
550
529
|
return [], nil unless try_tok(:lparen)
|
|
551
530
|
end
|
|
552
|
-
return [], nil if try_tok(:rparen)
|
|
553
531
|
|
|
554
532
|
res = []
|
|
555
533
|
splat = nil
|
|
556
534
|
must_have_default = false
|
|
557
535
|
loop do
|
|
536
|
+
break if peek_tok(:rparen)
|
|
558
537
|
c = assert_tok(:const)
|
|
559
538
|
var = node(Script::Tree::Variable.new(c.value), c.source_range)
|
|
560
539
|
if try_tok(:colon)
|
|
@@ -585,12 +564,8 @@ RUBY
|
|
|
585
564
|
def arglist(subexpr, description)
|
|
586
565
|
args = []
|
|
587
566
|
keywords = Sass::Util::NormalizedMap.new
|
|
588
|
-
e = send(subexpr)
|
|
589
|
-
|
|
590
|
-
return [args, keywords] unless e
|
|
591
|
-
|
|
592
567
|
splat = nil
|
|
593
|
-
|
|
568
|
+
while (e = send(subexpr))
|
|
594
569
|
if @lexer.peek && @lexer.peek.type == :colon
|
|
595
570
|
name = e
|
|
596
571
|
@lexer.expected!("comma") unless name.is_a?(Tree::Variable)
|
|
@@ -611,13 +586,12 @@ RUBY
|
|
|
611
586
|
elsif !keywords.empty?
|
|
612
587
|
raise SyntaxError.new("Positional arguments must come before keyword arguments.")
|
|
613
588
|
end
|
|
614
|
-
|
|
615
589
|
args << e if e
|
|
616
590
|
end
|
|
617
591
|
|
|
618
592
|
return args, keywords, splat unless try_tok(:comma)
|
|
619
|
-
e = assert_expr(subexpr, description)
|
|
620
593
|
end
|
|
594
|
+
return args, keywords
|
|
621
595
|
end
|
|
622
596
|
|
|
623
597
|
def raw
|
|
@@ -628,10 +602,10 @@ RUBY
|
|
|
628
602
|
|
|
629
603
|
def special_fun
|
|
630
604
|
first = try_tok(:special_fun)
|
|
631
|
-
return
|
|
605
|
+
return square_list unless first
|
|
632
606
|
str = literal_node(first.value, first.source_range)
|
|
633
607
|
return str unless try_tok(:string_interpolation)
|
|
634
|
-
mid =
|
|
608
|
+
mid = assert_expr :expr
|
|
635
609
|
assert_tok :end_interpolation
|
|
636
610
|
last = assert_expr(:special_fun)
|
|
637
611
|
node(
|
|
@@ -639,6 +613,50 @@ RUBY
|
|
|
639
613
|
first.source_range.start_pos)
|
|
640
614
|
end
|
|
641
615
|
|
|
616
|
+
def square_list
|
|
617
|
+
start_pos = source_position
|
|
618
|
+
return paren unless try_tok(:lsquare)
|
|
619
|
+
|
|
620
|
+
space_start_pos = source_position
|
|
621
|
+
e = interpolation(inner: :or_expr)
|
|
622
|
+
separator = nil
|
|
623
|
+
if e
|
|
624
|
+
elements = [e]
|
|
625
|
+
while (e = interpolation(inner: :or_expr))
|
|
626
|
+
elements << e
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
# If there's a comma after a space-separated list, it's actually a
|
|
630
|
+
# space-separated list nested in a comma-separated list.
|
|
631
|
+
if try_tok(:comma)
|
|
632
|
+
e = if elements.length == 1
|
|
633
|
+
elements.first
|
|
634
|
+
else
|
|
635
|
+
node(
|
|
636
|
+
Sass::Script::Tree::ListLiteral.new(elements, separator: :space),
|
|
637
|
+
space_start_pos)
|
|
638
|
+
end
|
|
639
|
+
elements = [e]
|
|
640
|
+
|
|
641
|
+
while (e = space)
|
|
642
|
+
elements << e
|
|
643
|
+
break unless try_tok(:comma)
|
|
644
|
+
end
|
|
645
|
+
separator = :comma
|
|
646
|
+
else
|
|
647
|
+
separator = :space if elements.length > 1
|
|
648
|
+
end
|
|
649
|
+
else
|
|
650
|
+
elements = []
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
assert_tok(:rsquare)
|
|
654
|
+
end_pos = source_position
|
|
655
|
+
|
|
656
|
+
node(Sass::Script::Tree::ListLiteral.new(elements, separator: separator, bracketed: true),
|
|
657
|
+
start_pos, end_pos)
|
|
658
|
+
end
|
|
659
|
+
|
|
642
660
|
def paren
|
|
643
661
|
return variable unless try_tok(:lparen)
|
|
644
662
|
start_pos = source_position
|
|
@@ -646,17 +664,13 @@ RUBY
|
|
|
646
664
|
e.force_division! if e
|
|
647
665
|
end_pos = source_position
|
|
648
666
|
assert_tok(:rparen)
|
|
649
|
-
|
|
650
|
-
@css_variable_warning.warn! if @css_variable_warning
|
|
651
|
-
e || node(Sass::Script::Tree::ListLiteral.new([], nil), start_pos, end_pos)
|
|
667
|
+
e || node(Sass::Script::Tree::ListLiteral.new([]), start_pos, end_pos)
|
|
652
668
|
end
|
|
653
669
|
|
|
654
670
|
def variable
|
|
655
671
|
start_pos = source_position
|
|
656
672
|
c = try_tok(:const)
|
|
657
673
|
return string unless c
|
|
658
|
-
|
|
659
|
-
@css_variable_warning.warn! if @css_variable_warning
|
|
660
674
|
node(Tree::Variable.new(*c.value), start_pos)
|
|
661
675
|
end
|
|
662
676
|
|
|
@@ -665,7 +679,7 @@ RUBY
|
|
|
665
679
|
return number unless first
|
|
666
680
|
str = literal_node(first.value, first.source_range)
|
|
667
681
|
return str unless try_tok(:string_interpolation)
|
|
668
|
-
mid =
|
|
682
|
+
mid = assert_expr :expr
|
|
669
683
|
assert_tok :end_interpolation
|
|
670
684
|
last = assert_expr(:string)
|
|
671
685
|
node(Tree::StringInterpolation.new(str, mid, last), first.source_range.start_pos)
|
|
@@ -683,7 +697,6 @@ RUBY
|
|
|
683
697
|
def selector
|
|
684
698
|
tok = try_tok(:selector)
|
|
685
699
|
return literal unless tok
|
|
686
|
-
@css_variable_warning.warn! if @css_variable_warning
|
|
687
700
|
node(tok.value, tok.source_range.start_pos)
|
|
688
701
|
end
|
|
689
702
|
|
|
@@ -723,10 +736,14 @@ RUBY
|
|
|
723
736
|
@lexer.expected!(names.map {|tok| Lexer::TOKEN_NAMES[tok] || tok}.join(" or "))
|
|
724
737
|
end
|
|
725
738
|
|
|
726
|
-
def
|
|
739
|
+
def peek_tok(name)
|
|
727
740
|
# Avoids an array allocation caused by argument globbing in the try_toks method.
|
|
728
741
|
peeked = @lexer.peek
|
|
729
|
-
peeked && name == peeked.type
|
|
742
|
+
peeked && name == peeked.type
|
|
743
|
+
end
|
|
744
|
+
|
|
745
|
+
def try_tok(name)
|
|
746
|
+
peek_tok(name) && @lexer.next
|
|
730
747
|
end
|
|
731
748
|
|
|
732
749
|
def try_toks(*names)
|
|
@@ -771,27 +788,12 @@ RUBY
|
|
|
771
788
|
range(source_range_or_start_pos, end_pos)
|
|
772
789
|
end
|
|
773
790
|
|
|
774
|
-
node.css_variable_warning = @css_variable_warning
|
|
775
791
|
node.line = source_range.start_pos.line
|
|
776
792
|
node.source_range = source_range
|
|
777
793
|
node.filename = @options[:filename]
|
|
778
794
|
node
|
|
779
795
|
end
|
|
780
796
|
|
|
781
|
-
# Runs the given block without CSS variable warnings enabled.
|
|
782
|
-
#
|
|
783
|
-
# CSS warnings don't apply within interpolation, so this is used to
|
|
784
|
-
# disable them.
|
|
785
|
-
#
|
|
786
|
-
# @yield []
|
|
787
|
-
def without_css_variable_warning
|
|
788
|
-
old_css_variable_warning = @css_variable_warning
|
|
789
|
-
@css_variable_warning = nil
|
|
790
|
-
yield
|
|
791
|
-
ensure
|
|
792
|
-
@css_variable_warning = old_css_variable_warning
|
|
793
|
-
end
|
|
794
|
-
|
|
795
797
|
# Checks a script node for any immediately-deprecated interpolations, and
|
|
796
798
|
# emits warnings for them.
|
|
797
799
|
#
|
|
@@ -13,6 +13,11 @@ module Sass::Script::Tree
|
|
|
13
13
|
# @return [String]
|
|
14
14
|
attr_reader :name
|
|
15
15
|
|
|
16
|
+
# The callable to be invoked
|
|
17
|
+
#
|
|
18
|
+
# @return [Sass::Callable] or nil if no callable is provided.
|
|
19
|
+
attr_reader :callable
|
|
20
|
+
|
|
16
21
|
# The arguments to the function.
|
|
17
22
|
#
|
|
18
23
|
# @return [Array<Node>]
|
|
@@ -39,13 +44,19 @@ module Sass::Script::Tree
|
|
|
39
44
|
# @return [Node?]
|
|
40
45
|
attr_accessor :kwarg_splat
|
|
41
46
|
|
|
42
|
-
# @param
|
|
47
|
+
# @param name_or_callable [String, Sass::Callable] See \{#name}
|
|
43
48
|
# @param args [Array<Node>] See \{#args}
|
|
44
49
|
# @param keywords [Sass::Util::NormalizedMap<Node>] See \{#keywords}
|
|
45
50
|
# @param splat [Node] See \{#splat}
|
|
46
51
|
# @param kwarg_splat [Node] See \{#kwarg_splat}
|
|
47
|
-
def initialize(
|
|
48
|
-
|
|
52
|
+
def initialize(name_or_callable, args, keywords, splat, kwarg_splat)
|
|
53
|
+
if name_or_callable.is_a?(Sass::Callable)
|
|
54
|
+
@callable = name_or_callable
|
|
55
|
+
@name = name_or_callable.name
|
|
56
|
+
else
|
|
57
|
+
@callable = nil
|
|
58
|
+
@name = name_or_callable
|
|
59
|
+
end
|
|
49
60
|
@args = args
|
|
50
61
|
@keywords = keywords
|
|
51
62
|
@splat = splat
|
|
@@ -56,8 +67,7 @@ module Sass::Script::Tree
|
|
|
56
67
|
# @return [String] A string representation of the function call
|
|
57
68
|
def inspect
|
|
58
69
|
args = @args.map {|a| a.inspect}.join(', ')
|
|
59
|
-
keywords =
|
|
60
|
-
map {|k, v| "$#{k}: #{v.inspect}"}.join(', ')
|
|
70
|
+
keywords = @keywords.as_stored.to_a.map {|k, v| "$#{k}: #{v.inspect}"}.join(', ')
|
|
61
71
|
# rubocop:disable RedundantSelf
|
|
62
72
|
if self.splat
|
|
63
73
|
splat = args.empty? && keywords.empty? ? "" : ", "
|
|
@@ -77,8 +87,7 @@ module Sass::Script::Tree
|
|
|
77
87
|
end
|
|
78
88
|
|
|
79
89
|
args = @args.map(&arg_to_sass)
|
|
80
|
-
keywords =
|
|
81
|
-
map {|k, v| "$#{dasherize(k, opts)}: #{arg_to_sass[v]}"}
|
|
90
|
+
keywords = @keywords.as_stored.to_a.map {|k, v| "$#{dasherize(k, opts)}: #{arg_to_sass[v]}"}
|
|
82
91
|
|
|
83
92
|
# rubocop:disable RedundantSelf
|
|
84
93
|
if self.splat
|
|
@@ -120,27 +129,31 @@ module Sass::Script::Tree
|
|
|
120
129
|
# @return [Sass::Script::Value] The SassScript object that is the value of the function call
|
|
121
130
|
# @raise [Sass::SyntaxError] if the function call raises an ArgumentError
|
|
122
131
|
def _perform(environment)
|
|
123
|
-
args =
|
|
132
|
+
args = @args.each_with_index.
|
|
124
133
|
map {|a, i| perform_arg(a, environment, signature && signature.args[i])}
|
|
125
134
|
keywords = Sass::Util.map_hash(@keywords) do |k, v|
|
|
126
135
|
[k, perform_arg(v, environment, k.tr('-', '_'))]
|
|
127
136
|
end
|
|
128
137
|
splat = Sass::Tree::Visitors::Perform.perform_splat(
|
|
129
138
|
@splat, keywords, @kwarg_splat, environment)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
139
|
+
|
|
140
|
+
fn = @callable || environment.function(@name)
|
|
141
|
+
|
|
142
|
+
if fn && fn.origin == :stylesheet
|
|
143
|
+
environment.stack.with_function(filename, line, name) do
|
|
144
|
+
return without_original(perform_sass_fn(fn, args, splat, environment))
|
|
145
|
+
end
|
|
133
146
|
end
|
|
134
147
|
|
|
135
148
|
args = construct_ruby_args(ruby_name, args, splat, environment)
|
|
136
149
|
|
|
137
|
-
if Sass::Script::Functions.callable?(ruby_name)
|
|
138
|
-
css_variable_warning.warn! if css_variable_warning
|
|
139
|
-
|
|
150
|
+
if Sass::Script::Functions.callable?(ruby_name) && (!fn || fn.origin == :builtin)
|
|
140
151
|
local_environment = Sass::Environment.new(environment.global_env, environment.options)
|
|
141
152
|
local_environment.caller = Sass::ReadOnlyEnvironment.new(environment, environment.options)
|
|
142
|
-
result =
|
|
143
|
-
|
|
153
|
+
result = local_environment.stack.with_function(filename, line, name) do
|
|
154
|
+
opts(Sass::Script::Functions::EvaluationContext.new(
|
|
155
|
+
local_environment).send(ruby_name, *args))
|
|
156
|
+
end
|
|
144
157
|
without_original(result)
|
|
145
158
|
else
|
|
146
159
|
opts(to_literal(args))
|
|
@@ -206,6 +219,7 @@ module Sass::Script::Tree
|
|
|
206
219
|
raise Sass::SyntaxError.new(
|
|
207
220
|
"#{args[signature.args.size].inspect} is not a keyword argument for `#{name}'")
|
|
208
221
|
elsif keywords.empty?
|
|
222
|
+
args << {} if signature.var_kwargs
|
|
209
223
|
return args
|
|
210
224
|
end
|
|
211
225
|
|
|
@@ -271,30 +285,21 @@ module Sass::Script::Tree
|
|
|
271
285
|
message = "wrong number of arguments (#{given} for #{expected})"
|
|
272
286
|
end
|
|
273
287
|
elsif Sass::Util.jruby?
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
# is manually-thrown ArgumentErrors, which are indistinguishable from
|
|
278
|
-
# legitimate ArgumentErrors. We treat both of these as
|
|
279
|
-
# Sass::SyntaxErrors even though it can hide Ruby errors.
|
|
280
|
-
e.backtrace[0] !~ /:in `(block in )?#{ruby_name}'$/
|
|
281
|
-
else
|
|
282
|
-
should_maybe_raise =
|
|
283
|
-
e.message =~ /^wrong number of arguments calling `[^`]+` \((\d+) for (\d+)\)/
|
|
284
|
-
given, expected = $1, $2
|
|
285
|
-
end
|
|
288
|
+
should_maybe_raise =
|
|
289
|
+
e.message =~ /^wrong number of arguments calling `[^`]+` \((\d+) for (\d+)\)/
|
|
290
|
+
given, expected = $1, $2
|
|
286
291
|
|
|
287
292
|
if should_maybe_raise
|
|
288
293
|
# JRuby 1.7 includes __send__ before send and _perform.
|
|
289
294
|
trace = e.backtrace.dup
|
|
290
|
-
raise e if
|
|
295
|
+
raise e if trace.shift !~ /:in `__send__'$/
|
|
291
296
|
|
|
292
297
|
# JRuby (as of 1.7.2) doesn't put the actual method
|
|
293
298
|
# for which the argument error was thrown in the backtrace, so we
|
|
294
299
|
# detect whether our send threw an argument error.
|
|
295
300
|
if !(trace[0] =~ /:in `send'$/ && trace[1] =~ /:in `_perform'$/)
|
|
296
301
|
raise e
|
|
297
|
-
|
|
302
|
+
else
|
|
298
303
|
# JRuby 1.7 doesn't use standard formatting for its ArgumentErrors.
|
|
299
304
|
message = "wrong number of arguments (#{given} for #{expected})"
|
|
300
305
|
end
|
|
@@ -13,13 +13,20 @@ module Sass::Script::Tree
|
|
|
13
13
|
# @return [Symbol]
|
|
14
14
|
attr_reader :separator
|
|
15
15
|
|
|
16
|
+
# Whether the list is surrounded by square brackets.
|
|
17
|
+
#
|
|
18
|
+
# @return [Boolean]
|
|
19
|
+
attr_reader :bracketed
|
|
20
|
+
|
|
16
21
|
# Creates a new list literal.
|
|
17
22
|
#
|
|
18
23
|
# @param elements [Array<Node>] See \{#elements}
|
|
19
24
|
# @param separator [Symbol] See \{#separator}
|
|
20
|
-
|
|
25
|
+
# @param bracketed [Boolean] See \{#bracketed}
|
|
26
|
+
def initialize(elements, separator: nil, bracketed: false)
|
|
21
27
|
@elements = elements
|
|
22
28
|
@separator = separator
|
|
29
|
+
@bracketed = bracketed
|
|
23
30
|
end
|
|
24
31
|
|
|
25
32
|
# @see Node#children
|
|
@@ -27,7 +34,7 @@ module Sass::Script::Tree
|
|
|
27
34
|
|
|
28
35
|
# @see Value#to_sass
|
|
29
36
|
def to_sass(opts = {})
|
|
30
|
-
return "()" if elements.empty?
|
|
37
|
+
return bracketed ? "[]" : "()" if elements.empty?
|
|
31
38
|
members = elements.map do |v|
|
|
32
39
|
if element_needs_parens?(v)
|
|
33
40
|
"(#{v.to_sass(opts)})"
|
|
@@ -36,9 +43,12 @@ module Sass::Script::Tree
|
|
|
36
43
|
end
|
|
37
44
|
end
|
|
38
45
|
|
|
39
|
-
|
|
46
|
+
if separator == :comma && members.length == 1
|
|
47
|
+
return "#{bracketed ? '[' : '('}#{members.first},#{bracketed ? ']' : ')'}"
|
|
48
|
+
end
|
|
40
49
|
|
|
41
|
-
members.join(sep_str(nil))
|
|
50
|
+
contents = members.join(sep_str(nil))
|
|
51
|
+
bracketed ? "[#{contents}]" : contents
|
|
42
52
|
end
|
|
43
53
|
|
|
44
54
|
# @see Node#deep_copy
|
|
@@ -49,7 +59,9 @@ module Sass::Script::Tree
|
|
|
49
59
|
end
|
|
50
60
|
|
|
51
61
|
def inspect
|
|
52
|
-
|
|
62
|
+
(bracketed ? '[' : '(') +
|
|
63
|
+
elements.map {|e| e.inspect}.join(separator == :space ? ' ' : ', ') +
|
|
64
|
+
(bracketed ? ']' : ')')
|
|
53
65
|
end
|
|
54
66
|
|
|
55
67
|
def force_division!
|
|
@@ -61,7 +73,8 @@ module Sass::Script::Tree
|
|
|
61
73
|
def _perform(environment)
|
|
62
74
|
list = Sass::Script::Value::List.new(
|
|
63
75
|
elements.map {|e| e.perform(environment)},
|
|
64
|
-
separator
|
|
76
|
+
separator: separator,
|
|
77
|
+
bracketed: bracketed)
|
|
65
78
|
list.source_range = source_range
|
|
66
79
|
list.options = options
|
|
67
80
|
list
|
|
@@ -73,8 +86,10 @@ module Sass::Script::Tree
|
|
|
73
86
|
# when serialized to Sass.
|
|
74
87
|
def element_needs_parens?(element)
|
|
75
88
|
if element.is_a?(ListLiteral)
|
|
76
|
-
return
|
|
77
|
-
|
|
89
|
+
return false if element.elements.length < 2
|
|
90
|
+
return false if element.bracketed
|
|
91
|
+
return Sass::Script::Parser.precedence_of(element.separator || :space) <=
|
|
92
|
+
Sass::Script::Parser.precedence_of(separator || :space)
|
|
78
93
|
end
|
|
79
94
|
|
|
80
95
|
return false unless separator == :space
|
|
@@ -49,14 +49,14 @@ module Sass::Script::Tree
|
|
|
49
49
|
# @see Node#_perform
|
|
50
50
|
def _perform(environment)
|
|
51
51
|
keys = Set.new
|
|
52
|
-
map = Sass::Script::Value::Map.new(
|
|
52
|
+
map = Sass::Script::Value::Map.new(Hash[pairs.map do |(k, v)|
|
|
53
53
|
k, v = k.perform(environment), v.perform(environment)
|
|
54
54
|
if keys.include?(k)
|
|
55
55
|
raise Sass::SyntaxError.new("Duplicate key #{k.inspect} in map #{to_sass}.")
|
|
56
56
|
end
|
|
57
57
|
keys << k
|
|
58
58
|
[k, v]
|
|
59
|
-
end)
|
|
59
|
+
end])
|
|
60
60
|
map.options = options
|
|
61
61
|
map
|
|
62
62
|
end
|
|
@@ -23,14 +23,6 @@ module Sass::Script::Tree
|
|
|
23
23
|
# @return [String]
|
|
24
24
|
attr_accessor :filename
|
|
25
25
|
|
|
26
|
-
# The warning that this node should emit if it executes in a way that's not
|
|
27
|
-
# safe for a CSS variable value.
|
|
28
|
-
#
|
|
29
|
-
# This is `nil` if this is not in a CSS variable value.
|
|
30
|
-
#
|
|
31
|
-
# @return [Sass::Script::CssVariableWarning]
|
|
32
|
-
attr_accessor :css_variable_warning
|
|
33
|
-
|
|
34
26
|
# Sets the options hash for this node,
|
|
35
27
|
# as well as for all child nodes.
|
|
36
28
|
# See {file:SASS_REFERENCE.md#Options the Sass options documentation}.
|
|
@@ -81,13 +81,6 @@ module Sass::Script::Tree
|
|
|
81
81
|
"Invalid null operation: \"#{value1.inspect} #{@operator} #{value2.inspect}\".")
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
if css_variable_warning && @operator == :div &&
|
|
85
|
-
!(value1.is_a?(Sass::Script::Value::Number) && value1.original &&
|
|
86
|
-
value2.is_a?(Sass::Script::Value::Number) && value2.original) &&
|
|
87
|
-
!(value1.is_a?(Sass::Script::Value::String) && value2.is_a?(Sass::Script::Value::String))
|
|
88
|
-
css_variable_warning.warn!
|
|
89
|
-
end
|
|
90
|
-
|
|
91
84
|
begin
|
|
92
85
|
result = opts(value1.send(@operator, value2))
|
|
93
86
|
rescue NoMethodError => e
|
|
@@ -17,7 +17,7 @@ module Sass::Script::Value
|
|
|
17
17
|
# @param keywords [Hash<String, Value>, NormalizedMap<Value>] See \{#keywords}
|
|
18
18
|
# @param separator [String] See \{List#separator}.
|
|
19
19
|
def initialize(value, keywords, separator)
|
|
20
|
-
super(value, separator)
|
|
20
|
+
super(value, separator: separator)
|
|
21
21
|
if keywords.is_a?(Sass::Util::NormalizedMap)
|
|
22
22
|
@keywords = keywords
|
|
23
23
|
else
|
|
@@ -192,6 +192,12 @@ MSG
|
|
|
192
192
|
# @return [Symbol]
|
|
193
193
|
def separator; nil; end
|
|
194
194
|
|
|
195
|
+
# Whether the value is surrounded by square brackets. For non-list values,
|
|
196
|
+
# this will be `false`.
|
|
197
|
+
#
|
|
198
|
+
# @return [Boolean]
|
|
199
|
+
def bracketed; false; end
|
|
200
|
+
|
|
195
201
|
# Returns the value of this value as a list.
|
|
196
202
|
# Single values are considered the same as single-element lists.
|
|
197
203
|
#
|
|
@@ -228,6 +234,17 @@ MSG
|
|
|
228
234
|
false
|
|
229
235
|
end
|
|
230
236
|
|
|
237
|
+
# Creates a new list containing `contents` but with the same brackets and
|
|
238
|
+
# separators as this object, when interpreted as a list.
|
|
239
|
+
#
|
|
240
|
+
# @param contents [Array<Value>] The contents of the new list.
|
|
241
|
+
# @param separator [Symbol] The separator of the new list. Defaults to \{#separator}.
|
|
242
|
+
# @param bracketed [Boolean] Whether the new list is bracketed. Defaults to \{#bracketed}.
|
|
243
|
+
# @return [Sass::Script::Value::List]
|
|
244
|
+
def with_contents(contents, separator: self.separator, bracketed: self.bracketed)
|
|
245
|
+
Sass::Script::Value::List.new(contents, separator: separator, bracketed: bracketed)
|
|
246
|
+
end
|
|
247
|
+
|
|
231
248
|
protected
|
|
232
249
|
|
|
233
250
|
# Evaluates the value.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Sass::Script::Value
|
|
2
|
+
# A SassScript object representing a null value.
|
|
3
|
+
class Callable < Base
|
|
4
|
+
# Constructs a Callable value for use in SassScript.
|
|
5
|
+
#
|
|
6
|
+
# @param callable [Sass::Callable] The callable to be used when the
|
|
7
|
+
# callable is called.
|
|
8
|
+
def initialize(callable)
|
|
9
|
+
super(callable)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def to_s(opts = {})
|
|
13
|
+
raise Sass::SyntaxError.new("#{to_sass} isn't a valid CSS value.")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def inspect
|
|
17
|
+
to_sass
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @abstract
|
|
21
|
+
def to_sass
|
|
22
|
+
Sass::Util.abstract(self)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -563,6 +563,11 @@ module Sass::Script::Value
|
|
|
563
563
|
def to_s(opts = {})
|
|
564
564
|
return smallest if options[:style] == :compressed
|
|
565
565
|
return representation if representation
|
|
566
|
+
|
|
567
|
+
# IE10 doesn't properly support the color name "transparent", so we emit
|
|
568
|
+
# generated transparent colors as rgba(0, 0, 0, 0) in favor of that. See
|
|
569
|
+
# #1782.
|
|
570
|
+
return rgba_str if Number.basically_equal?(alpha, 0)
|
|
566
571
|
return name if name
|
|
567
572
|
alpha? ? rgba_str : hex_str
|
|
568
573
|
end
|