sass 3.2.0.alpha.60 → 3.2.0.alpha.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/REVISION +1 -1
- data/VERSION +1 -1
- data/lib/sass/cache_stores/filesystem.rb +1 -0
- data/lib/sass/engine.rb +1 -1
- data/lib/sass/media.rb +50 -0
- data/lib/sass/script/funcall.rb +2 -2
- data/lib/sass/script/literal.rb +0 -20
- data/lib/sass/script/operation.rb +8 -0
- data/lib/sass/selector.rb +1 -1
- data/lib/sass/selector/sequence.rb +129 -17
- data/lib/sass/tree/visitors/convert.rb +2 -1
- data/lib/sass/tree/visitors/cssize.rb +21 -6
- data/lib/sass/tree/visitors/deep_copy.rb +10 -0
- data/lib/sass/tree/visitors/perform.rb +3 -0
- data/lib/sass/tree/visitors/set_options.rb +10 -0
- data/lib/sass/tree/visitors/to_css.rb +11 -3
- data/lib/sass/util.rb +32 -0
- data/test/sass/engine_test.rb +49 -2
- data/test/sass/extend_test.rb +476 -2
- data/test/sass/more_results/more_import.css +2 -2
- data/test/sass/results/import.css +2 -2
- data/test/sass/results/import_charset.css +1 -0
- data/test/sass/results/import_charset_1_8.css +1 -0
- data/test/sass/results/import_charset_ibm866.css +1 -0
- data/test/sass/results/scss_import.css +2 -2
- data/test/sass/script_test.rb +5 -0
- data/test/sass/scss/scss_test.rb +3 -3
- data/test/sass/templates/import_charset.sass +2 -0
- data/test/sass/templates/import_charset_1_8.sass +2 -0
- data/test/sass/templates/import_charset_ibm866.sass +2 -0
- data/test/sass/util_test.rb +6 -0
- metadata +13 -13
data/REVISION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
f03f995506891014aea1df1a16672298469b3966
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.2.0.alpha.
|
1
|
+
3.2.0.alpha.61
|
data/lib/sass/engine.rb
CHANGED
@@ -224,7 +224,7 @@ module Sass
|
|
224
224
|
# If you're compiling a single Sass file from the filesystem,
|
225
225
|
# use \{Sass::Engine.for\_file}.
|
226
226
|
# If you're compiling multiple files from the filesystem,
|
227
|
-
# use {Sass::Plugin.
|
227
|
+
# use {Sass::Plugin}.
|
228
228
|
#
|
229
229
|
# @param template [String] The Sass template.
|
230
230
|
# This template can be encoded using any encoding
|
data/lib/sass/media.rb
CHANGED
@@ -51,6 +51,20 @@ module Sass::Media
|
|
51
51
|
def to_src(options)
|
52
52
|
queries.map {|q| q.to_src(options)}.join(', ')
|
53
53
|
end
|
54
|
+
|
55
|
+
# Returns a deep copy of this query list and all its children.
|
56
|
+
#
|
57
|
+
# @return [QueryList]
|
58
|
+
def deep_copy
|
59
|
+
QueryList.new(queries.map {|q| q.deep_copy})
|
60
|
+
end
|
61
|
+
|
62
|
+
# Sets the options hash for the script nodes in the media query.
|
63
|
+
#
|
64
|
+
# @param options [{Symbol => Object}] The options has to set.
|
65
|
+
def options=(options)
|
66
|
+
queries.each {|q| q.options = options}
|
67
|
+
end
|
54
68
|
end
|
55
69
|
|
56
70
|
# A single media query.
|
@@ -164,6 +178,25 @@ module Sass::Media
|
|
164
178
|
src << expressions.map {|e| e.to_src(options)}.join(' and ')
|
165
179
|
src
|
166
180
|
end
|
181
|
+
|
182
|
+
# Returns a deep copy of this query and all its children.
|
183
|
+
#
|
184
|
+
# @return [Query]
|
185
|
+
def deep_copy
|
186
|
+
Query.new(
|
187
|
+
modifier.map {|c| c.is_a?(Sass::Script::Node) ? c.deep_copy : c},
|
188
|
+
type.map {|c| c.is_a?(Sass::Script::Node) ? c.deep_copy : c},
|
189
|
+
expressions.map {|q| q.deep_copy})
|
190
|
+
end
|
191
|
+
|
192
|
+
# Sets the options hash for the script nodes in the media query.
|
193
|
+
#
|
194
|
+
# @param options [{Symbol => Object}] The options has to set.
|
195
|
+
def options=(options)
|
196
|
+
modifier.each {|m| m.options = options if m.is_a?(Sass::Script::Node)}
|
197
|
+
type.each {|t| t.options = options if t.is_a?(Sass::Script::Node)}
|
198
|
+
expressions.each {|e| e.options = options}
|
199
|
+
end
|
167
200
|
end
|
168
201
|
|
169
202
|
# A media query expression.
|
@@ -232,6 +265,23 @@ module Sass::Media
|
|
232
265
|
src << ')'
|
233
266
|
src
|
234
267
|
end
|
268
|
+
|
269
|
+
# Returns a deep copy of this expression.
|
270
|
+
#
|
271
|
+
# @return [Expression]
|
272
|
+
def deep_copy
|
273
|
+
Expression.new(
|
274
|
+
name.map {|c| c.is_a?(Sass::Script::Node) ? c.deep_copy : c},
|
275
|
+
value.map {|c| c.is_a?(Sass::Script::Node) ? c.deep_copy : c})
|
276
|
+
end
|
277
|
+
|
278
|
+
# Sets the options hash for the script nodes in the expression.
|
279
|
+
#
|
280
|
+
# @param options [{Symbol => Object}] The options has to set.
|
281
|
+
def options=(options)
|
282
|
+
name.each {|n| n.options = options if n.is_a?(Sass::Script::Node)}
|
283
|
+
value.each {|v| v.options = options if v.is_a?(Sass::Script::Node)}
|
284
|
+
end
|
235
285
|
end
|
236
286
|
|
237
287
|
# Converts an interpolation array that may represent a single variable to source.
|
data/lib/sass/script/funcall.rb
CHANGED
@@ -36,7 +36,7 @@ module Sass
|
|
36
36
|
# @return [String] A string representation of the function call
|
37
37
|
def inspect
|
38
38
|
args = @args.map {|a| a.inspect}.join(', ')
|
39
|
-
keywords = @keywords.
|
39
|
+
keywords = Sass::Util.hash_to_a(@keywords).
|
40
40
|
map {|k, v| "$#{k}: #{v.inspect}"}.join(', ')
|
41
41
|
"#{name}(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords})"
|
42
42
|
end
|
@@ -44,7 +44,7 @@ module Sass
|
|
44
44
|
# @see Node#to_sass
|
45
45
|
def to_sass(opts = {})
|
46
46
|
args = @args.map {|a| a.to_sass(opts)}.join(', ')
|
47
|
-
keywords = @keywords.
|
47
|
+
keywords = Sass::Util.hash_to_a(@keywords).
|
48
48
|
map {|k, v| "$#{dasherize(k, opts)}: #{v.to_sass(opts)}"}.join(', ')
|
49
49
|
"#{dasherize(name, opts)}(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords})"
|
50
50
|
end
|
data/lib/sass/script/literal.rb
CHANGED
@@ -55,26 +55,6 @@ The #options attribute is not set on this #{self.class}.
|
|
55
55
|
MSG
|
56
56
|
end
|
57
57
|
|
58
|
-
# The SassScript `and` operation.
|
59
|
-
#
|
60
|
-
# @param other [Literal] The right-hand side of the operator
|
61
|
-
# @return [Literal] The result of a logical and:
|
62
|
-
# `other` if this literal isn't a false {Bool},
|
63
|
-
# and this literal otherwise
|
64
|
-
def and(other)
|
65
|
-
to_bool ? other : self
|
66
|
-
end
|
67
|
-
|
68
|
-
# The SassScript `or` operation.
|
69
|
-
#
|
70
|
-
# @param other [Literal] The right-hand side of the operator
|
71
|
-
# @return [Literal] The result of the logical or:
|
72
|
-
# this literal if it isn't a false {Bool},
|
73
|
-
# and `other` otherwise
|
74
|
-
def or(other)
|
75
|
-
to_bool ? self : other
|
76
|
-
end
|
77
|
-
|
78
58
|
# The SassScript `==` operation.
|
79
59
|
# **Note that this returns a {Sass::Script::Bool} object,
|
80
60
|
# not a Ruby boolean**.
|
@@ -72,6 +72,14 @@ module Sass::Script
|
|
72
72
|
# @raise [Sass::SyntaxError] if the operation is undefined for the operands
|
73
73
|
def _perform(environment)
|
74
74
|
literal1 = @operand1.perform(environment)
|
75
|
+
|
76
|
+
# Special-case :and and :or to support short-circuiting.
|
77
|
+
if @operator == :and
|
78
|
+
return literal1.to_bool ? @operand2.perform(environment) : literal1
|
79
|
+
elsif @operator == :or
|
80
|
+
return literal1.to_bool ? literal1 : @operand2.perform(environment)
|
81
|
+
end
|
82
|
+
|
75
83
|
literal2 = @operand2.perform(environment)
|
76
84
|
|
77
85
|
begin
|
data/lib/sass/selector.rb
CHANGED
@@ -379,7 +379,7 @@ module Sass
|
|
379
379
|
attr_reader :selector
|
380
380
|
|
381
381
|
# @param [String] The name of the pseudoclass
|
382
|
-
# @param [Selector::
|
382
|
+
# @param [Selector::CommaSequence] The selector argument
|
383
383
|
def initialize(name, selector)
|
384
384
|
@name = name
|
385
385
|
@selector = selector
|
@@ -124,15 +124,15 @@ module Sass
|
|
124
124
|
# @param path [Array<Array<SimpleSequence or String>>] A list of parenthesized selector groups.
|
125
125
|
# @return [Array<Array<SimpleSequence or String>>] A list of fully-expanded selectors.
|
126
126
|
def weave(path)
|
127
|
+
# This function works by moving through the selector path left-to-right,
|
128
|
+
# building all possible prefixes simultaneously. These prefixes are
|
129
|
+
# `befores`, while the remaining parenthesized suffixes is `afters`.
|
127
130
|
befores = [[]]
|
128
131
|
afters = path.dup
|
129
132
|
|
130
133
|
until afters.empty?
|
131
134
|
current = afters.shift.dup
|
132
135
|
last_current = [current.pop]
|
133
|
-
while !current.empty? && last_current.first.is_a?(String) || current.last.is_a?(String)
|
134
|
-
last_current.unshift(current.pop)
|
135
|
-
end
|
136
136
|
befores = Sass::Util.flatten(befores.map do |before|
|
137
137
|
next [] unless sub = subweave(before, current)
|
138
138
|
sub.map {|seqs| seqs + last_current}
|
@@ -150,6 +150,12 @@ module Sass
|
|
150
150
|
# `.foo .baz .bar .bang`, `.foo .baz .bar.bang`, `.foo .baz .bang .bar`,
|
151
151
|
# and so on until `.baz .bang .foo .bar`.
|
152
152
|
#
|
153
|
+
# Semantically, for selectors A and B, this returns all selectors `AB_i`
|
154
|
+
# such that the union over all i of elements matched by `AB_i X` is
|
155
|
+
# identical to the intersection of all elements matched by `A X` and all
|
156
|
+
# elements matched by `B X`. Some `AB_i` are elided to reduce the size of
|
157
|
+
# the output.
|
158
|
+
#
|
153
159
|
# @param seq1 [Array<SimpleSequence or String>]
|
154
160
|
# @param seq2 [Array<SimpleSequence or String>]
|
155
161
|
# @return [Array<Array<SimpleSequence or String>>]
|
@@ -157,31 +163,34 @@ module Sass
|
|
157
163
|
return [seq2] if seq1.empty?
|
158
164
|
return [seq1] if seq2.empty?
|
159
165
|
|
166
|
+
seq1, seq2 = seq1.dup, seq2.dup
|
160
167
|
return unless init = merge_initial_ops(seq1, seq2)
|
168
|
+
return unless fin = merge_final_ops(seq1, seq2)
|
161
169
|
seq1 = group_selectors(seq1)
|
162
170
|
seq2 = group_selectors(seq2)
|
163
171
|
lcs = Sass::Util.lcs(seq2, seq1) do |s1, s2|
|
164
172
|
next s1 if s1 == s2
|
165
173
|
next unless s1.first.is_a?(SimpleSequence) && s2.first.is_a?(SimpleSequence)
|
166
|
-
next s2 if
|
167
|
-
next s1 if
|
174
|
+
next s2 if superselector?(s1, s2)
|
175
|
+
next s1 if superselector?(s2, s1)
|
168
176
|
end
|
169
177
|
|
170
178
|
diff = [[init]]
|
171
179
|
until lcs.empty?
|
172
|
-
diff << chunks(seq1, seq2) {|s|
|
180
|
+
diff << chunks(seq1, seq2) {|s| superselector?(s.first, lcs.first)} << [lcs.shift]
|
173
181
|
seq1.shift
|
174
182
|
seq2.shift
|
175
183
|
end
|
176
184
|
diff << chunks(seq1, seq2) {|s| s.empty?}
|
185
|
+
diff += fin.map {|sel| sel.is_a?(Array) ? sel : [sel]}
|
177
186
|
diff.reject! {|c| c.empty?}
|
178
187
|
|
179
188
|
Sass::Util.paths(diff).map {|p| p.flatten}
|
180
189
|
end
|
181
190
|
|
182
|
-
# Extracts initial selector
|
191
|
+
# Extracts initial selector combinators (`"+"`, `">"`, `"~"`, and `"\n"`)
|
183
192
|
# from two sequences and merges them together into a single array of
|
184
|
-
# selector
|
193
|
+
# selector combinators.
|
185
194
|
#
|
186
195
|
# @param seq1 [Array<SimpleSequence or String>]
|
187
196
|
# @param seq2 [Array<SimpleSequence or String>]
|
@@ -204,6 +213,100 @@ module Sass
|
|
204
213
|
return (newline ? ["\n"] : []) + (ops1.size > ops2.size ? ops1 : ops2)
|
205
214
|
end
|
206
215
|
|
216
|
+
# Extracts final selector combinators (`"+"`, `">"`, `"~"`) and the
|
217
|
+
# selectors to which they apply from two sequences and merges them
|
218
|
+
# together into a single array.
|
219
|
+
#
|
220
|
+
# @param seq1 [Array<SimpleSequence or String>]
|
221
|
+
# @param seq2 [Array<SimpleSequence or String>]
|
222
|
+
# @return [Array<SimpleSequence or String or
|
223
|
+
# Array<Array<SimpleSequence or String>>]
|
224
|
+
# If there are no trailing combinators to be merged, this will be the
|
225
|
+
# empty array. If the trailing combinators cannot be merged, this will
|
226
|
+
# be nil. Otherwise, this will contained the merged selector. Array
|
227
|
+
# elements are [Sass::Util#paths]-style options; conceptually, an "or"
|
228
|
+
# of multiple selectors.
|
229
|
+
def merge_final_ops(seq1, seq2, res = [])
|
230
|
+
ops1, ops2 = [], []
|
231
|
+
ops1 << seq1.pop while seq1.last.is_a?(String)
|
232
|
+
ops2 << seq2.pop while seq2.last.is_a?(String)
|
233
|
+
|
234
|
+
# Not worth the headache of trying to preserve newlines here. The most
|
235
|
+
# important use of newlines is at the beginning of the selector to wrap
|
236
|
+
# across lines anyway.
|
237
|
+
ops1.reject! {|o| o == "\n"}
|
238
|
+
ops2.reject! {|o| o == "\n"}
|
239
|
+
|
240
|
+
return res if ops1.empty? && ops2.empty?
|
241
|
+
if ops1.size > 1 || ops2.size > 1
|
242
|
+
# If there are multiple operators, something hacky's going on. If one
|
243
|
+
# is a supersequence of the other, use that, otherwise give up.
|
244
|
+
lcs = Sass::Util.lcs(ops1, ops2)
|
245
|
+
return unless lcs == ops1 || lcs == ops2
|
246
|
+
res.unshift *(ops1.size > ops2.size ? ops1 : ops2).reverse
|
247
|
+
return res
|
248
|
+
end
|
249
|
+
|
250
|
+
# This code looks complicated, but it's actually just a bunch of special
|
251
|
+
# cases for interactions between different combinators.
|
252
|
+
op1, op2 = ops1.first, ops2.first
|
253
|
+
if op1 && op2
|
254
|
+
sel1 = seq1.pop
|
255
|
+
sel2 = seq2.pop
|
256
|
+
if op1 == '~' && op2 == '~'
|
257
|
+
if superselector?([sel1], [sel2])
|
258
|
+
res.unshift sel2, '~'
|
259
|
+
elsif superselector?([sel2], [sel1])
|
260
|
+
res.unshift sel1, '~'
|
261
|
+
else
|
262
|
+
merged = sel1.unify(sel2.members)
|
263
|
+
res.unshift [
|
264
|
+
[sel1, '~', sel2, '~'],
|
265
|
+
[sel2, '~', sel1, '~'],
|
266
|
+
([merged, '~'] if merged)
|
267
|
+
].compact
|
268
|
+
end
|
269
|
+
elsif (op1 == '~' && op2 == '+') || (op1 == '+' && op2 == '~')
|
270
|
+
if op1 == '~'
|
271
|
+
tilde_sel, plus_sel = sel1, sel2
|
272
|
+
else
|
273
|
+
tilde_sel, plus_sel = sel2, sel1
|
274
|
+
end
|
275
|
+
|
276
|
+
if superselector?([tilde_sel], [plus_sel])
|
277
|
+
res.unshift plus_sel, '+'
|
278
|
+
else
|
279
|
+
merged = plus_sel.unify(tilde_sel.members)
|
280
|
+
res.unshift [
|
281
|
+
[tilde_sel, '~', plus_sel, '+'],
|
282
|
+
([merged, '+'] if merged)
|
283
|
+
].compact
|
284
|
+
end
|
285
|
+
elsif op1 == '>' && %w[~ +].include?(op2)
|
286
|
+
res.unshift sel2, op2
|
287
|
+
seq1.push sel1, op1
|
288
|
+
elsif op2 == '>' && %w[~ +].include?(op1)
|
289
|
+
res.unshift sel1, op1
|
290
|
+
seq2.push sel2, op2
|
291
|
+
elsif op1 == op2
|
292
|
+
return unless merged = sel1.unify(sel2.members)
|
293
|
+
res.unshift merged, op1
|
294
|
+
else
|
295
|
+
# Unknown selector combinators can't be unified
|
296
|
+
return
|
297
|
+
end
|
298
|
+
return merge_final_ops(seq1, seq2, res)
|
299
|
+
elsif op1
|
300
|
+
seq2.pop if op1 == '>' && seq2.last && superselector?([seq2.last], [seq1.last])
|
301
|
+
res.unshift seq1.pop, op1
|
302
|
+
return merge_final_ops(seq1, seq2, res)
|
303
|
+
else # op2
|
304
|
+
seq1.pop if op2 == '>' && seq1.last && superselector?([seq1.last], [seq2.last])
|
305
|
+
res.unshift seq2.pop, op2
|
306
|
+
return merge_final_ops(seq1, seq2, res)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
207
310
|
# Takes initial subsequences of `seq1` and `seq2` and returns all
|
208
311
|
# orderings of those subsequences. The initial subsequences are determined
|
209
312
|
# by a block.
|
@@ -223,6 +326,7 @@ module Sass
|
|
223
326
|
# cutting off some initial subsequence.
|
224
327
|
# @yieldreturn [Boolean] Whether or not to cut off the initial subsequence
|
225
328
|
# here.
|
329
|
+
# @return [Array<Array>] All possible orderings of the initial subsequences.
|
226
330
|
def chunks(seq1, seq2)
|
227
331
|
chunk1 = []
|
228
332
|
chunk1 << seq1.shift until yield seq1
|
@@ -257,25 +361,33 @@ module Sass
|
|
257
361
|
end
|
258
362
|
|
259
363
|
# Given two sequences of simple selectors, returns whether `sseq1` is a
|
260
|
-
# superselector of `sseq2
|
364
|
+
# superselector of `sseq2`; that is, whether `sseq1` matches every element
|
365
|
+
# `sseq2` matches.
|
366
|
+
#
|
367
|
+
# Both `sseq1` and `sseq2` are of the form
|
368
|
+
# `SimpleSelector (String SimpleSelector)* String*`, although selectors
|
369
|
+
# with a trailing operator are considered to be neither superselectors nor
|
370
|
+
# subselectors.
|
261
371
|
#
|
262
|
-
# @param sseq1 [Array<
|
263
|
-
# @param sseq2 [Array<
|
372
|
+
# @param sseq1 [Array<SimpleSequence or String>]
|
373
|
+
# @param sseq2 [Array<SimpleSequence or String>]
|
264
374
|
# @return [Boolean]
|
265
|
-
def
|
375
|
+
def superselector?(sseq1, sseq2)
|
376
|
+
sseq1 = sseq1.reject {|e| e == "\n"}
|
377
|
+
sseq2 = sseq2.reject {|e| e == "\n"}
|
378
|
+
# Selectors with trailing operators are neither superselectors nor
|
379
|
+
# subselectors.
|
380
|
+
return if sseq1.last.is_a?(String) || sseq2.last.is_a?(String)
|
266
381
|
if sseq1.size > 1
|
267
382
|
# More complex selectors are never superselectors of less complex ones
|
268
383
|
return unless sseq2.size > 1
|
269
384
|
# .foo ~ .bar is a superselector of .foo + .bar
|
270
385
|
return unless sseq1[1] == "~" ? sseq2[1] != ">" : sseq2[1] == sseq1[1]
|
271
386
|
return unless sseq1.first.superselector?(sseq2.first)
|
272
|
-
return
|
273
|
-
return false if sseq2.size == 2
|
274
|
-
return subweave_superselector?(sseq1[2..-1], sseq2[2..-1])
|
387
|
+
return superselector?(sseq1[2..-1], sseq2[2..-1])
|
275
388
|
elsif sseq2.size > 1
|
276
389
|
return true if sseq2[1] == ">" && sseq1.first.superselector?(sseq2.first)
|
277
|
-
return
|
278
|
-
return subweave_superselector?(sseq1, sseq2[2..-1])
|
390
|
+
return superselector?(sseq1, sseq2[2..-1])
|
279
391
|
else
|
280
392
|
sseq1.first.superselector?(sseq2.first)
|
281
393
|
end
|
@@ -168,7 +168,8 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
168
168
|
def visit_mixin(node)
|
169
169
|
unless node.args.empty? && node.keywords.empty?
|
170
170
|
args = node.args.map {|a| a.to_sass(@options)}.join(", ")
|
171
|
-
keywords = node.keywords
|
171
|
+
keywords = Sass::Util.hash_to_a(node.keywords).
|
172
|
+
map {|k, v| "$#{dasherize(k)}: #{v.to_sass(@options)}"}.join(', ')
|
172
173
|
arglist = "(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords})"
|
173
174
|
end
|
174
175
|
"#{tab_str}#{@format == :sass ? '+' : '@include '}#{dasherize(node.name)}#{arglist}#{node.has_children ? yield : semi}\n"
|
@@ -52,12 +52,27 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
52
52
|
def visit_root(node)
|
53
53
|
yield
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
55
|
+
if parent.nil?
|
56
|
+
# In Ruby 1.9 we can make all @charset nodes invisible
|
57
|
+
# and infer the final @charset from the encoding of the final string.
|
58
|
+
if Sass::Util.ruby1_8?
|
59
|
+
charset = node.children.find {|c| c.is_a?(Sass::Tree::CharsetNode)}
|
60
|
+
node.children.reject! {|c| c.is_a?(Sass::Tree::CharsetNode)}
|
61
|
+
node.children.unshift charset if charset
|
62
|
+
end
|
63
|
+
|
64
|
+
imports = Sass::Util.extract!(node.children) do |c|
|
65
|
+
c.is_a?(Sass::Tree::DirectiveNode) && !c.is_a?(Sass::Tree::MediaNode) &&
|
66
|
+
c.resolved_value =~ /^@import /i
|
67
|
+
end
|
68
|
+
charset_and_index = Sass::Util.ruby1_8? &&
|
69
|
+
node.children.each_with_index.find {|c, _| c.is_a?(Sass::Tree::CharsetNode)}
|
70
|
+
if charset_and_index
|
71
|
+
index = charset_and_index.last
|
72
|
+
node.children = node.children[0..index] + imports + node.children[index+1..-1]
|
73
|
+
else
|
74
|
+
node.children = imports + node.children
|
75
|
+
end
|
61
76
|
end
|
62
77
|
|
63
78
|
return node, @extends
|
@@ -84,4 +84,14 @@ class Sass::Tree::Visitors::DeepCopy < Sass::Tree::Visitors::Base
|
|
84
84
|
node.expr = node.expr.deep_copy
|
85
85
|
yield
|
86
86
|
end
|
87
|
+
|
88
|
+
def visit_directive(node)
|
89
|
+
node.value = node.value.map {|c| c.is_a?(Sass::Script::Node) ? c.deep_copy : c}
|
90
|
+
yield
|
91
|
+
end
|
92
|
+
|
93
|
+
def visit_media(node)
|
94
|
+
node.query = query.deep_copy
|
95
|
+
yield
|
96
|
+
end
|
87
97
|
end
|