sass 3.2.19 → 3.3.0.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CONTRIBUTING +1 -1
- data/MIT-LICENSE +2 -2
- data/README.md +13 -14
- data/REVISION +1 -1
- data/Rakefile +4 -6
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/bin/sass +1 -6
- data/bin/sass-convert +1 -6
- data/bin/scss +1 -6
- data/lib/sass/cache_stores/base.rb +0 -2
- data/lib/sass/cache_stores/chain.rb +1 -1
- data/lib/sass/cache_stores/filesystem.rb +3 -6
- data/lib/sass/callbacks.rb +1 -1
- data/lib/sass/css.rb +1 -1
- data/lib/sass/engine.rb +4 -11
- data/lib/sass/error.rb +2 -2
- data/lib/sass/exec.rb +10 -40
- data/lib/sass/importers/filesystem.rb +15 -52
- data/lib/sass/logger/log_level.rb +3 -3
- data/lib/sass/media.rb +4 -1
- data/lib/sass/plugin.rb +1 -2
- data/lib/sass/plugin/compiler.rb +18 -40
- data/lib/sass/plugin/staleness_checker.rb +5 -21
- data/lib/sass/railtie.rb +0 -1
- data/lib/sass/script/funcall.rb +8 -62
- data/lib/sass/script/functions.rb +457 -557
- data/lib/sass/script/lexer.rb +30 -25
- data/lib/sass/script/list.rb +1 -2
- data/lib/sass/script/literal.rb +18 -0
- data/lib/sass/script/null.rb +1 -4
- data/lib/sass/script/operation.rb +1 -0
- data/lib/sass/script/parser.rb +35 -42
- data/lib/sass/script/string.rb +1 -1
- data/lib/sass/script/unary_operation.rb +3 -8
- data/lib/sass/scss/parser.rb +14 -33
- data/lib/sass/scss/rx.rb +10 -3
- data/lib/sass/selector.rb +16 -19
- data/lib/sass/selector/sequence.rb +7 -16
- data/lib/sass/selector/simple.rb +1 -1
- data/lib/sass/selector/simple_sequence.rb +15 -25
- data/lib/sass/tree/comment_node.rb +2 -2
- data/lib/sass/tree/import_node.rb +2 -9
- data/lib/sass/tree/visitors/check_nesting.rb +2 -3
- data/lib/sass/tree/visitors/convert.rb +4 -9
- data/lib/sass/tree/visitors/cssize.rb +15 -36
- data/lib/sass/tree/visitors/perform.rb +20 -23
- data/lib/sass/tree/visitors/set_options.rb +0 -8
- data/lib/sass/tree/visitors/to_css.rb +1 -0
- data/lib/sass/util.rb +2 -120
- data/lib/sass/util/multibyte_string_scanner.rb +8 -29
- data/test/sass/conversion_test.rb +8 -33
- data/test/sass/css2sass_test.rb +0 -19
- data/test/sass/engine_test.rb +17 -129
- data/test/sass/extend_test.rb +24 -169
- data/test/sass/functions_test.rb +73 -93
- data/test/sass/plugin_test.rb +11 -72
- data/test/sass/script_conversion_test.rb +0 -14
- data/test/sass/script_test.rb +1 -40
- data/test/sass/scss/css_test.rb +3 -44
- data/test/sass/scss/scss_test.rb +3 -134
- data/test/sass/util_test.rb +0 -93
- data/vendor/listen/CHANGELOG.md +2 -83
- data/vendor/listen/Gemfile +1 -8
- data/vendor/listen/Guardfile +1 -1
- data/vendor/listen/LICENSE +1 -1
- data/vendor/listen/README.md +5 -8
- data/vendor/listen/lib/listen.rb +5 -7
- data/vendor/listen/lib/listen/adapter.rb +29 -76
- data/vendor/listen/lib/listen/adapters/darwin.rb +10 -11
- data/vendor/listen/lib/listen/adapters/linux.rb +30 -33
- data/vendor/listen/lib/listen/adapters/polling.rb +1 -2
- data/vendor/listen/lib/listen/adapters/windows.rb +21 -27
- data/vendor/listen/lib/listen/directory_record.rb +10 -63
- data/vendor/listen/lib/listen/listener.rb +0 -22
- data/vendor/listen/lib/listen/multi_listener.rb +0 -22
- data/vendor/listen/lib/listen/version.rb +1 -1
- data/vendor/listen/listen.gemspec +4 -0
- data/vendor/listen/spec/listen/adapter_spec.rb +4 -45
- data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -6
- data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -6
- data/vendor/listen/spec/listen/adapters/windows_spec.rb +1 -7
- data/vendor/listen/spec/listen/directory_record_spec.rb +4 -91
- data/vendor/listen/spec/listen/listener_spec.rb +0 -14
- data/vendor/listen/spec/listen/multi_listener_spec.rb +1 -19
- data/vendor/listen/spec/spec_helper.rb +3 -6
- data/vendor/listen/spec/support/adapter_helper.rb +212 -125
- data/vendor/listen/spec/support/listeners_helper.rb +1 -13
- data/vendor/listen/spec/support/platform_helper.rb +0 -4
- metadata +113 -105
- checksums.yaml +0 -7
- data/lib/sass/util/test.rb +0 -10
- data/test/sass/exec_test.rb +0 -86
- data/test/sass/results/cached_import_option.css +0 -3
- data/test/sass/templates/_cached_import_option_partial.scss +0 -1
- data/test/sass/templates/_same_name_different_partiality.scss +0 -1
- data/test/sass/templates/bork5.sass +0 -3
- data/test/sass/templates/cached_import_option.scss +0 -3
- data/test/sass/templates/same_name_different_ext.sass +0 -2
- data/test/sass/templates/same_name_different_ext.scss +0 -1
- data/test/sass/templates/same_name_different_partiality.scss +0 -1
- data/test/sass/templates/subdir/import_up1.scss +0 -1
- data/test/sass/templates/subdir/import_up2.scss +0 -1
- data/vendor/listen/CONTRIBUTING.md +0 -38
- data/vendor/listen/lib/listen/adapters/bsd.rb +0 -112
- data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
- data/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
- data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
data/lib/sass/scss/rx.rb
CHANGED
@@ -124,9 +124,16 @@ module Sass
|
|
124
124
|
STRING1_NOINTERP = /\"((?:[^\n\r\f\\"#]|#(?!\{)|\\#{NL}|#{ESCAPE})*)\"/
|
125
125
|
STRING2_NOINTERP = /\'((?:[^\n\r\f\\'#]|#(?!\{)|\\#{NL}|#{ESCAPE})*)\'/
|
126
126
|
STRING_NOINTERP = /#{STRING1_NOINTERP}|#{STRING2_NOINTERP}/
|
127
|
-
|
128
|
-
|
129
|
-
|
127
|
+
# Can't use IDENT here, because it seems to take exponential time on 1.8.
|
128
|
+
# We could use it for 1.9 only, but I don't want to introduce a cross-version
|
129
|
+
# behavior difference.
|
130
|
+
# In any case, almost all CSS idents will be matched by this.
|
131
|
+
#
|
132
|
+
# We explicitly avoid parsing newlines or values/selectors longer than
|
133
|
+
# about 50 characters. This mitigates the problem of exponential parsing
|
134
|
+
# time when a value has a long string of valid, parsable content followed
|
135
|
+
# by something invalid.
|
136
|
+
STATIC_VALUE = /(-?#{NMSTART}|#{STRING_NOINTERP}|[ \t](?!%)|#[a-f0-9]|[,%]|#{NUM}|\!important){1,50}([;}])/i
|
130
137
|
STATIC_SELECTOR = /(#{NMCHAR}|[ \t]|[,>+*]|[:#.]#{NMSTART}){0,50}([{])/i
|
131
138
|
end
|
132
139
|
end
|
data/lib/sass/selector.rb
CHANGED
@@ -120,7 +120,7 @@ module Sass
|
|
120
120
|
|
121
121
|
# @see AbstractSequence#specificity
|
122
122
|
def specificity
|
123
|
-
|
123
|
+
0
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
@@ -346,19 +346,19 @@ module Sass
|
|
346
346
|
# A pseudoclass (e.g. `:visited`) or pseudoelement (e.g. `::first-line`) selector.
|
347
347
|
# It can have arguments (e.g. `:nth-child(2n+1)`).
|
348
348
|
class Pseudo < Simple
|
349
|
-
#
|
350
|
-
#
|
351
|
-
#
|
349
|
+
# The type of the selector.
|
350
|
+
# `:class` if this is a pseudoclass selector,
|
351
|
+
# `:element` if it's a pseudoelement.
|
352
352
|
#
|
353
|
-
# @return [
|
354
|
-
|
353
|
+
# @return [Symbol]
|
354
|
+
attr_reader :type
|
355
355
|
|
356
|
-
#
|
357
|
-
#
|
358
|
-
#
|
356
|
+
# Some psuedo-class-syntax selectors (`:after` and `:before)
|
357
|
+
# are actually considered pseudo-elements
|
358
|
+
# and must be at the end of the selector to function properly.
|
359
359
|
#
|
360
|
-
# @return [
|
361
|
-
|
360
|
+
# @return [Array<String>]
|
361
|
+
FINAL_SELECTORS = %w[after before]
|
362
362
|
|
363
363
|
# The name of the selector.
|
364
364
|
#
|
@@ -380,22 +380,18 @@ module Sass
|
|
380
380
|
# @param arg [nil, Array<String, Sass::Script::Node>] The argument to the selector,
|
381
381
|
# or nil if no argument was given
|
382
382
|
def initialize(type, name, arg)
|
383
|
-
@
|
383
|
+
@type = type
|
384
384
|
@name = name
|
385
385
|
@arg = arg
|
386
386
|
end
|
387
387
|
|
388
|
-
|
389
|
-
|
390
|
-
#
|
391
|
-
# @return [Symbol]
|
392
|
-
def type
|
393
|
-
ACTUALLY_ELEMENTS.include?(name.first) ? :element : syntactic_type
|
388
|
+
def final?
|
389
|
+
type == :class && FINAL_SELECTORS.include?(name.first)
|
394
390
|
end
|
395
391
|
|
396
392
|
# @see Selector#to_a
|
397
393
|
def to_a
|
398
|
-
res = [
|
394
|
+
res = [@type == :class ? ":" : "::"] + @name
|
399
395
|
(res << "(").concat(Sass::Util.strip_string_array(@arg)) << ")" if @arg
|
400
396
|
res
|
401
397
|
end
|
@@ -409,6 +405,7 @@ module Sass
|
|
409
405
|
sel.is_a?(Pseudo) && sel.type == :element &&
|
410
406
|
(sel.name != self.name || sel.arg != self.arg)
|
411
407
|
end
|
408
|
+
return sels + [self] if final?
|
412
409
|
super
|
413
410
|
end
|
414
411
|
|
@@ -255,7 +255,7 @@ module Sass
|
|
255
255
|
# is a supersequence of the other, use that, otherwise give up.
|
256
256
|
lcs = Sass::Util.lcs(ops1, ops2)
|
257
257
|
return unless lcs == ops1 || lcs == ops2
|
258
|
-
res.unshift
|
258
|
+
res.unshift *(ops1.size > ops2.size ? ops1 : ops2).reverse
|
259
259
|
return res
|
260
260
|
end
|
261
261
|
|
@@ -437,32 +437,23 @@ module Sass
|
|
437
437
|
# @param seqses [Array<Array<Array<SimpleSequence or String>>>]
|
438
438
|
# @return [Array<Array<Array<SimpleSequence or String>>>]
|
439
439
|
def trim(seqses)
|
440
|
-
# Avoid truly horrific quadratic behavior. TODO: I think there
|
441
|
-
# may be a way to get perfect trimming without going quadratic.
|
442
|
-
return seqses if seqses.size > 100
|
443
|
-
|
444
|
-
# Keep the results in a separate array so we can be sure we aren't
|
445
|
-
# comparing against an already-trimmed selector. This ensures that two
|
446
|
-
# identical selectors don't mutually trim one another.
|
447
|
-
result = seqses.dup
|
448
|
-
|
449
440
|
# This is n^2 on the sequences, but only comparing between
|
450
441
|
# separate sequences should limit the quadratic behavior.
|
451
|
-
seqses.
|
452
|
-
|
453
|
-
|
454
|
-
|
442
|
+
seqses.map do |seqs1|
|
443
|
+
seqs1.reject do |seq1|
|
444
|
+
min_spec = 0
|
445
|
+
_sources(seq1).map {|seq| min_spec += seq.specificity}
|
446
|
+
seqses.any? do |seqs2|
|
455
447
|
next if seqs1.equal?(seqs2)
|
456
448
|
# Second Law of Extend: the specificity of a generated selector
|
457
449
|
# should never be less than the specificity of the extending
|
458
450
|
# selector.
|
459
451
|
#
|
460
452
|
# See https://github.com/nex3/sass/issues/324.
|
461
|
-
seqs2.any? {|seq2| _specificity(seq2) >=
|
453
|
+
seqs2.any? {|seq2| _specificity(seq2) >= min_spec && _superselector?(seq2, seq1)}
|
462
454
|
end
|
463
455
|
end
|
464
456
|
end
|
465
|
-
result
|
466
457
|
end
|
467
458
|
|
468
459
|
def _hash
|
data/lib/sass/selector/simple.rb
CHANGED
@@ -85,7 +85,7 @@ module Sass
|
|
85
85
|
sels_with_ix = Sass::Util.enum_with_index(sels)
|
86
86
|
_, i =
|
87
87
|
if self.is_a?(Pseudo) || self.is_a?(SelectorPseudoClass)
|
88
|
-
sels_with_ix.find {|sel, _| sel.is_a?(Pseudo) && (sels.last.type == :element)}
|
88
|
+
sels_with_ix.find {|sel, _| sel.is_a?(Pseudo) && (sels.last.final? || sels.last.type == :element)}
|
89
89
|
else
|
90
90
|
sels_with_ix.find {|sel, _| sel.is_a?(Pseudo) || sel.is_a?(SelectorPseudoClass)}
|
91
91
|
end
|
@@ -37,16 +37,11 @@ module Sass
|
|
37
37
|
@base ||= (members.first if members.first.is_a?(Element) || members.first.is_a?(Universal))
|
38
38
|
end
|
39
39
|
|
40
|
-
|
41
|
-
@pseudo_elements ||= (members - [base]).
|
42
|
-
select {|sel| sel.is_a?(Pseudo) && sel.type == :element}
|
43
|
-
end
|
44
|
-
|
45
|
-
# Returns the non-base, non-pseudo-class selectors in this sequence.
|
40
|
+
# Returns the non-base selectors in this sequence.
|
46
41
|
#
|
47
42
|
# @return [Set<Simple>]
|
48
43
|
def rest
|
49
|
-
@rest ||= Set.new(
|
44
|
+
@rest ||= Set.new(base ? members[1..-1] : members)
|
50
45
|
end
|
51
46
|
|
52
47
|
# Whether or not this compound selector is the subject of the parent
|
@@ -79,16 +74,13 @@ module Sass
|
|
79
74
|
# Parent selector only appears as the first selector in the sequence
|
80
75
|
return [self] unless @members.first.is_a?(Parent)
|
81
76
|
|
82
|
-
|
83
|
-
|
84
|
-
return members if @members.size == 1
|
85
|
-
unless members.last.is_a?(SimpleSequence)
|
77
|
+
return super_seq.members if @members.size == 1
|
78
|
+
unless super_seq.members.last.is_a?(SimpleSequence)
|
86
79
|
raise Sass::SyntaxError.new("Invalid parent selector: " + super_seq.to_a.join)
|
87
80
|
end
|
88
81
|
|
89
|
-
members[0...-1] +
|
90
|
-
[SimpleSequence.new(members.last.members + @members[1..-1], subject?)]
|
91
|
-
[newline].compact
|
82
|
+
super_seq.members[0...-1] +
|
83
|
+
[SimpleSequence.new(super_seq.members.last.members + @members[1..-1], subject?)]
|
92
84
|
end
|
93
85
|
|
94
86
|
# Non-destrucively extends this selector with the extensions specified in a hash
|
@@ -109,8 +101,8 @@ module Sass
|
|
109
101
|
# If A {@extend B} and C {...},
|
110
102
|
# seq is A, sels is B, and self is C
|
111
103
|
|
112
|
-
self_without_sel =
|
113
|
-
group.each {|e, _| e.result = :failed_to_unify
|
104
|
+
self_without_sel = self.members - sels
|
105
|
+
group.each {|e, _| e.result = :failed_to_unify}
|
114
106
|
next unless unified = seq.members.last.unify(self_without_sel, subject?)
|
115
107
|
group.each {|e, _| e.result = :succeeded}
|
116
108
|
next if group.map {|e, _| check_directives_match!(e, parent_directives)}.none?
|
@@ -137,9 +129,9 @@ module Sass
|
|
137
129
|
# by the time extension and unification happen,
|
138
130
|
# this exception will only ever be raised as a result of programmer error
|
139
131
|
def unify(sels, other_subject)
|
140
|
-
return unless sseq = members.inject(sels) do |
|
141
|
-
return unless
|
142
|
-
sel.unify(
|
132
|
+
return unless sseq = members.inject(sels) do |sseq, sel|
|
133
|
+
return unless sseq
|
134
|
+
sel.unify(sseq)
|
143
135
|
end
|
144
136
|
SimpleSequence.new(sseq, other_subject || subject?)
|
145
137
|
end
|
@@ -153,9 +145,7 @@ module Sass
|
|
153
145
|
# @param sseq [SimpleSequence]
|
154
146
|
# @return [Boolean]
|
155
147
|
def superselector?(sseq)
|
156
|
-
(base.nil? || base.eql?(sseq.base)) &&
|
157
|
-
pseudo_elements.eql?(sseq.pseudo_elements) &&
|
158
|
-
rest.subset?(sseq.rest)
|
148
|
+
(base.nil? || base.eql?(sseq.base)) && rest.subset?(sseq.rest)
|
159
149
|
end
|
160
150
|
|
161
151
|
# @see Simple#to_a
|
@@ -181,7 +171,7 @@ module Sass
|
|
181
171
|
def with_more_sources(sources)
|
182
172
|
sseq = dup
|
183
173
|
sseq.members = members.dup
|
184
|
-
sseq.sources
|
174
|
+
sseq.sources.merge sources
|
185
175
|
sseq
|
186
176
|
end
|
187
177
|
|
@@ -207,8 +197,8 @@ WARNING
|
|
207
197
|
end
|
208
198
|
|
209
199
|
def _eql?(other)
|
210
|
-
other.base.eql?(self.base) && other.
|
211
|
-
|
200
|
+
other.base.eql?(self.base) && Sass::Util.set_eql?(other.rest, self.rest) &&
|
201
|
+
other.subject? == self.subject?
|
212
202
|
end
|
213
203
|
end
|
214
204
|
end
|
@@ -70,13 +70,13 @@ module Sass::Tree
|
|
70
70
|
private
|
71
71
|
|
72
72
|
def normalize_indentation(str)
|
73
|
-
|
73
|
+
pre = str.split("\n").inject(str[/^[ \t]*/].split("")) do |pre, line|
|
74
74
|
line[/^[ \t]*/].split("").zip(pre).inject([]) do |arr, (a, b)|
|
75
75
|
break arr if a != b
|
76
76
|
arr << a
|
77
77
|
end
|
78
78
|
end.join
|
79
|
-
str.gsub(/^#{
|
79
|
+
str.gsub(/^#{pre}/, '')
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
@@ -9,9 +9,6 @@ module Sass
|
|
9
9
|
# @return [String]
|
10
10
|
attr_reader :imported_filename
|
11
11
|
|
12
|
-
# Sets the imported file.
|
13
|
-
attr_writer :imported_file
|
14
|
-
|
15
12
|
# @param imported_filename [String] The name of the imported file
|
16
13
|
def initialize(imported_filename)
|
17
14
|
@imported_filename = imported_filename
|
@@ -46,12 +43,12 @@ module Sass
|
|
46
43
|
|
47
44
|
if @options[:importer]
|
48
45
|
f = @options[:importer].find_relative(
|
49
|
-
@imported_filename, @options[:filename],
|
46
|
+
@imported_filename, @options[:filename], @options.dup)
|
50
47
|
return f if f
|
51
48
|
end
|
52
49
|
|
53
50
|
paths.each do |p|
|
54
|
-
if f = p.find(@imported_filename,
|
51
|
+
if f = p.find(@imported_filename, @options.dup)
|
55
52
|
return f
|
56
53
|
end
|
57
54
|
end
|
@@ -66,10 +63,6 @@ module Sass
|
|
66
63
|
rescue SyntaxError => e
|
67
64
|
raise SyntaxError.new(e.message, :line => self.line, :filename => @filename)
|
68
65
|
end
|
69
|
-
|
70
|
-
def options_for_importer
|
71
|
-
@options.merge(:_line => line)
|
72
|
-
end
|
73
66
|
end
|
74
67
|
end
|
75
68
|
end
|
@@ -23,8 +23,7 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
|
|
23
23
|
SCRIPT_NODES = [Sass::Tree::ImportNode] + CONTROL_NODES
|
24
24
|
def visit_children(parent)
|
25
25
|
old_parent = @parent
|
26
|
-
@parent = parent unless is_any_of?(parent, SCRIPT_NODES)
|
27
|
-
(parent.bubbles? && !old_parent.is_a?(Sass::Tree::RootNode))
|
26
|
+
@parent = parent unless is_any_of?(parent, SCRIPT_NODES)
|
28
27
|
@parents.push parent
|
29
28
|
super
|
30
29
|
ensure
|
@@ -140,7 +139,7 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
|
|
140
139
|
end
|
141
140
|
|
142
141
|
def try_send(method, *args)
|
143
|
-
return unless respond_to?(method
|
142
|
+
return unless respond_to?(method)
|
144
143
|
send(method, *args)
|
145
144
|
end
|
146
145
|
end
|
@@ -89,6 +89,7 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
89
89
|
end.gsub(/^/, spaces) + "\n"
|
90
90
|
content
|
91
91
|
end
|
92
|
+
content.sub!(%r{^\s*(/\*)}, '/*!') if node.type == :loud #'
|
92
93
|
content
|
93
94
|
end
|
94
95
|
|
@@ -194,19 +195,13 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
194
195
|
end
|
195
196
|
|
196
197
|
def visit_mixin(node)
|
197
|
-
arg_to_sass = lambda do |arg|
|
198
|
-
sass = arg.to_sass(@options)
|
199
|
-
sass = "(#{sass})" if arg.is_a?(Sass::Script::List) && arg.separator == :comma
|
200
|
-
sass
|
201
|
-
end
|
202
|
-
|
203
198
|
unless node.args.empty? && node.keywords.empty? && node.splat.nil?
|
204
|
-
args = node.args.map(
|
199
|
+
args = node.args.map {|a| a.to_sass(@options)}.join(", ")
|
205
200
|
keywords = Sass::Util.hash_to_a(node.keywords).
|
206
|
-
map {|k, v| "$#{dasherize(k)}: #{
|
201
|
+
map {|k, v| "$#{dasherize(k)}: #{v.to_sass(@options)}"}.join(', ')
|
207
202
|
if node.splat
|
208
203
|
splat = (args.empty? && keywords.empty?) ? "" : ", "
|
209
|
-
splat = "#{splat}#{
|
204
|
+
splat = "#{splat}#{node.splat.to_sass(@options)}..."
|
210
205
|
end
|
211
206
|
arglist = "(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords}#{splat})"
|
212
207
|
end
|
@@ -32,8 +32,6 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
MERGEABLE_DIRECTIVES = [Sass::Tree::MediaNode]
|
36
|
-
|
37
35
|
# Runs a block of code with the current parent node
|
38
36
|
# replaced with the given node.
|
39
37
|
#
|
@@ -41,18 +39,11 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
41
39
|
# @yield A block in which the parent is set to `parent`.
|
42
40
|
# @return [Object] The return value of the block.
|
43
41
|
def with_parent(parent)
|
44
|
-
if parent.is_a?(Sass::Tree::DirectiveNode)
|
45
|
-
if MERGEABLE_DIRECTIVES.any? {|klass| parent.is_a?(klass)}
|
46
|
-
old_parent_directive = @parent_directives.pop
|
47
|
-
end
|
48
|
-
@parent_directives.push parent
|
49
|
-
end
|
50
|
-
|
42
|
+
@parent_directives.push parent if parent.is_a?(Sass::Tree::DirectiveNode)
|
51
43
|
old_parent, @parent = @parent, parent
|
52
44
|
yield
|
53
45
|
ensure
|
54
46
|
@parent_directives.pop if parent.is_a?(Sass::Tree::DirectiveNode)
|
55
|
-
@parent_directives.push old_parent_directive if old_parent_directive
|
56
47
|
@parent = old_parent
|
57
48
|
end
|
58
49
|
|
@@ -73,29 +64,17 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
73
64
|
node.children.unshift charset if charset
|
74
65
|
end
|
75
66
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
node.children.reject! do |n|
|
80
|
-
i += 1
|
81
|
-
if import_limit
|
82
|
-
next false unless n.is_a?(Sass::Tree::CssImportNode)
|
83
|
-
imports_to_move << n
|
84
|
-
next true
|
85
|
-
end
|
86
|
-
|
87
|
-
if !n.is_a?(Sass::Tree::CommentNode) &&
|
88
|
-
!n.is_a?(Sass::Tree::CharsetNode) &&
|
89
|
-
!n.is_a?(Sass::Tree::CssImportNode)
|
90
|
-
import_limit = i
|
91
|
-
end
|
92
|
-
|
93
|
-
false
|
67
|
+
imports = Sass::Util.extract!(node.children) do |c|
|
68
|
+
c.is_a?(Sass::Tree::DirectiveNode) && !c.is_a?(Sass::Tree::MediaNode) &&
|
69
|
+
c.resolved_value =~ /^@import /i
|
94
70
|
end
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
71
|
+
charset_and_index = Sass::Util.ruby1_8? &&
|
72
|
+
node.children.each_with_index.find {|c, _| c.is_a?(Sass::Tree::CharsetNode)}
|
73
|
+
if charset_and_index
|
74
|
+
index = charset_and_index.last
|
75
|
+
node.children = node.children[0..index] + imports + node.children[index+1..-1]
|
76
|
+
else
|
77
|
+
node.children = imports + node.children
|
99
78
|
end
|
100
79
|
end
|
101
80
|
|
@@ -136,12 +115,12 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
136
115
|
end
|
137
116
|
|
138
117
|
sel = sseq.members
|
139
|
-
parent.resolved_rules.members.each do |
|
140
|
-
if !
|
141
|
-
raise Sass::SyntaxError.new("#{
|
118
|
+
parent.resolved_rules.members.each do |seq|
|
119
|
+
if !seq.members.last.is_a?(Sass::Selector::SimpleSequence)
|
120
|
+
raise Sass::SyntaxError.new("#{seq} can't extend: invalid selector")
|
142
121
|
end
|
143
122
|
|
144
|
-
@extends[sel] = Extend.new(
|
123
|
+
@extends[sel] = Extend.new(seq, sel, node, @parent_directives.dup, :not_found)
|
145
124
|
end
|
146
125
|
end
|
147
126
|
|
@@ -14,13 +14,11 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
14
14
|
|
15
15
|
begin
|
16
16
|
unless keywords.empty?
|
17
|
-
unknown_args =
|
18
|
-
callable.args.map {|var| var.first.underscored_name})
|
17
|
+
unknown_args = keywords.keys - callable.args.map {|var| var.first.underscored_name}
|
19
18
|
if callable.splat && unknown_args.include?(callable.splat.underscored_name)
|
20
19
|
raise Sass::SyntaxError.new("Argument $#{callable.splat.name} of #{downcase_desc} cannot be used as a named argument.")
|
21
20
|
elsif unknown_args.any?
|
22
|
-
|
23
|
-
raise Sass::SyntaxError.new("#{desc} doesn't have #{description} #{unknown_args.map {|name| "$#{name}"}.join ', '}.")
|
21
|
+
raise Sass::SyntaxError.new("#{desc} doesn't have #{unknown_args.length > 1 ? 'the following arguments:' : 'an argument named'} #{unknown_args.map{|name| "$#{name}"}.join ', '}.")
|
24
22
|
end
|
25
23
|
end
|
26
24
|
rescue Sass::SyntaxError => keyword_exception
|
@@ -68,7 +66,6 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
68
66
|
end
|
69
67
|
|
70
68
|
yield env
|
71
|
-
rescue Exception => e
|
72
69
|
ensure
|
73
70
|
# If there's a keyword exception, we don't want to throw it immediately,
|
74
71
|
# because the invalid keywords may be part of a glob argument that should be
|
@@ -80,10 +77,10 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
80
77
|
# non-Sass exceptions.
|
81
78
|
if keyword_exception &&
|
82
79
|
!(arg_list && arg_list.keywords_accessed) &&
|
83
|
-
(
|
80
|
+
($!.nil? || $!.is_a?(Sass::SyntaxError))
|
84
81
|
raise keyword_exception
|
85
|
-
elsif
|
86
|
-
raise
|
82
|
+
elsif $!
|
83
|
+
raise $!
|
87
84
|
end
|
88
85
|
end
|
89
86
|
|
@@ -144,9 +141,9 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
144
141
|
res = node.expr.perform(@environment)
|
145
142
|
res = res.value if res.is_a?(Sass::Script::String)
|
146
143
|
if node.filename
|
147
|
-
|
144
|
+
$stderr.puts "#{node.filename}:#{node.line} DEBUG: #{res}"
|
148
145
|
else
|
149
|
-
|
146
|
+
$stderr.puts "Line #{node.line} DEBUG: #{res}"
|
150
147
|
end
|
151
148
|
[]
|
152
149
|
end
|
@@ -220,17 +217,15 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
220
217
|
file = node.imported_file
|
221
218
|
handle_import_loop!(node) if @stack.any? {|e| e[:filename] == file.options[:filename]}
|
222
219
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
raise e
|
233
|
-
end
|
220
|
+
@stack.push(:filename => node.filename, :line => node.line)
|
221
|
+
root = file.to_tree
|
222
|
+
Sass::Tree::Visitors::CheckNesting.visit(root)
|
223
|
+
node.children = root.children.map {|c| visit(c)}.flatten
|
224
|
+
node
|
225
|
+
rescue Sass::SyntaxError => e
|
226
|
+
e.modify_backtrace(:filename => node.imported_file.options[:filename])
|
227
|
+
e.add_backtrace(:filename => node.filename, :line => node.line)
|
228
|
+
raise e
|
234
229
|
ensure
|
235
230
|
@stack.pop unless path
|
236
231
|
end
|
@@ -335,7 +330,9 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
335
330
|
res = node.expr.perform(@environment)
|
336
331
|
res = res.value if res.is_a?(Sass::Script::String)
|
337
332
|
msg = "WARNING: #{res}\n "
|
338
|
-
msg << stack_trace.join("\n ")
|
333
|
+
msg << stack_trace.join("\n ")
|
334
|
+
# JRuby doesn't automatically add a newline for #warn
|
335
|
+
msg << (RUBY_PLATFORM =~ /java/ ? "\n\n" : "\n")
|
339
336
|
Sass::Util.sass_warn msg
|
340
337
|
[]
|
341
338
|
ensure
|
@@ -421,7 +418,7 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
421
418
|
end
|
422
419
|
end
|
423
420
|
|
424
|
-
return
|
421
|
+
return if mixins.empty?
|
425
422
|
raise Sass::SyntaxError.new("#{msg} #{node.name} includes itself") if mixins.size == 1
|
426
423
|
|
427
424
|
msg << "\n" << Sass::Util.enum_cons(mixins.reverse + [node.name], 2).map do |m1, m2|
|