sass 3.3.0 → 3.4.25
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/.yardopts +3 -1
- data/CODE_OF_CONDUCT.md +10 -0
- data/CONTRIBUTING.md +148 -0
- data/MIT-LICENSE +1 -1
- data/README.md +76 -62
- data/Rakefile +104 -24
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/bin/sass +1 -1
- data/bin/scss +1 -1
- data/extra/sass-spec-ref.sh +32 -0
- data/extra/update_watch.rb +1 -1
- data/lib/sass/cache_stores/filesystem.rb +9 -5
- data/lib/sass/cache_stores/memory.rb +4 -5
- data/lib/sass/callbacks.rb +2 -2
- data/lib/sass/css.rb +12 -13
- data/lib/sass/deprecation.rb +55 -0
- data/lib/sass/engine.rb +106 -70
- data/lib/sass/environment.rb +39 -19
- data/lib/sass/error.rb +17 -20
- data/lib/sass/exec/base.rb +199 -0
- data/lib/sass/exec/sass_convert.rb +283 -0
- data/lib/sass/exec/sass_scss.rb +440 -0
- data/lib/sass/exec.rb +5 -771
- data/lib/sass/features.rb +9 -2
- data/lib/sass/importers/base.rb +8 -3
- data/lib/sass/importers/filesystem.rb +30 -38
- data/lib/sass/logger/base.rb +8 -2
- data/lib/sass/logger/delayed.rb +50 -0
- data/lib/sass/logger.rb +8 -3
- data/lib/sass/media.rb +1 -4
- data/lib/sass/plugin/compiler.rb +224 -90
- data/lib/sass/plugin/configuration.rb +38 -22
- data/lib/sass/plugin/merb.rb +2 -2
- data/lib/sass/plugin/rack.rb +3 -3
- data/lib/sass/plugin/rails.rb +1 -1
- data/lib/sass/plugin/staleness_checker.rb +4 -4
- data/lib/sass/plugin.rb +6 -5
- data/lib/sass/script/css_lexer.rb +1 -1
- data/lib/sass/script/css_parser.rb +2 -3
- data/lib/sass/script/css_variable_warning.rb +52 -0
- data/lib/sass/script/functions.rb +739 -318
- data/lib/sass/script/lexer.rb +134 -54
- data/lib/sass/script/parser.rb +252 -56
- data/lib/sass/script/tree/funcall.rb +13 -6
- data/lib/sass/script/tree/interpolation.rb +127 -4
- data/lib/sass/script/tree/list_literal.rb +31 -4
- data/lib/sass/script/tree/literal.rb +4 -0
- data/lib/sass/script/tree/node.rb +21 -3
- data/lib/sass/script/tree/operation.rb +54 -1
- data/lib/sass/script/tree/selector.rb +26 -0
- data/lib/sass/script/tree/string_interpolation.rb +59 -38
- data/lib/sass/script/tree/variable.rb +1 -1
- data/lib/sass/script/tree.rb +1 -0
- data/lib/sass/script/value/base.rb +17 -14
- data/lib/sass/script/value/bool.rb +0 -5
- data/lib/sass/script/value/color.rb +78 -42
- data/lib/sass/script/value/helpers.rb +119 -2
- data/lib/sass/script/value/list.rb +0 -15
- data/lib/sass/script/value/map.rb +1 -1
- data/lib/sass/script/value/null.rb +0 -5
- data/lib/sass/script/value/number.rb +112 -31
- data/lib/sass/script/value/string.rb +102 -13
- data/lib/sass/script/value.rb +0 -1
- data/lib/sass/script.rb +3 -3
- data/lib/sass/scss/css_parser.rb +24 -4
- data/lib/sass/scss/parser.rb +290 -383
- data/lib/sass/scss/rx.rb +17 -9
- data/lib/sass/scss/static_parser.rb +306 -4
- data/lib/sass/scss.rb +0 -2
- data/lib/sass/selector/abstract_sequence.rb +35 -18
- data/lib/sass/selector/comma_sequence.rb +114 -19
- data/lib/sass/selector/pseudo.rb +266 -0
- data/lib/sass/selector/sequence.rb +146 -40
- data/lib/sass/selector/simple.rb +22 -33
- data/lib/sass/selector/simple_sequence.rb +122 -39
- data/lib/sass/selector.rb +57 -197
- data/lib/sass/shared.rb +2 -2
- data/lib/sass/source/map.rb +31 -14
- data/lib/sass/source/position.rb +4 -4
- data/lib/sass/stack.rb +2 -8
- data/lib/sass/supports.rb +10 -13
- data/lib/sass/tree/at_root_node.rb +1 -0
- data/lib/sass/tree/charset_node.rb +1 -1
- data/lib/sass/tree/comment_node.rb +1 -1
- data/lib/sass/tree/css_import_node.rb +9 -1
- data/lib/sass/tree/directive_node.rb +8 -2
- data/lib/sass/tree/error_node.rb +18 -0
- data/lib/sass/tree/extend_node.rb +1 -1
- data/lib/sass/tree/function_node.rb +9 -0
- data/lib/sass/tree/import_node.rb +6 -5
- data/lib/sass/tree/keyframe_rule_node.rb +15 -0
- data/lib/sass/tree/node.rb +5 -3
- data/lib/sass/tree/prop_node.rb +6 -7
- data/lib/sass/tree/rule_node.rb +26 -11
- data/lib/sass/tree/visitors/check_nesting.rb +56 -32
- data/lib/sass/tree/visitors/convert.rb +59 -44
- data/lib/sass/tree/visitors/cssize.rb +34 -30
- data/lib/sass/tree/visitors/deep_copy.rb +6 -1
- data/lib/sass/tree/visitors/extend.rb +15 -13
- data/lib/sass/tree/visitors/perform.rb +87 -50
- data/lib/sass/tree/visitors/set_options.rb +15 -1
- data/lib/sass/tree/visitors/to_css.rb +72 -43
- data/lib/sass/util/multibyte_string_scanner.rb +0 -2
- data/lib/sass/util/normalized_map.rb +0 -1
- data/lib/sass/util/subset_map.rb +2 -3
- data/lib/sass/util.rb +334 -154
- data/lib/sass/version.rb +7 -7
- data/lib/sass.rb +10 -8
- data/test/sass/cache_test.rb +62 -20
- data/test/sass/callbacks_test.rb +1 -1
- data/test/sass/compiler_test.rb +24 -11
- data/test/sass/conversion_test.rb +241 -50
- data/test/sass/css2sass_test.rb +73 -5
- data/test/sass/css_variable_test.rb +132 -0
- data/test/sass/encoding_test.rb +219 -0
- data/test/sass/engine_test.rb +343 -260
- data/test/sass/exec_test.rb +12 -2
- data/test/sass/extend_test.rb +333 -44
- data/test/sass/functions_test.rb +353 -260
- data/test/sass/importer_test.rb +40 -21
- data/test/sass/logger_test.rb +1 -1
- data/test/sass/more_results/more_import.css +1 -1
- data/test/sass/more_templates/more1.sass +10 -10
- data/test/sass/more_templates/more_import.sass +2 -2
- data/test/sass/plugin_test.rb +24 -21
- data/test/sass/results/compact.css +1 -1
- data/test/sass/results/complex.css +4 -4
- data/test/sass/results/expanded.css +1 -1
- data/test/sass/results/import.css +1 -1
- data/test/sass/results/import_charset_ibm866.css +2 -2
- data/test/sass/results/mixins.css +17 -17
- data/test/sass/results/nested.css +1 -1
- data/test/sass/results/parent_ref.css +2 -2
- data/test/sass/results/script.css +5 -5
- data/test/sass/results/scss_import.css +1 -1
- data/test/sass/script_conversion_test.rb +71 -39
- data/test/sass/script_test.rb +714 -123
- data/test/sass/scss/css_test.rb +213 -30
- data/test/sass/scss/rx_test.rb +8 -4
- data/test/sass/scss/scss_test.rb +766 -22
- data/test/sass/source_map_test.rb +263 -95
- data/test/sass/superselector_test.rb +210 -0
- data/test/sass/templates/_partial.sass +1 -1
- data/test/sass/templates/basic.sass +10 -10
- data/test/sass/templates/bork1.sass +1 -1
- data/test/sass/templates/bork5.sass +1 -1
- data/test/sass/templates/compact.sass +10 -10
- data/test/sass/templates/complex.sass +187 -187
- data/test/sass/templates/compressed.sass +10 -10
- data/test/sass/templates/expanded.sass +10 -10
- data/test/sass/templates/import.sass +2 -2
- data/test/sass/templates/importee.sass +3 -3
- data/test/sass/templates/mixins.sass +22 -22
- data/test/sass/templates/multiline.sass +4 -4
- data/test/sass/templates/nested.sass +13 -13
- data/test/sass/templates/parent_ref.sass +12 -12
- data/test/sass/templates/script.sass +70 -70
- data/test/sass/templates/scss_import.scss +2 -1
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +1 -1
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +2 -2
- data/test/sass/templates/subdir/subdir.sass +3 -3
- data/test/sass/templates/units.sass +10 -10
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +11 -3
- data/test/sass/util/normalized_map_test.rb +1 -1
- data/test/sass/util/subset_map_test.rb +2 -2
- data/test/sass/util_test.rb +46 -45
- data/test/sass/value_helpers_test.rb +5 -7
- data/test/sass-spec.yml +3 -0
- data/test/test_helper.rb +7 -6
- data/vendor/listen/CHANGELOG.md +1 -228
- data/vendor/listen/Gemfile +5 -15
- data/vendor/listen/README.md +111 -77
- data/vendor/listen/Rakefile +0 -42
- data/vendor/listen/lib/listen/adapter.rb +195 -82
- data/vendor/listen/lib/listen/adapters/bsd.rb +27 -64
- data/vendor/listen/lib/listen/adapters/darwin.rb +21 -58
- data/vendor/listen/lib/listen/adapters/linux.rb +23 -55
- data/vendor/listen/lib/listen/adapters/polling.rb +25 -34
- data/vendor/listen/lib/listen/adapters/windows.rb +50 -46
- data/vendor/listen/lib/listen/directory_record.rb +96 -61
- data/vendor/listen/lib/listen/listener.rb +135 -37
- data/vendor/listen/lib/listen/turnstile.rb +9 -5
- data/vendor/listen/lib/listen/version.rb +1 -1
- data/vendor/listen/lib/listen.rb +33 -19
- data/vendor/listen/listen.gemspec +6 -0
- data/vendor/listen/spec/listen/adapter_spec.rb +43 -77
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +8 -8
- data/vendor/listen/spec/listen/directory_record_spec.rb +81 -56
- data/vendor/listen/spec/listen/listener_spec.rb +128 -39
- data/vendor/listen/spec/listen_spec.rb +15 -21
- data/vendor/listen/spec/spec_helper.rb +4 -0
- data/vendor/listen/spec/support/adapter_helper.rb +52 -15
- data/vendor/listen/spec/support/directory_record_helper.rb +7 -5
- data/vendor/listen/spec/support/listeners_helper.rb +30 -7
- metadata +310 -300
- data/CONTRIBUTING +0 -3
- data/ext/mkrf_conf.rb +0 -27
- data/lib/sass/script/value/deprecated_false.rb +0 -55
- data/lib/sass/scss/script_lexer.rb +0 -15
- data/lib/sass/scss/script_parser.rb +0 -25
- data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
- data/vendor/listen/lib/listen/multi_listener.rb +0 -143
- data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
- data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
@@ -34,25 +34,35 @@ module Sass::Script::Value
|
|
34
34
|
attr_accessor :original
|
35
35
|
|
36
36
|
def self.precision
|
37
|
-
|
37
|
+
Thread.current[:sass_numeric_precision] || Thread.main[:sass_numeric_precision] || 5
|
38
38
|
end
|
39
39
|
|
40
40
|
# Sets the number of digits of precision
|
41
41
|
# For example, if this is `3`,
|
42
42
|
# `3.1415926` will be printed as `3.142`.
|
43
|
+
# The numeric precision is stored as a thread local for thread safety reasons.
|
44
|
+
# To set for all threads, be sure to set the precision on the main thread.
|
43
45
|
def self.precision=(digits)
|
44
|
-
|
45
|
-
|
46
|
+
Thread.current[:sass_numeric_precision] = digits.round
|
47
|
+
Thread.current[:sass_numeric_precision_factor] = nil
|
48
|
+
Thread.current[:sass_numeric_epsilon] = nil
|
46
49
|
end
|
47
50
|
|
48
51
|
# the precision factor used in numeric output
|
49
52
|
# it is derived from the `precision` method.
|
50
53
|
def self.precision_factor
|
51
|
-
|
54
|
+
Thread.current[:sass_numeric_precision_factor] ||= 10.0**precision
|
55
|
+
end
|
56
|
+
|
57
|
+
# Used in checking equality of floating point numbers. Any
|
58
|
+
# numbers within an `epsilon` of each other are considered functionally equal.
|
59
|
+
# The value for epsilon is one tenth of the current numeric precision.
|
60
|
+
def self.epsilon
|
61
|
+
Thread.current[:sass_numeric_epsilon] ||= 1 / (precision_factor * 10)
|
52
62
|
end
|
53
63
|
|
54
64
|
# Used so we don't allocate two new arrays for each new number.
|
55
|
-
NO_UNITS
|
65
|
+
NO_UNITS = []
|
56
66
|
|
57
67
|
# @param value [Numeric] The value of the number
|
58
68
|
# @param numerator_units [::String, Array<::String>] See \{#numerator\_units}
|
@@ -63,6 +73,7 @@ module Sass::Script::Value
|
|
63
73
|
super(value)
|
64
74
|
@numerator_units = numerator_units
|
65
75
|
@denominator_units = denominator_units
|
76
|
+
@options = nil
|
66
77
|
normalize!
|
67
78
|
end
|
68
79
|
|
@@ -200,7 +211,7 @@ module Sass::Script::Value
|
|
200
211
|
rescue Sass::UnitConversionError
|
201
212
|
return Bool::FALSE
|
202
213
|
end
|
203
|
-
Bool.new(this.value
|
214
|
+
Bool.new(basically_equal?(this.value, other.value))
|
204
215
|
end
|
205
216
|
|
206
217
|
def hash
|
@@ -211,7 +222,7 @@ module Sass::Script::Value
|
|
211
222
|
# Hash-equality must be transitive, so it just compares the exact value,
|
212
223
|
# numerator units, and denominator units.
|
213
224
|
def eql?(other)
|
214
|
-
value
|
225
|
+
basically_equal?(value, other.value) && numerator_units == other.numerator_units &&
|
215
226
|
denominator_units == other.denominator_units
|
216
227
|
end
|
217
228
|
|
@@ -271,6 +282,8 @@ module Sass::Script::Value
|
|
271
282
|
#
|
272
283
|
# @return [String] The representation
|
273
284
|
def inspect(opts = {})
|
285
|
+
return original if original
|
286
|
+
|
274
287
|
value = self.class.round(self.value)
|
275
288
|
str = value.to_s
|
276
289
|
|
@@ -279,20 +292,30 @@ module Sass::Script::Value
|
|
279
292
|
# and confusing.
|
280
293
|
str = ("%0.#{self.class.precision}f" % value).gsub(/0*$/, '') if str.include?('e')
|
281
294
|
|
295
|
+
# Sometimes numeric formatting will result in a decimal number with a trailing zero (x.0)
|
296
|
+
if str =~ /(.*)\.0$/
|
297
|
+
str = $1
|
298
|
+
end
|
299
|
+
|
300
|
+
# We omit a leading zero before the decimal point in compressed mode.
|
301
|
+
if @options && options[:style] == :compressed
|
302
|
+
str.sub!(/^(-)?0\./, '\1.')
|
303
|
+
end
|
304
|
+
|
282
305
|
unitless? ? str : "#{str}#{unit_str}"
|
283
306
|
end
|
284
307
|
alias_method :to_sass, :inspect
|
285
308
|
|
286
|
-
# @return [
|
309
|
+
# @return [Integer] The integer value of the number
|
287
310
|
# @raise [Sass::SyntaxError] if the number isn't an integer
|
288
311
|
def to_i
|
289
312
|
super unless int?
|
290
|
-
value
|
313
|
+
value.to_i
|
291
314
|
end
|
292
315
|
|
293
316
|
# @return [Boolean] Whether or not this number is an integer.
|
294
317
|
def int?
|
295
|
-
value % 1
|
318
|
+
basically_equal?(value % 1, 0.0)
|
296
319
|
end
|
297
320
|
|
298
321
|
# @return [Boolean] Whether or not this number has no units.
|
@@ -373,12 +396,24 @@ module Sass::Script::Value
|
|
373
396
|
|
374
397
|
private
|
375
398
|
|
399
|
+
# @private
|
400
|
+
# @see Sass::Script::Number.basically_equal?
|
401
|
+
def basically_equal?(num1, num2)
|
402
|
+
self.class.basically_equal?(num1, num2)
|
403
|
+
end
|
404
|
+
|
405
|
+
# Checks whether two numbers are within an epsilon of each other.
|
406
|
+
# @return [Boolean]
|
407
|
+
def self.basically_equal?(num1, num2)
|
408
|
+
(num1 - num2).abs < epsilon
|
409
|
+
end
|
410
|
+
|
376
411
|
# @private
|
377
412
|
def self.round(num)
|
378
413
|
if num.is_a?(Float) && (num.infinite? || num.nan?)
|
379
414
|
num
|
380
|
-
elsif num % 1
|
381
|
-
num.
|
415
|
+
elsif basically_equal?(num % 1, 0.0)
|
416
|
+
num.round
|
382
417
|
else
|
383
418
|
((num * precision_factor).round / precision_factor).to_f
|
384
419
|
end
|
@@ -437,33 +472,79 @@ module Sass::Script::Value
|
|
437
472
|
sans_common_units(@numerator_units, @denominator_units)
|
438
473
|
|
439
474
|
@denominator_units.each_with_index do |d, i|
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
end
|
475
|
+
next unless convertable?(d) && (u = @numerator_units.find(&method(:convertable?)))
|
476
|
+
@value /= conversion_factor(d, u)
|
477
|
+
@denominator_units.delete_at(i)
|
478
|
+
@numerator_units.delete_at(@numerator_units.index(u))
|
445
479
|
end
|
446
480
|
end
|
447
481
|
|
448
|
-
#
|
449
|
-
|
450
|
-
|
451
|
-
#
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
482
|
+
# This is the source data for all the unit logic. It's pre-processed to make
|
483
|
+
# it efficient to figure out whether a set of units is mutually compatible
|
484
|
+
# and what the conversion ratio is between two units.
|
485
|
+
#
|
486
|
+
# These come from http://www.w3.org/TR/2012/WD-css3-values-20120308/.
|
487
|
+
relative_sizes = [
|
488
|
+
{
|
489
|
+
'in' => Rational(1),
|
490
|
+
'cm' => Rational(1, 2.54),
|
491
|
+
'pc' => Rational(1, 6),
|
492
|
+
'mm' => Rational(1, 25.4),
|
493
|
+
'q' => Rational(1, 101.6),
|
494
|
+
'pt' => Rational(1, 72),
|
495
|
+
'px' => Rational(1, 96)
|
496
|
+
},
|
497
|
+
{
|
498
|
+
'deg' => Rational(1, 360),
|
499
|
+
'grad' => Rational(1, 400),
|
500
|
+
'rad' => Rational(1, 2 * Math::PI),
|
501
|
+
'turn' => Rational(1)
|
502
|
+
},
|
503
|
+
{
|
504
|
+
's' => Rational(1),
|
505
|
+
'ms' => Rational(1, 1000)
|
506
|
+
},
|
507
|
+
{
|
508
|
+
'Hz' => Rational(1),
|
509
|
+
'kHz' => Rational(1000)
|
510
|
+
},
|
511
|
+
{
|
512
|
+
'dpi' => Rational(1),
|
513
|
+
'dpcm' => Rational(254, 100),
|
514
|
+
'dppx' => Rational(96)
|
515
|
+
}
|
516
|
+
]
|
517
|
+
|
518
|
+
# A hash from each known unit to the set of units that it's mutually
|
519
|
+
# convertible with.
|
520
|
+
MUTUALLY_CONVERTIBLE = {}
|
521
|
+
relative_sizes.map do |values|
|
522
|
+
set = values.keys.to_set
|
523
|
+
values.keys.each {|name| MUTUALLY_CONVERTIBLE[name] = set}
|
524
|
+
end
|
525
|
+
|
526
|
+
# A two-dimensional hash from two units to the conversion ratio between
|
527
|
+
# them. Multiply `X` by `CONVERSION_TABLE[X][Y]` to convert it to `Y`.
|
528
|
+
CONVERSION_TABLE = {}
|
529
|
+
relative_sizes.each do |values|
|
530
|
+
values.each do |(name1, value1)|
|
531
|
+
CONVERSION_TABLE[name1] ||= {}
|
532
|
+
values.each do |(name2, value2)|
|
533
|
+
value = value1 / value2
|
534
|
+
CONVERSION_TABLE[name1][name2] = value.denominator == 1 ? value.to_i : value.to_f
|
535
|
+
end
|
536
|
+
end
|
537
|
+
end
|
458
538
|
|
459
539
|
def conversion_factor(from_unit, to_unit)
|
460
|
-
|
461
|
-
return 1.0 / conversion_factor(to_unit, from_unit) if res.nil?
|
462
|
-
res
|
540
|
+
CONVERSION_TABLE[from_unit][to_unit]
|
463
541
|
end
|
464
542
|
|
465
543
|
def convertable?(units)
|
466
|
-
Array(units).
|
544
|
+
units = Array(units).to_set
|
545
|
+
return true if units.empty?
|
546
|
+
return false unless (mutually_convertible = MUTUALLY_CONVERTIBLE[units.first])
|
547
|
+
units.subset?(mutually_convertible)
|
467
548
|
end
|
468
549
|
|
469
550
|
def sans_common_units(units1, units2)
|
@@ -1,6 +1,9 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
1
2
|
module Sass::Script::Value
|
2
3
|
# A SassScript object representing a CSS string *or* a CSS identifier.
|
3
4
|
class String < Base
|
5
|
+
@@interpolation_deprecation = Sass::Deprecation.new
|
6
|
+
|
4
7
|
# The Ruby value of the string.
|
5
8
|
#
|
6
9
|
# @return [String]
|
@@ -13,37 +16,123 @@ module Sass::Script::Value
|
|
13
16
|
# @return [Symbol] `:string` or `:identifier`
|
14
17
|
attr_reader :type
|
15
18
|
|
19
|
+
def self.value(contents)
|
20
|
+
contents.gsub("\\\n", "").gsub(/\\(?:([0-9a-fA-F]{1,6})\s?|(.))/) do
|
21
|
+
next $2 if $2
|
22
|
+
# Handle unicode escapes as per CSS Syntax Level 3 section 4.3.8.
|
23
|
+
code_point = $1.to_i(16)
|
24
|
+
if code_point == 0 || code_point > 0x10FFFF ||
|
25
|
+
(code_point >= 0xD800 && code_point <= 0xDFFF)
|
26
|
+
'�'
|
27
|
+
else
|
28
|
+
[code_point].pack("U")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns the quoted string representation of `contents`.
|
34
|
+
#
|
35
|
+
# @options opts :quote [String]
|
36
|
+
# The preferred quote style for quoted strings. If `:none`, strings are
|
37
|
+
# always emitted unquoted. If `nil`, quoting is determined automatically.
|
38
|
+
# @options opts :sass [String]
|
39
|
+
# Whether to quote strings for Sass source, as opposed to CSS. Defaults to `false`.
|
40
|
+
def self.quote(contents, opts = {})
|
41
|
+
quote = opts[:quote]
|
42
|
+
|
43
|
+
# Short-circuit if there are no characters that need quoting.
|
44
|
+
unless contents =~ /[\n\\"']|\#\{/
|
45
|
+
quote ||= '"'
|
46
|
+
return "#{quote}#{contents}#{quote}"
|
47
|
+
end
|
48
|
+
|
49
|
+
if quote.nil?
|
50
|
+
if contents.include?('"')
|
51
|
+
if contents.include?("'")
|
52
|
+
quote = '"'
|
53
|
+
else
|
54
|
+
quote = "'"
|
55
|
+
end
|
56
|
+
else
|
57
|
+
quote = '"'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Replace single backslashes with multiples.
|
62
|
+
contents = contents.gsub("\\", "\\\\\\\\")
|
63
|
+
|
64
|
+
# Escape interpolation.
|
65
|
+
contents = contents.gsub('#{', "\\\#{") if opts[:sass]
|
66
|
+
|
67
|
+
if quote == '"'
|
68
|
+
contents = contents.gsub('"', "\\\"")
|
69
|
+
else
|
70
|
+
contents = contents.gsub("'", "\\'")
|
71
|
+
end
|
72
|
+
|
73
|
+
contents = contents.gsub(/\n(?![a-fA-F0-9\s])/, "\\a").gsub("\n", "\\a ")
|
74
|
+
"#{quote}#{contents}#{quote}"
|
75
|
+
end
|
76
|
+
|
16
77
|
# Creates a new string.
|
17
78
|
#
|
18
79
|
# @param value [String] See \{#value}
|
19
80
|
# @param type [Symbol] See \{#type}
|
20
|
-
|
81
|
+
# @param deprecated_interp_equivalent [String?]
|
82
|
+
# If this was created via a potentially-deprecated string interpolation,
|
83
|
+
# this is the replacement expression that should be suggested to the user.
|
84
|
+
def initialize(value, type = :identifier, deprecated_interp_equivalent = nil)
|
21
85
|
super(value)
|
22
86
|
@type = type
|
87
|
+
@deprecated_interp_equivalent = deprecated_interp_equivalent
|
23
88
|
end
|
24
89
|
|
25
90
|
# @see Value#plus
|
26
91
|
def plus(other)
|
27
|
-
|
28
|
-
|
92
|
+
other_value = if other.is_a?(Sass::Script::Value::String)
|
93
|
+
other.value
|
94
|
+
else
|
95
|
+
other.to_s(:quote => :none)
|
96
|
+
end
|
97
|
+
Sass::Script::Value::String.new(value + other_value, type)
|
29
98
|
end
|
30
99
|
|
31
100
|
# @see Value#to_s
|
32
101
|
def to_s(opts = {})
|
33
|
-
if @type == :identifier
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
return "\"#{value.gsub('"', "\\\"")}\"" if opts[:quote] == %q{"}
|
38
|
-
return "'#{value.gsub("'", "\\'")}'" if opts[:quote] == %q{'}
|
39
|
-
return "\"#{value}\"" unless value.include?('"')
|
40
|
-
return "'#{value}'" unless value.include?("'")
|
41
|
-
"\"#{value.gsub('"', "\\\"")}\"" # '
|
102
|
+
return @value.gsub(/\n\s*/, ' ') if opts[:quote] == :none || @type == :identifier
|
103
|
+
String.quote(value, opts)
|
42
104
|
end
|
43
105
|
|
44
106
|
# @see Value#to_sass
|
45
107
|
def to_sass(opts = {})
|
46
|
-
to_s
|
108
|
+
to_s(opts.merge(:sass => true))
|
109
|
+
end
|
110
|
+
|
111
|
+
def separator
|
112
|
+
check_deprecated_interp
|
113
|
+
super
|
114
|
+
end
|
115
|
+
|
116
|
+
def to_a
|
117
|
+
check_deprecated_interp
|
118
|
+
super
|
119
|
+
end
|
120
|
+
|
121
|
+
# Prints a warning if this string was created using potentially-deprecated
|
122
|
+
# interpolation.
|
123
|
+
def check_deprecated_interp
|
124
|
+
return unless @deprecated_interp_equivalent
|
125
|
+
|
126
|
+
@@interpolation_deprecation.warn(source_range.file, source_range.start_pos.line, <<WARNING)
|
127
|
+
\#{} interpolation near operators will be simplified in a future version of Sass.
|
128
|
+
To preserve the current behavior, use quotes:
|
129
|
+
|
130
|
+
#{@deprecated_interp_equivalent}
|
131
|
+
WARNING
|
132
|
+
end
|
133
|
+
|
134
|
+
def inspect
|
135
|
+
String.quote(value)
|
47
136
|
end
|
48
137
|
end
|
49
138
|
end
|
data/lib/sass/script/value.rb
CHANGED
@@ -5,7 +5,6 @@ require 'sass/script/value/string'
|
|
5
5
|
require 'sass/script/value/number'
|
6
6
|
require 'sass/script/value/color'
|
7
7
|
require 'sass/script/value/bool'
|
8
|
-
require 'sass/script/value/deprecated_false'
|
9
8
|
require 'sass/script/value/null'
|
10
9
|
require 'sass/script/value/list'
|
11
10
|
require 'sass/script/value/arg_list'
|
data/lib/sass/script.rb
CHANGED
@@ -16,12 +16,12 @@ module Sass
|
|
16
16
|
# Parses a string of SassScript
|
17
17
|
#
|
18
18
|
# @param value [String] The SassScript
|
19
|
-
# @param line [
|
19
|
+
# @param line [Integer] The number of the line on which the SassScript appeared.
|
20
20
|
# Used for error reporting
|
21
|
-
# @param offset [
|
21
|
+
# @param offset [Integer] The number of characters in on `line` that the SassScript started.
|
22
22
|
# Used for error reporting
|
23
23
|
# @param options [{Symbol => Object}] An options hash;
|
24
|
-
# see {file:SASS_REFERENCE.md#
|
24
|
+
# see {file:SASS_REFERENCE.md#Options the Sass options documentation}
|
25
25
|
# @return [Script::Tree::Node] The root node of the parse tree
|
26
26
|
def self.parse(value, line, offset, options = {})
|
27
27
|
Parser.parse(value, line, offset, options)
|
data/lib/sass/scss/css_parser.rb
CHANGED
@@ -11,9 +11,16 @@ module Sass
|
|
11
11
|
|
12
12
|
def placeholder_selector; nil; end
|
13
13
|
def parent_selector; nil; end
|
14
|
-
def interpolation; nil; end
|
14
|
+
def interpolation(warn_for_color = false); nil; end
|
15
15
|
def use_css_import?; true; end
|
16
16
|
|
17
|
+
def block_contents(node, context)
|
18
|
+
if node.is_a?(Sass::Tree::DirectiveNode) && node.normalized_name == '@keyframes'
|
19
|
+
context = :keyframes
|
20
|
+
end
|
21
|
+
super(node, context)
|
22
|
+
end
|
23
|
+
|
17
24
|
def block_child(context)
|
18
25
|
case context
|
19
26
|
when :ruleset
|
@@ -22,15 +29,28 @@ module Sass
|
|
22
29
|
directive || ruleset
|
23
30
|
when :directive
|
24
31
|
directive || declaration_or_ruleset
|
32
|
+
when :keyframes
|
33
|
+
keyframes_ruleset
|
25
34
|
end
|
26
35
|
end
|
27
36
|
|
28
|
-
def nested_properties!(node
|
37
|
+
def nested_properties!(node)
|
29
38
|
expected('expression (e.g. 1px, bold)')
|
30
39
|
end
|
31
40
|
|
32
|
-
|
33
|
-
|
41
|
+
def ruleset
|
42
|
+
start_pos = source_position
|
43
|
+
return unless (selector = selector_comma_sequence)
|
44
|
+
block(node(Sass::Tree::RuleNode.new(selector, range(start_pos)), start_pos), :ruleset)
|
45
|
+
end
|
46
|
+
|
47
|
+
def keyframes_ruleset
|
48
|
+
start_pos = source_position
|
49
|
+
return unless (selector = keyframes_selector)
|
50
|
+
block(node(Sass::Tree::KeyframeRuleNode.new(selector.strip), start_pos), :ruleset)
|
51
|
+
end
|
52
|
+
|
53
|
+
@sass_script_parser = Sass::Script::CssParser
|
34
54
|
end
|
35
55
|
end
|
36
56
|
end
|