sass 3.4.25 → 3.5.0.pre.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +1 -1
- data/README.md +1 -1
- data/Rakefile +13 -157
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/lib/sass.rb +3 -10
- data/lib/sass/cache_stores/filesystem.rb +1 -1
- data/lib/sass/css.rb +2 -3
- data/lib/sass/engine.rb +46 -32
- data/lib/sass/environment.rb +27 -6
- data/lib/sass/error.rb +5 -5
- data/lib/sass/exec/base.rb +3 -12
- data/lib/sass/features.rb +1 -0
- data/lib/sass/importers/filesystem.rb +2 -2
- data/lib/sass/plugin.rb +1 -1
- data/lib/sass/plugin/compiler.rb +21 -51
- data/lib/sass/plugin/configuration.rb +1 -1
- data/lib/sass/plugin/rack.rb +3 -3
- data/lib/sass/plugin/staleness_checker.rb +3 -3
- data/lib/sass/railtie.rb +1 -1
- data/lib/sass/script.rb +3 -3
- data/lib/sass/script/functions.rb +238 -47
- data/lib/sass/script/lexer.rb +8 -6
- data/lib/sass/script/parser.rb +76 -75
- 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 +2 -10
- data/lib/sass/script/tree/operation.rb +16 -50
- data/lib/sass/script/value.rb +2 -0
- data/lib/sass/script/value/arg_list.rb +1 -1
- data/lib/sass/script/value/base.rb +20 -3
- data/lib/sass/script/value/callable.rb +25 -0
- data/lib/sass/script/value/color.rb +10 -10
- data/lib/sass/script/value/function.rb +19 -0
- data/lib/sass/script/value/helpers.rb +16 -7
- data/lib/sass/script/value/list.rb +33 -12
- data/lib/sass/script/value/map.rb +2 -2
- data/lib/sass/script/value/number.rb +3 -3
- data/lib/sass/script/value/string.rb +12 -5
- data/lib/sass/scss/parser.rb +101 -45
- data/lib/sass/scss/rx.rb +5 -11
- data/lib/sass/scss/static_parser.rb +0 -7
- data/lib/sass/selector.rb +4 -0
- data/lib/sass/selector/abstract_sequence.rb +5 -5
- data/lib/sass/selector/comma_sequence.rb +3 -15
- data/lib/sass/selector/pseudo.rb +4 -0
- data/lib/sass/selector/sequence.rb +30 -3
- data/lib/sass/selector/simple.rb +13 -7
- data/lib/sass/selector/simple_sequence.rb +1 -1
- data/lib/sass/shared.rb +3 -5
- data/lib/sass/source/map.rb +4 -4
- data/lib/sass/source/position.rb +4 -4
- data/lib/sass/stack.rb +21 -1
- data/lib/sass/tree/charset_node.rb +1 -1
- data/lib/sass/tree/comment_node.rb +1 -1
- data/lib/sass/tree/node.rb +3 -3
- data/lib/sass/tree/prop_node.rb +46 -54
- data/lib/sass/tree/rule_node.rb +7 -15
- 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 +1 -10
- data/lib/sass/tree/visitors/deep_copy.rb +2 -2
- data/lib/sass/tree/visitors/perform.rb +23 -12
- data/lib/sass/tree/visitors/set_options.rb +1 -1
- data/lib/sass/tree/visitors/to_css.rb +46 -12
- data/lib/sass/util.rb +16 -321
- data/lib/sass/util/multibyte_string_scanner.rb +127 -131
- data/lib/sass/util/normalized_map.rb +1 -8
- data/lib/sass/version.rb +2 -2
- data/test/sass-spec.yml +1 -1
- data/test/sass/compiler_test.rb +4 -14
- data/test/sass/conversion_test.rb +113 -162
- data/test/sass/css2sass_test.rb +17 -19
- data/test/sass/css_variable_test.rb +176 -70
- data/test/sass/encoding_test.rb +2 -32
- data/test/sass/engine_test.rb +114 -65
- data/test/sass/extend_test.rb +37 -51
- data/test/sass/functions_test.rb +57 -15
- data/test/sass/importer_test.rb +2 -2
- 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 +9 -12
- data/test/sass/script_conversion_test.rb +9 -0
- data/test/sass/script_test.rb +38 -48
- data/test/sass/scss/css_test.rb +5 -19
- data/test/sass/scss/scss_test.rb +58 -39
- data/test/sass/source_map_test.rb +26 -28
- 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/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/util/multibyte_string_scanner_test.rb +139 -149
- data/test/sass/util_test.rb +0 -36
- data/test/test_helper.rb +39 -0
- metadata +30 -57
- data/extra/sass-spec-ref.sh +0 -32
- data/lib/sass/deprecation.rb +0 -55
- 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.rb +0 -54
- 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/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
@@ -144,13 +144,6 @@ MESSAGE
|
|
144
144
|
ns, name = expr!(:qualified_name)
|
145
145
|
res << ns << '|' if ns
|
146
146
|
res << name << tok!(%r{/})
|
147
|
-
|
148
|
-
location = " of #{@filename}" if @filename
|
149
|
-
Sass::Util.sass_warn <<MESSAGE
|
150
|
-
DEPRECATION WARNING on line #{@line}, column #{@offset}#{location}:
|
151
|
-
The reference combinator #{res} is deprecated and will be removed in a future release.
|
152
|
-
MESSAGE
|
153
|
-
|
154
147
|
res
|
155
148
|
end
|
156
149
|
|
data/lib/sass/selector.rb
CHANGED
@@ -8,7 +8,7 @@ module Sass
|
|
8
8
|
class AbstractSequence
|
9
9
|
# The line of the Sass template on which this selector was declared.
|
10
10
|
#
|
11
|
-
# @return [
|
11
|
+
# @return [Fixnum]
|
12
12
|
attr_reader :line
|
13
13
|
|
14
14
|
# The name of the file in which this selector was declared.
|
@@ -19,8 +19,8 @@ module Sass
|
|
19
19
|
# Sets the line of the Sass template on which this selector was declared.
|
20
20
|
# This also sets the line for all child selectors.
|
21
21
|
#
|
22
|
-
# @param line [
|
23
|
-
# @return [
|
22
|
+
# @param line [Fixnum]
|
23
|
+
# @return [Fixnum]
|
24
24
|
def line=(line)
|
25
25
|
members.each {|m| m.line = line}
|
26
26
|
@line = line
|
@@ -42,7 +42,7 @@ module Sass
|
|
42
42
|
# Subclasses should define `#_hash` rather than overriding this method,
|
43
43
|
# which automatically handles memoizing the result.
|
44
44
|
#
|
45
|
-
# @return [
|
45
|
+
# @return [Fixnum]
|
46
46
|
def hash
|
47
47
|
@_hash ||= _hash
|
48
48
|
end
|
@@ -83,7 +83,7 @@ module Sass
|
|
83
83
|
# The base is given by {Sass::Selector::SPECIFICITY_BASE}. This can be a
|
84
84
|
# number or a range representing possible specificities.
|
85
85
|
#
|
86
|
-
# @return [
|
86
|
+
# @return [Fixnum, Range]
|
87
87
|
def specificity
|
88
88
|
_specificity(members)
|
89
89
|
end
|
@@ -2,8 +2,6 @@ module Sass
|
|
2
2
|
module Selector
|
3
3
|
# A comma-separated sequence of selectors.
|
4
4
|
class CommaSequence < AbstractSequence
|
5
|
-
@@compound_extend_deprecation = Sass::Deprecation.new
|
6
|
-
|
7
5
|
# The comma-separated selector sequences
|
8
6
|
# represented by this class.
|
9
7
|
#
|
@@ -98,11 +96,8 @@ module Sass
|
|
98
96
|
# The node that caused this extension.
|
99
97
|
# @param parent_directives [Array<Sass::Tree::DirectiveNode>]
|
100
98
|
# The parent directives containing `extend_node`.
|
101
|
-
# @param allow_compound_target [Boolean]
|
102
|
-
# Whether `extendee` is allowed to contain compound selectors.
|
103
99
|
# @raise [Sass::SyntaxError] if this extension is invalid.
|
104
|
-
def populate_extends(extends, extendee, extend_node = nil, parent_directives = []
|
105
|
-
allow_compound_target = false)
|
100
|
+
def populate_extends(extends, extendee, extend_node = nil, parent_directives = [])
|
106
101
|
extendee.members.each do |seq|
|
107
102
|
if seq.members.size > 1
|
108
103
|
raise Sass::SyntaxError.new("Can't extend #{seq}: can't extend nested selectors")
|
@@ -116,13 +111,6 @@ module Sass
|
|
116
111
|
end
|
117
112
|
|
118
113
|
sel = sseq.members
|
119
|
-
if !allow_compound_target && sel.length > 1
|
120
|
-
@@compound_extend_deprecation.warn(sseq.filename, sseq.line, <<WARNING)
|
121
|
-
Extending a compound selector, #{sseq}, is deprecated and will not be supported in a future release.
|
122
|
-
See https://github.com/sass/sass/issues/1599 for details.
|
123
|
-
WARNING
|
124
|
-
end
|
125
|
-
|
126
114
|
members.each do |member|
|
127
115
|
unless member.members.last.is_a?(Sass::Selector::SimpleSequence)
|
128
116
|
raise Sass::SyntaxError.new("#{member} can't extend: invalid selector")
|
@@ -158,8 +146,8 @@ WARNING
|
|
158
146
|
Sass::Script::Value::List.new(seq.members.map do |component|
|
159
147
|
next if component == "\n"
|
160
148
|
Sass::Script::Value::String.new(component.to_s)
|
161
|
-
end.compact, :space)
|
162
|
-
end, :comma)
|
149
|
+
end.compact, separator: :space)
|
150
|
+
end, separator: :comma)
|
163
151
|
end
|
164
152
|
|
165
153
|
# Returns a string representation of the sequence.
|
data/lib/sass/selector/pseudo.rb
CHANGED
@@ -6,8 +6,8 @@ module Sass
|
|
6
6
|
# Sets the line of the Sass template on which this selector was declared.
|
7
7
|
# This also sets the line for all child selectors.
|
8
8
|
#
|
9
|
-
# @param line [
|
10
|
-
# @return [
|
9
|
+
# @param line [Fixnum]
|
10
|
+
# @return [Fixnum]
|
11
11
|
def line=(line)
|
12
12
|
members.each {|m| m.line = line if m.is_a?(SimpleSequence)}
|
13
13
|
@line = line
|
@@ -283,6 +283,9 @@ module Sass
|
|
283
283
|
next unless s1.first.is_a?(SimpleSequence) && s2.first.is_a?(SimpleSequence)
|
284
284
|
next s2 if parent_superselector?(s1, s2)
|
285
285
|
next s1 if parent_superselector?(s2, s1)
|
286
|
+
next unless must_unify?(s1, s2)
|
287
|
+
next unless (unified = Sequence.new(s1).unify(Sequence.new(s2)))
|
288
|
+
unified.members.first.members if unified.members.length == 1
|
286
289
|
end
|
287
290
|
|
288
291
|
diff = [[init]]
|
@@ -494,7 +497,7 @@ module Sass
|
|
494
497
|
return if seq1.size > seq2.size
|
495
498
|
return seq1.first.superselector?(seq2.last, seq2[0...-1]) if seq1.size == 1
|
496
499
|
|
497
|
-
_, si =
|
500
|
+
_, si = seq2.each_with_index.find do |e, i|
|
498
501
|
return if i == seq2.size - 1
|
499
502
|
next if e.is_a?(String)
|
500
503
|
seq1.first.superselector?(e, seq2[0...i])
|
@@ -537,6 +540,30 @@ module Sass
|
|
537
540
|
_superselector?(seq1 + [base], seq2 + [base])
|
538
541
|
end
|
539
542
|
|
543
|
+
# Returns whether two selectors must be unified to produce a valid
|
544
|
+
# combined selector. This is true when both selectors contain the same
|
545
|
+
# unique simple selector such as an id.
|
546
|
+
#
|
547
|
+
# @param seq1 [Array<SimpleSequence or String>]
|
548
|
+
# @param seq2 [Array<SimpleSequence or String>]
|
549
|
+
# @return [Boolean]
|
550
|
+
def must_unify?(seq1, seq2)
|
551
|
+
unique_selectors = seq1.map do |sseq|
|
552
|
+
next [] if sseq.is_a?(String)
|
553
|
+
sseq.members.select {|sel| sel.unique?}
|
554
|
+
end.flatten.to_set
|
555
|
+
|
556
|
+
return false if unique_selectors.empty?
|
557
|
+
|
558
|
+
seq2.any? do |sseq|
|
559
|
+
next false if sseq.is_a?(String)
|
560
|
+
sseq.members.any? do |sel|
|
561
|
+
next unless sel.unique?
|
562
|
+
unique_selectors.include?(sel)
|
563
|
+
end
|
564
|
+
end
|
565
|
+
end
|
566
|
+
|
540
567
|
# Removes redundant selectors from between multiple lists of
|
541
568
|
# selectors. This takes a list of lists of selector sequences;
|
542
569
|
# each individual list is assumed to have no redundancy within
|
data/lib/sass/selector/simple.rb
CHANGED
@@ -5,7 +5,7 @@ module Sass
|
|
5
5
|
class Simple
|
6
6
|
# The line of the Sass template on which this selector was declared.
|
7
7
|
#
|
8
|
-
# @return [
|
8
|
+
# @return [Fixnum]
|
9
9
|
attr_accessor :line
|
10
10
|
|
11
11
|
# The name of the file in which this selector was declared,
|
@@ -14,6 +14,14 @@ module Sass
|
|
14
14
|
# @return [String, nil]
|
15
15
|
attr_accessor :filename
|
16
16
|
|
17
|
+
# Whether only one instance of this simple selector is allowed in a given
|
18
|
+
# complex selector.
|
19
|
+
#
|
20
|
+
# @return [Boolean]
|
21
|
+
def unique?
|
22
|
+
false
|
23
|
+
end
|
24
|
+
|
17
25
|
# @see #to_s
|
18
26
|
#
|
19
27
|
# @return [String]
|
@@ -36,7 +44,7 @@ module Sass
|
|
36
44
|
# so if that contains information irrelevant to the identity of the selector,
|
37
45
|
# this should be overridden.
|
38
46
|
#
|
39
|
-
# @return [
|
47
|
+
# @return [Fixnum]
|
40
48
|
def hash
|
41
49
|
@_hash ||= equality_key.hash
|
42
50
|
end
|
@@ -72,11 +80,9 @@ module Sass
|
|
72
80
|
# by the time extension and unification happen,
|
73
81
|
# this exception will only ever be raised as a result of programmer error
|
74
82
|
def unify(sels)
|
75
|
-
return sels.first.unify([self]) if sels.length == 1 && sels.first.is_a?(Universal)
|
76
83
|
return sels if sels.any? {|sel2| eql?(sel2)}
|
77
|
-
sels_with_ix = Sass::Util.enum_with_index(sels)
|
78
84
|
if !is_a?(Pseudo) || (sels.last.is_a?(Pseudo) && sels.last.type == :element)
|
79
|
-
_, i =
|
85
|
+
_, i = sels.each_with_index.find {|sel, _| sel.is_a?(Pseudo)}
|
80
86
|
end
|
81
87
|
return sels + [self] unless i
|
82
88
|
sels[0...i] + [self] + sels[i..-1]
|
@@ -107,10 +113,10 @@ module Sass
|
|
107
113
|
# could be found at all.
|
108
114
|
# If the second value is `false`, the first should be ignored.
|
109
115
|
def unify_namespaces(ns1, ns2)
|
116
|
+
return nil, false unless ns1 == ns2 || ns1.nil? || ns1 == '*' || ns2.nil? || ns2 == '*'
|
110
117
|
return ns2, true if ns1 == '*'
|
111
118
|
return ns1, true if ns2 == '*'
|
112
|
-
|
113
|
-
[ns1, true]
|
119
|
+
[ns1 || ns2, true]
|
114
120
|
end
|
115
121
|
end
|
116
122
|
end
|
@@ -184,7 +184,7 @@ module Sass
|
|
184
184
|
result
|
185
185
|
end.flatten
|
186
186
|
|
187
|
-
groups =
|
187
|
+
groups = extends[members.to_set].group_by {|ex| ex.extender}.to_a
|
188
188
|
groups.map! do |seq, group|
|
189
189
|
sels = group.map {|e| e.target}.flatten
|
190
190
|
# If A {@extend B} and C {...},
|
data/lib/sass/shared.rb
CHANGED
@@ -27,11 +27,9 @@ module Sass
|
|
27
27
|
# from to
|
28
28
|
#
|
29
29
|
# @param scanner [StringScanner] The string scanner to move
|
30
|
-
# @param start [
|
31
|
-
#
|
32
|
-
# @param
|
33
|
-
# A `Fixnum` in 1.8, a `String` in 1.9
|
34
|
-
# @param count [Integer] The number of opening characters matched
|
30
|
+
# @param start [String] The character opening the balanced pair.
|
31
|
+
# @param finish [String] The character closing the balanced pair.
|
32
|
+
# @param count [Fixnum] The number of opening characters matched
|
35
33
|
# before calling this method
|
36
34
|
# @return [(String, String)] The string matched within the balanced pair
|
37
35
|
# and the rest of the string.
|
data/lib/sass/source/map.rb
CHANGED
@@ -37,7 +37,7 @@ module Sass::Source
|
|
37
37
|
|
38
38
|
# Shifts all output source ranges forward one or more lines.
|
39
39
|
#
|
40
|
-
# @param delta [
|
40
|
+
# @param delta [Fixnum] The number of lines to shift the ranges forward.
|
41
41
|
def shift_output_lines(delta)
|
42
42
|
return if delta == 0
|
43
43
|
@data.each do |m|
|
@@ -49,7 +49,7 @@ module Sass::Source
|
|
49
49
|
# Shifts any output source ranges that lie on the first line forward one or
|
50
50
|
# more characters on that line.
|
51
51
|
#
|
52
|
-
# @param delta [
|
52
|
+
# @param delta [Fixnum] The number of characters to shift the ranges
|
53
53
|
# forward.
|
54
54
|
def shift_output_offsets(delta)
|
55
55
|
return if delta == 0
|
@@ -93,8 +93,8 @@ module Sass::Source
|
|
93
93
|
raise ArgumentError.new("Sass::Source::Map#to_json requires either " \
|
94
94
|
"the :css_uri option or both the :css_path and :soucemap_path options.")
|
95
95
|
end
|
96
|
-
css_path &&= Sass::Util.pathname(
|
97
|
-
sourcemap_path &&= Sass::Util.pathname(
|
96
|
+
css_path &&= Sass::Util.pathname(File.absolute_path(css_path))
|
97
|
+
sourcemap_path &&= Sass::Util.pathname(File.absolute_path(sourcemap_path))
|
98
98
|
css_uri ||= Sass::Util.file_uri_from_path(
|
99
99
|
Sass::Util.relative_path_from(css_path, sourcemap_path.dirname))
|
100
100
|
|
data/lib/sass/source/position.rb
CHANGED
@@ -2,17 +2,17 @@ module Sass::Source
|
|
2
2
|
class Position
|
3
3
|
# The one-based line of the document associated with the position.
|
4
4
|
#
|
5
|
-
# @return [
|
5
|
+
# @return [Fixnum]
|
6
6
|
attr_accessor :line
|
7
7
|
|
8
8
|
# The one-based offset in the line of the document associated with the
|
9
9
|
# position.
|
10
10
|
#
|
11
|
-
# @return [
|
11
|
+
# @return [Fixnum]
|
12
12
|
attr_accessor :offset
|
13
13
|
|
14
|
-
# @param line [
|
15
|
-
# @param offset [
|
14
|
+
# @param line [Fixnum] The source line
|
15
|
+
# @param offset [Fixnum] The source offset
|
16
16
|
def initialize(line, offset)
|
17
17
|
@line = line
|
18
18
|
@offset = offset
|
data/lib/sass/stack.rb
CHANGED
@@ -98,8 +98,28 @@ module Sass
|
|
98
98
|
with_frame(filename, line, :mixin, name) {yield}
|
99
99
|
end
|
100
100
|
|
101
|
+
# Pushes a function frame onto the stack.
|
102
|
+
#
|
103
|
+
# @param filename [String] See \{Frame#filename}.
|
104
|
+
# @param line [String] See \{Frame#line}.
|
105
|
+
# @param name [String] See \{Frame#name}.
|
106
|
+
# @yield [] A block in which the new frame is on the stack.
|
107
|
+
def with_function(filename, line, name)
|
108
|
+
with_frame(filename, line, :function, name) {yield}
|
109
|
+
end
|
110
|
+
|
111
|
+
# Pushes a function frame onto the stack.
|
112
|
+
#
|
113
|
+
# @param filename [String] See \{Frame#filename}.
|
114
|
+
# @param line [String] See \{Frame#line}.
|
115
|
+
# @param name [String] See \{Frame#name}.
|
116
|
+
# @yield [] A block in which the new frame is on the stack.
|
117
|
+
def with_directive(filename, line, name)
|
118
|
+
with_frame(filename, line, :directive, name) {yield}
|
119
|
+
end
|
120
|
+
|
101
121
|
def to_s
|
102
|
-
|
122
|
+
(frames.reverse + [nil]).each_cons(2).each_with_index.
|
103
123
|
map do |(frame, caller), i|
|
104
124
|
"#{i == 0 ? 'on' : 'from'} line #{frame.line}" +
|
105
125
|
" of #{frame.filename || 'an unknown file'}" +
|
data/lib/sass/tree/node.rb
CHANGED
@@ -69,7 +69,7 @@ module Sass
|
|
69
69
|
|
70
70
|
# The line of the document on which this node appeared.
|
71
71
|
#
|
72
|
-
# @return [
|
72
|
+
# @return [Fixnum]
|
73
73
|
attr_accessor :line
|
74
74
|
|
75
75
|
# The source range in the document on which this node appeared.
|
@@ -83,7 +83,7 @@ module Sass
|
|
83
83
|
attr_writer :filename
|
84
84
|
|
85
85
|
# The options hash for the node.
|
86
|
-
# See {file:SASS_REFERENCE.md#
|
86
|
+
# See {file:SASS_REFERENCE.md#options the Sass options documentation}.
|
87
87
|
#
|
88
88
|
# @return [{Symbol => Object}]
|
89
89
|
attr_reader :options
|
@@ -151,7 +151,7 @@ module Sass
|
|
151
151
|
# @return [Boolean]
|
152
152
|
def invisible?; false; end
|
153
153
|
|
154
|
-
# The output style. See {file:SASS_REFERENCE.md#
|
154
|
+
# The output style. See {file:SASS_REFERENCE.md#options the Sass options documentation}.
|
155
155
|
#
|
156
156
|
# @return [Symbol]
|
157
157
|
def style
|
data/lib/sass/tree/prop_node.rb
CHANGED
@@ -20,7 +20,11 @@ module Sass::Tree
|
|
20
20
|
|
21
21
|
# The value of the property.
|
22
22
|
#
|
23
|
-
#
|
23
|
+
# For most properties, this will just contain a single Node. However, for
|
24
|
+
# CSS variables, it will contain multiple strings and nodes representing
|
25
|
+
# interpolation. Any adjacent strings will be merged together.
|
26
|
+
#
|
27
|
+
# @return [Array<String, Sass::Script::Tree::Node>]
|
24
28
|
attr_accessor :value
|
25
29
|
|
26
30
|
# The value of the property
|
@@ -39,7 +43,7 @@ module Sass::Tree
|
|
39
43
|
# * This is a child property of another property
|
40
44
|
# * The parent property has a value, and thus will be rendered
|
41
45
|
#
|
42
|
-
# @return [
|
46
|
+
# @return [Fixnum]
|
43
47
|
attr_accessor :tabs
|
44
48
|
|
45
49
|
# The source range in which the property name appears.
|
@@ -52,14 +56,22 @@ module Sass::Tree
|
|
52
56
|
# @return [Sass::Source::Range]
|
53
57
|
attr_accessor :value_source_range
|
54
58
|
|
59
|
+
# Whether this represents a CSS custom property.
|
60
|
+
#
|
61
|
+
# @return [Boolean]
|
62
|
+
def custom_property?
|
63
|
+
name.first.is_a?(String) && name.first.start_with?("--")
|
64
|
+
end
|
65
|
+
|
55
66
|
# @param name [Array<String, Sass::Script::Tree::Node>] See \{#name}
|
56
|
-
# @param value [Sass::Script::Tree::Node] See \{#value}
|
67
|
+
# @param value [Array<String, Sass::Script::Tree::Node>] See \{#value}
|
57
68
|
# @param prop_syntax [Symbol] `:new` if this property uses `a: b`-style syntax,
|
58
69
|
# `:old` if it uses `:a b`-style syntax
|
59
70
|
def initialize(name, value, prop_syntax)
|
60
71
|
@name = Sass::Util.strip_string_array(
|
61
72
|
Sass::Util.merge_adjacent_strings(name))
|
62
|
-
@value = value
|
73
|
+
@value = Sass::Util.merge_adjacent_strings(value)
|
74
|
+
@value = Sass::Util.strip_string_array(@value) unless custom_property?
|
63
75
|
@tabs = 0
|
64
76
|
@prop_syntax = prop_syntax
|
65
77
|
super()
|
@@ -81,9 +93,10 @@ module Sass::Tree
|
|
81
93
|
# @return [String] The message
|
82
94
|
def pseudo_class_selector_message
|
83
95
|
if @prop_syntax == :new ||
|
84
|
-
|
85
|
-
!value.
|
86
|
-
!value.
|
96
|
+
custom_property? ||
|
97
|
+
!value.first.is_a?(Sass::Script::Tree::Literal) ||
|
98
|
+
!value.first.value.is_a?(Sass::Script::Value::String) ||
|
99
|
+
!value.first.value.value.empty?
|
87
100
|
return ""
|
88
101
|
end
|
89
102
|
|
@@ -98,73 +111,52 @@ module Sass::Tree
|
|
98
111
|
# @param fmt [Symbol] `:scss` or `:sass`.
|
99
112
|
def declaration(opts = {:old => @prop_syntax == :old}, fmt = :sass)
|
100
113
|
name = self.name.map {|n| n.is_a?(String) ? n : n.to_sass(opts)}.join
|
114
|
+
value = self.value.map {|n| n.is_a?(String) ? n : n.to_sass(opts)}.join
|
115
|
+
value = "(#{value})" if value_needs_parens?
|
116
|
+
|
101
117
|
if name[0] == ?:
|
102
|
-
raise Sass::SyntaxError.new("The \"#{name}: #{
|
118
|
+
raise Sass::SyntaxError.new("The \"#{name}: #{value}\"" +
|
103
119
|
" hack is not allowed in the Sass indented syntax")
|
104
120
|
end
|
105
121
|
|
122
|
+
# The indented syntax doesn't support newlines in custom property values,
|
123
|
+
# but we can losslessly convert them to spaces instead.
|
124
|
+
value = value.tr("\n", " ") if fmt == :sass
|
125
|
+
|
106
126
|
old = opts[:old] && fmt == :sass
|
107
|
-
|
108
|
-
mid = old ? '' : ':'
|
109
|
-
"#{initial}#{name}#{mid} #{self.class.val_to_sass(value, opts)}".rstrip
|
127
|
+
"#{old ? ':' : ''}#{name}#{old ? '' : ':'}#{custom_property? ? '' : ' '}#{value}".rstrip
|
110
128
|
end
|
111
129
|
|
112
130
|
# A property node is invisible if its value is empty.
|
113
131
|
#
|
114
132
|
# @return [Boolean]
|
115
133
|
def invisible?
|
116
|
-
resolved_value.empty?
|
134
|
+
!custom_property? && resolved_value.empty?
|
117
135
|
end
|
118
136
|
|
119
137
|
private
|
120
138
|
|
139
|
+
# Returns whether \{#value} neesd parentheses in order to be parsed
|
140
|
+
# properly as division.
|
141
|
+
def value_needs_parens?
|
142
|
+
return false if custom_property?
|
143
|
+
|
144
|
+
root = value.first
|
145
|
+
root.is_a?(Sass::Script::Tree::Operation) &&
|
146
|
+
root.operator == :div &&
|
147
|
+
root.operand1.is_a?(Sass::Script::Tree::Literal) &&
|
148
|
+
root.operand1.value.is_a?(Sass::Script::Value::Number) &&
|
149
|
+
root.operand1.value.original.nil? &&
|
150
|
+
root.operand2.is_a?(Sass::Script::Tree::Literal) &&
|
151
|
+
root.operand2.value.is_a?(Sass::Script::Value::Number) &&
|
152
|
+
root.operand2.value.original.nil?
|
153
|
+
end
|
154
|
+
|
121
155
|
def check!
|
122
156
|
return unless @options[:property_syntax] && @options[:property_syntax] != @prop_syntax
|
123
157
|
raise Sass::SyntaxError.new(
|
124
158
|
"Illegal property syntax: can't use #{@prop_syntax} syntax when " +
|
125
159
|
":property_syntax => #{@options[:property_syntax].inspect} is set.")
|
126
160
|
end
|
127
|
-
|
128
|
-
class << self
|
129
|
-
# @private
|
130
|
-
def val_to_sass(value, opts)
|
131
|
-
val_to_sass_comma(value, opts).to_sass(opts)
|
132
|
-
end
|
133
|
-
|
134
|
-
private
|
135
|
-
|
136
|
-
def val_to_sass_comma(node, opts)
|
137
|
-
return node unless node.is_a?(Sass::Script::Tree::Operation)
|
138
|
-
return val_to_sass_concat(node, opts) unless node.operator == :comma
|
139
|
-
|
140
|
-
Sass::Script::Tree::Operation.new(
|
141
|
-
val_to_sass_concat(node.operand1, opts),
|
142
|
-
val_to_sass_comma(node.operand2, opts),
|
143
|
-
node.operator)
|
144
|
-
end
|
145
|
-
|
146
|
-
def val_to_sass_concat(node, opts)
|
147
|
-
return node unless node.is_a?(Sass::Script::Tree::Operation)
|
148
|
-
return val_to_sass_div(node, opts) unless node.operator == :space
|
149
|
-
|
150
|
-
Sass::Script::Tree::Operation.new(
|
151
|
-
val_to_sass_div(node.operand1, opts),
|
152
|
-
val_to_sass_concat(node.operand2, opts),
|
153
|
-
node.operator)
|
154
|
-
end
|
155
|
-
|
156
|
-
def val_to_sass_div(node, opts)
|
157
|
-
unless node.is_a?(Sass::Script::Tree::Operation) && node.operator == :div &&
|
158
|
-
node.operand1.is_a?(Sass::Script::Tree::Literal) &&
|
159
|
-
node.operand1.value.is_a?(Sass::Script::Value::Number) &&
|
160
|
-
node.operand2.is_a?(Sass::Script::Tree::Literal) &&
|
161
|
-
node.operand2.value.is_a?(Sass::Script::Value::Number) &&
|
162
|
-
(!node.operand1.value.original || !node.operand2.value.original)
|
163
|
-
return node
|
164
|
-
end
|
165
|
-
|
166
|
-
Sass::Script::Value::String.new("(#{node.to_sass(opts)})")
|
167
|
-
end
|
168
|
-
end
|
169
161
|
end
|
170
162
|
end
|