sass 3.2.0.alpha.74 → 3.2.0.alpha.75
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/css.rb +144 -48
- data/lib/sass/scss/parser.rb +2 -2
- data/lib/sass/selector/abstract_sequence.rb +11 -2
- data/lib/sass/selector/simple.rb +6 -0
- data/lib/sass/tree/node.rb +2 -2
- data/lib/sass/tree/visitors/check_nesting.rb +2 -2
- data/lib/sass/util.rb +9 -8
- data/test/sass/css2sass_test.rb +24 -0
- metadata +6 -6
data/REVISION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
b551f92303175e7651794dcf5a70f6148042bf69
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.2.0.alpha.
|
1
|
+
3.2.0.alpha.75
|
data/lib/sass/css.rb
CHANGED
@@ -77,14 +77,29 @@ module Sass
|
|
77
77
|
# @return [Tree::Node] The root node of the parsed tree
|
78
78
|
def build_tree
|
79
79
|
root = Sass::SCSS::CssParser.new(@template, @options[:filename]).parse
|
80
|
+
parse_selectors root
|
80
81
|
expand_commas root
|
82
|
+
nest_seqs root
|
81
83
|
parent_ref_rules root
|
82
|
-
remove_parent_refs root
|
83
84
|
flatten_rules root
|
84
85
|
fold_commas root
|
86
|
+
dump_selectors root
|
85
87
|
root
|
86
88
|
end
|
87
89
|
|
90
|
+
# Parse all the selectors in the document and assign them to
|
91
|
+
# {Sass::Tree::RuleNode#parsed_rules}.
|
92
|
+
#
|
93
|
+
# @param root [Tree::Node] The parent node
|
94
|
+
def parse_selectors(root)
|
95
|
+
root.children.each do |child|
|
96
|
+
next parse_selectors(child) if child.is_a?(Tree::DirectiveNode)
|
97
|
+
next unless child.is_a?(Tree::RuleNode)
|
98
|
+
parser = Sass::SCSS::CssParser.new(child.rule.first, child.filename, child.line)
|
99
|
+
child.parsed_rules = parser.parse_selector
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
88
103
|
# Transform
|
89
104
|
#
|
90
105
|
# foo, bar, baz
|
@@ -102,13 +117,14 @@ module Sass
|
|
102
117
|
# @param root [Tree::Node] The parent node
|
103
118
|
def expand_commas(root)
|
104
119
|
root.children.map! do |child|
|
105
|
-
|
120
|
+
# child.parsed_rules.members.size > 1 iff the rule contains a comma
|
121
|
+
unless child.is_a?(Tree::RuleNode) && child.parsed_rules.members.size > 1
|
106
122
|
expand_commas(child) if child.is_a?(Tree::DirectiveNode)
|
107
123
|
next child
|
108
124
|
end
|
109
|
-
child.
|
110
|
-
|
111
|
-
node =
|
125
|
+
child.parsed_rules.members.map do |seq|
|
126
|
+
node = Tree::RuleNode.new([])
|
127
|
+
node.parsed_rules = make_cseq(seq)
|
112
128
|
node.children = child.children
|
113
129
|
node
|
114
130
|
end
|
@@ -116,22 +132,7 @@ module Sass
|
|
116
132
|
root.children.flatten!
|
117
133
|
end
|
118
134
|
|
119
|
-
# Make rules use
|
120
|
-
#
|
121
|
-
# foo
|
122
|
-
# color: green
|
123
|
-
# foo.bar
|
124
|
-
# color: blue
|
125
|
-
#
|
126
|
-
# becomes
|
127
|
-
#
|
128
|
-
# foo
|
129
|
-
# color: green
|
130
|
-
# &.bar
|
131
|
-
# color: blue
|
132
|
-
#
|
133
|
-
# This has the side effect of nesting rules,
|
134
|
-
# so that
|
135
|
+
# Make rules use nesting so that
|
135
136
|
#
|
136
137
|
# foo
|
137
138
|
# color: green
|
@@ -144,28 +145,31 @@ module Sass
|
|
144
145
|
#
|
145
146
|
# foo
|
146
147
|
# color: green
|
147
|
-
#
|
148
|
+
# bar
|
148
149
|
# color: red
|
149
|
-
#
|
150
|
+
# baz
|
150
151
|
# color: blue
|
151
152
|
#
|
152
153
|
# @param root [Tree::Node] The parent node
|
153
|
-
def
|
154
|
+
def nest_seqs(root)
|
154
155
|
current_rule = nil
|
155
156
|
root.children.map! do |child|
|
156
157
|
unless child.is_a?(Tree::RuleNode)
|
157
|
-
|
158
|
+
nest_seqs(child) if child.is_a?(Tree::DirectiveNode)
|
158
159
|
next child
|
159
160
|
end
|
160
161
|
|
161
|
-
|
162
|
+
seq = first_seq(child)
|
163
|
+
seq.members.reject! {|sseq| sseq == "\n"}
|
164
|
+
first, rest = seq.members.first, seq.members[1..-1]
|
162
165
|
|
163
|
-
if current_rule.nil? || current_rule
|
164
|
-
current_rule = Tree::RuleNode.new([
|
166
|
+
if current_rule.nil? || first_sseq(current_rule) != first
|
167
|
+
current_rule = Tree::RuleNode.new([])
|
168
|
+
current_rule.parsed_rules = make_seq(first)
|
165
169
|
end
|
166
170
|
|
167
|
-
|
168
|
-
child.
|
171
|
+
unless rest.empty?
|
172
|
+
child.parsed_rules = make_seq(*rest)
|
169
173
|
current_rule << child
|
170
174
|
else
|
171
175
|
current_rule.children += child.children
|
@@ -176,32 +180,57 @@ module Sass
|
|
176
180
|
root.children.compact!
|
177
181
|
root.children.uniq!
|
178
182
|
|
179
|
-
root.children.each {
|
183
|
+
root.children.each {|v| nest_seqs(v)}
|
180
184
|
end
|
181
185
|
|
182
|
-
#
|
186
|
+
# Make rules use parent refs so that
|
183
187
|
#
|
184
188
|
# foo
|
185
|
-
#
|
186
|
-
#
|
189
|
+
# color: green
|
190
|
+
# foo.bar
|
191
|
+
# color: blue
|
187
192
|
#
|
188
193
|
# becomes
|
189
194
|
#
|
190
195
|
# foo
|
191
|
-
#
|
196
|
+
# color: green
|
197
|
+
# &.bar
|
192
198
|
# color: blue
|
193
199
|
#
|
194
200
|
# @param root [Tree::Node] The parent node
|
195
|
-
def
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
child
|
200
|
-
|
201
|
-
|
202
|
-
|
201
|
+
def parent_ref_rules(root)
|
202
|
+
current_rule = nil
|
203
|
+
root.children.map! do |child|
|
204
|
+
unless child.is_a?(Tree::RuleNode)
|
205
|
+
parent_ref_rules(child) if child.is_a?(Tree::DirectiveNode)
|
206
|
+
next child
|
207
|
+
end
|
208
|
+
|
209
|
+
sseq = first_sseq(child)
|
210
|
+
next child unless sseq.is_a?(Sass::Selector::SimpleSequence)
|
211
|
+
|
212
|
+
firsts, rest = [sseq.members.first], sseq.members[1..-1]
|
213
|
+
firsts.push rest.shift if firsts.first.is_a?(Sass::Selector::Parent)
|
214
|
+
|
215
|
+
if current_rule.nil? || first_sseq(current_rule).members != firsts
|
216
|
+
current_rule = Tree::RuleNode.new([])
|
217
|
+
current_rule.parsed_rules = make_sseq(*firsts)
|
218
|
+
end
|
219
|
+
|
220
|
+
unless rest.empty?
|
221
|
+
rest.unshift Sass::Selector::Parent.new
|
222
|
+
child.parsed_rules = make_sseq(*rest)
|
223
|
+
current_rule << child
|
224
|
+
else
|
225
|
+
current_rule.children += child.children
|
203
226
|
end
|
227
|
+
|
228
|
+
current_rule
|
204
229
|
end
|
230
|
+
root.children.compact!
|
231
|
+
root.children.uniq!
|
232
|
+
|
233
|
+
root.children.each {|v| parent_ref_rules(v)}
|
205
234
|
end
|
206
235
|
|
207
236
|
# Flatten rules so that
|
@@ -238,7 +267,7 @@ module Sass
|
|
238
267
|
end
|
239
268
|
end
|
240
269
|
|
241
|
-
# Flattens a single rule
|
270
|
+
# Flattens a single rule.
|
242
271
|
#
|
243
272
|
# @param rule [Tree::RuleNode] The candidate for flattening
|
244
273
|
# @see #flatten_rules
|
@@ -246,10 +275,10 @@ module Sass
|
|
246
275
|
while rule.children.size == 1 && rule.children.first.is_a?(Tree::RuleNode)
|
247
276
|
child = rule.children.first
|
248
277
|
|
249
|
-
if child.
|
250
|
-
rule.
|
278
|
+
if first_simple_sel(child).is_a?(Sass::Selector::Parent)
|
279
|
+
rule.parsed_rules = child.parsed_rules.resolve_parent_refs(rule.parsed_rules)
|
251
280
|
else
|
252
|
-
rule.
|
281
|
+
rule.parsed_rules = make_seq(first_sseq(rule), *first_seq(child).members)
|
253
282
|
end
|
254
283
|
|
255
284
|
rule.children = child.children
|
@@ -282,7 +311,7 @@ module Sass
|
|
282
311
|
end
|
283
312
|
|
284
313
|
if prev_rule && prev_rule.children == child.children
|
285
|
-
prev_rule.
|
314
|
+
prev_rule.parsed_rules.members << first_seq(child)
|
286
315
|
next nil
|
287
316
|
end
|
288
317
|
|
@@ -292,5 +321,72 @@ module Sass
|
|
292
321
|
end
|
293
322
|
root.children.compact!
|
294
323
|
end
|
324
|
+
|
325
|
+
# Dump all the parsed {Sass::Tree::RuleNode} selectors to strings.
|
326
|
+
#
|
327
|
+
# @param root [Tree::Node] The parent node
|
328
|
+
def dump_selectors(root)
|
329
|
+
root.children.each do |child|
|
330
|
+
next dump_selectors(child) if child.is_a?(Tree::DirectiveNode)
|
331
|
+
next unless child.is_a?(Tree::RuleNode)
|
332
|
+
child.rule = child.parsed_rules.to_s
|
333
|
+
dump_selectors(child)
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
# Create a {Sass::Selector::CommaSequence}.
|
338
|
+
#
|
339
|
+
# @param seqs [Array<Sass::Selector::Sequence>]
|
340
|
+
# @return [Sass::Selector::CommaSequence]
|
341
|
+
def make_cseq(*seqs)
|
342
|
+
Sass::Selector::CommaSequence.new(seqs)
|
343
|
+
end
|
344
|
+
|
345
|
+
# Create a {Sass::Selector::CommaSequence} containing only a single
|
346
|
+
# {Sass::Selector::Sequence}.
|
347
|
+
#
|
348
|
+
# @param sseqs [Array<Sass::Selector::Sequence, String>]
|
349
|
+
# @return [Sass::Selector::CommaSequence]
|
350
|
+
def make_seq(*sseqs)
|
351
|
+
make_cseq(Sass::Selector::Sequence.new(sseqs))
|
352
|
+
end
|
353
|
+
|
354
|
+
# Create a {Sass::Selector::CommaSequence} containing only a single
|
355
|
+
# {Sass::Selector::Sequence} which in turn contains only a single
|
356
|
+
# {Sass::Selector::SimpleSequence}.
|
357
|
+
#
|
358
|
+
# @param sseqs [Array<Sass::Selector::Sequence, String>]
|
359
|
+
# @return [Sass::Selector::CommaSequence]
|
360
|
+
def make_sseq(*sseqs)
|
361
|
+
make_seq(Sass::Selector::SimpleSequence.new(sseqs))
|
362
|
+
end
|
363
|
+
|
364
|
+
# Return the first {Sass::Selector::Sequence} in a {Sass::Tree::RuleNode}.
|
365
|
+
#
|
366
|
+
# @param rule [Sass::Tree::RuleNode]
|
367
|
+
# @return [Sass::Selector::Sequence]
|
368
|
+
def first_seq(rule)
|
369
|
+
rule.parsed_rules.members.first
|
370
|
+
end
|
371
|
+
|
372
|
+
# Return the first {Sass::Selector::SimpleSequence} in a
|
373
|
+
# {Sass::Tree::RuleNode}.
|
374
|
+
#
|
375
|
+
# @param rule [Sass::Tree::RuleNode]
|
376
|
+
# @return [Sass::Selector::SimpleSequence, String]
|
377
|
+
def first_sseq(rule)
|
378
|
+
first_seq(rule).members.first
|
379
|
+
end
|
380
|
+
|
381
|
+
# Return the first {Sass::Selector::Simple} in a {Sass::Tree::RuleNode},
|
382
|
+
# unless the rule begins with a combinator.
|
383
|
+
#
|
384
|
+
# @param rule [Sass::Tree::RuleNode]
|
385
|
+
# @return [Sass::Selector::Simple?]
|
386
|
+
def first_simple_sel(rule)
|
387
|
+
sseq = first_sseq(rule)
|
388
|
+
return unless sseq.is_a?(Sass::Selector::SimpleSequence)
|
389
|
+
sseq.members.first
|
390
|
+
end
|
295
391
|
end
|
296
392
|
end
|
data/lib/sass/scss/parser.rb
CHANGED
@@ -835,11 +835,11 @@ MESSAGE
|
|
835
835
|
@strs.pop
|
836
836
|
end
|
837
837
|
|
838
|
-
def str?
|
838
|
+
def str?
|
839
839
|
pos = @scanner.pos
|
840
840
|
line = @line
|
841
841
|
@strs.push ""
|
842
|
-
throw_error
|
842
|
+
throw_error {yield} && @strs.last
|
843
843
|
rescue Sass::SyntaxError => e
|
844
844
|
@scanner.pos = pos
|
845
845
|
@line = line
|
@@ -2,8 +2,9 @@ module Sass
|
|
2
2
|
module Selector
|
3
3
|
# The abstract parent class of the various selector sequence classes.
|
4
4
|
#
|
5
|
-
# All subclasses should implement a `members` method
|
6
|
-
#
|
5
|
+
# All subclasses should implement a `members` method that returns an array
|
6
|
+
# of object that respond to `#line=` and `#filename=`, as well as a `to_a`
|
7
|
+
# method that returns an array of strings and script nodes.
|
7
8
|
class AbstractSequence
|
8
9
|
# The line of the Sass template on which this selector was declared.
|
9
10
|
#
|
@@ -64,6 +65,14 @@ module Sass
|
|
64
65
|
@has_placeholder ||=
|
65
66
|
members.any? {|m| m.is_a?(AbstractSequence) ? m.has_placeholder? : m.is_a?(Placeholder)}
|
66
67
|
end
|
68
|
+
|
69
|
+
# Converts the selector into a string. This is the standard selector
|
70
|
+
# string, along with any SassScript interpolation that may exist.
|
71
|
+
#
|
72
|
+
# @return [String]
|
73
|
+
def to_s
|
74
|
+
to_a.map {|e| e.is_a?(Sass::Script::Node) ? "\#{#{e.to_sass}}" : e}.join
|
75
|
+
end
|
67
76
|
end
|
68
77
|
end
|
69
78
|
end
|
data/lib/sass/selector/simple.rb
CHANGED
@@ -33,6 +33,12 @@ module Sass
|
|
33
33
|
to_a.map {|e| e.is_a?(Sass::Script::Node) ? "\#{#{e.to_sass}}" : e}.join
|
34
34
|
end
|
35
35
|
|
36
|
+
# @see \{#inspect}
|
37
|
+
# @return [String]
|
38
|
+
def to_s
|
39
|
+
inspect
|
40
|
+
end
|
41
|
+
|
36
42
|
# Returns a hash code for this selector object.
|
37
43
|
#
|
38
44
|
# By default, this is based on the value of \{#to\_a},
|
data/lib/sass/tree/node.rb
CHANGED
@@ -159,9 +159,9 @@ module Sass
|
|
159
159
|
#
|
160
160
|
# @yield node
|
161
161
|
# @yieldparam node [Node] a node in the tree
|
162
|
-
def each
|
162
|
+
def each
|
163
163
|
yield self
|
164
|
-
children.each {|c| c.each
|
164
|
+
children.each {|c| c.each {|n| yield n}}
|
165
165
|
end
|
166
166
|
|
167
167
|
# Converts a node to Sass code that will generate it.
|
@@ -143,9 +143,9 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
|
|
143
143
|
return false
|
144
144
|
end
|
145
145
|
|
146
|
-
def try_send(method, *args
|
146
|
+
def try_send(method, *args)
|
147
147
|
return unless respond_to?(method)
|
148
|
-
send(method, *args
|
148
|
+
send(method, *args)
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
data/lib/sass/util.rb
CHANGED
@@ -85,8 +85,9 @@ module Sass
|
|
85
85
|
# @return [Hash] The mapped hash
|
86
86
|
# @see #map_keys
|
87
87
|
# @see #map_vals
|
88
|
-
def map_hash(hash
|
89
|
-
|
88
|
+
def map_hash(hash)
|
89
|
+
# Using &block here completely hoses performance on 1.8.
|
90
|
+
to_hash(hash.map {|k, v| yield k, v})
|
90
91
|
end
|
91
92
|
|
92
93
|
# Computes the powerset of the given array.
|
@@ -211,11 +212,11 @@ module Sass
|
|
211
212
|
# @yieldreturn [Object, nil] If the two values register as equal,
|
212
213
|
# this will return the value to use in the LCS array.
|
213
214
|
# @return [Array] The LCS
|
214
|
-
def lcs(x, y
|
215
|
+
def lcs(x, y)
|
215
216
|
x = [nil, *x]
|
216
217
|
y = [nil, *y]
|
217
218
|
block ||= proc {|a, b| a == b && a}
|
218
|
-
lcs_backtrace(lcs_table(x, y,
|
219
|
+
lcs_backtrace(lcs_table(x, y) {|a, b| yield a, b}, x, y, x.size-1, y.size-1) {|a, b| yield a, b}
|
219
220
|
end
|
220
221
|
|
221
222
|
# Converts a Hash to an Array. This is usually identical to `Hash#to_a`,
|
@@ -762,14 +763,14 @@ MSG
|
|
762
763
|
|
763
764
|
# Computes a single longest common subsequence for arrays x and y.
|
764
765
|
# Algorithm from [Wikipedia](http://en.wikipedia.org/wiki/Longest_common_subsequence_problem#Reading_out_an_LCS)
|
765
|
-
def lcs_backtrace(c, x, y, i, j
|
766
|
+
def lcs_backtrace(c, x, y, i, j)
|
766
767
|
return [] if i == 0 || j == 0
|
767
768
|
if v = yield(x[i], y[j])
|
768
|
-
return lcs_backtrace(c, x, y, i-1, j-1,
|
769
|
+
return lcs_backtrace(c, x, y, i-1, j-1) {|a, b| yield a, b} << v
|
769
770
|
end
|
770
771
|
|
771
|
-
return lcs_backtrace(c, x, y, i, j-1,
|
772
|
-
return lcs_backtrace(c, x, y, i-1, j,
|
772
|
+
return lcs_backtrace(c, x, y, i, j-1) {|a, b| yield a, b} if c[i][j-1] > c[i-1][j]
|
773
|
+
return lcs_backtrace(c, x, y, i-1, j) {|a, b| yield a, b}
|
773
774
|
end
|
774
775
|
end
|
775
776
|
end
|
data/test/sass/css2sass_test.rb
CHANGED
@@ -277,6 +277,30 @@ foo, , bar { a: b }
|
|
277
277
|
CSS
|
278
278
|
end
|
279
279
|
|
280
|
+
def test_selector_splitting
|
281
|
+
assert_equal(<<SASS, css2sass(<<CSS))
|
282
|
+
.foo >
|
283
|
+
.bar
|
284
|
+
a: b
|
285
|
+
.baz
|
286
|
+
c: d
|
287
|
+
SASS
|
288
|
+
.foo>.bar {a: b}
|
289
|
+
.foo>.baz {c: d}
|
290
|
+
CSS
|
291
|
+
|
292
|
+
assert_equal(<<SASS, css2sass(<<CSS))
|
293
|
+
.foo
|
294
|
+
&::bar
|
295
|
+
a: b
|
296
|
+
&::baz
|
297
|
+
c: d
|
298
|
+
SASS
|
299
|
+
.foo::bar {a: b}
|
300
|
+
.foo::baz {c: d}
|
301
|
+
CSS
|
302
|
+
end
|
303
|
+
|
280
304
|
# Error reporting
|
281
305
|
|
282
306
|
def test_error_reporting
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sass
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 592302987
|
5
5
|
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 3
|
8
8
|
- 2
|
9
9
|
- 0
|
10
10
|
- alpha
|
11
|
-
-
|
12
|
-
version: 3.2.0.alpha.
|
11
|
+
- 75
|
12
|
+
version: 3.2.0.alpha.75
|
13
13
|
platform: ruby
|
14
14
|
authors:
|
15
15
|
- Nathan Weizenbaum
|
@@ -86,7 +86,7 @@ files:
|
|
86
86
|
- lib/sass/logger.rb
|
87
87
|
- lib/sass/logger/base.rb
|
88
88
|
- lib/sass/logger/log_level.rb
|
89
|
-
- lib/sass/
|
89
|
+
- lib/sass/util.rb
|
90
90
|
- lib/sass/plugin.rb
|
91
91
|
- lib/sass/plugin/compiler.rb
|
92
92
|
- lib/sass/plugin/configuration.rb
|
@@ -151,6 +151,7 @@ files:
|
|
151
151
|
- lib/sass/tree/root_node.rb
|
152
152
|
- lib/sass/tree/rule_node.rb
|
153
153
|
- lib/sass/tree/content_node.rb
|
154
|
+
- lib/sass/tree/trace_node.rb
|
154
155
|
- lib/sass/tree/variable_node.rb
|
155
156
|
- lib/sass/tree/visitors/base.rb
|
156
157
|
- lib/sass/tree/visitors/check_nesting.rb
|
@@ -162,8 +163,7 @@ files:
|
|
162
163
|
- lib/sass/tree/visitors/to_css.rb
|
163
164
|
- lib/sass/tree/warn_node.rb
|
164
165
|
- lib/sass/tree/while_node.rb
|
165
|
-
- lib/sass/
|
166
|
-
- lib/sass/util.rb
|
166
|
+
- lib/sass/media.rb
|
167
167
|
- lib/sass/util/multibyte_string_scanner.rb
|
168
168
|
- lib/sass/util/subset_map.rb
|
169
169
|
- lib/sass/version.rb
|