sass 3.4.25 → 3.7.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CODE_OF_CONDUCT.md +1 -1
- data/CONTRIBUTING.md +3 -3
- data/README.md +17 -9
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/extra/sass-spec-ref.sh +9 -1
- data/lib/sass.rb +0 -7
- data/lib/sass/cache_stores/filesystem.rb +1 -1
- data/lib/sass/css.rb +1 -2
- data/lib/sass/engine.rb +39 -29
- data/lib/sass/environment.rb +26 -5
- data/lib/sass/error.rb +2 -2
- data/lib/sass/exec/base.rb +2 -13
- data/lib/sass/exec/sass_scss.rb +1 -5
- data/lib/sass/features.rb +1 -0
- data/lib/sass/importers/filesystem.rb +6 -4
- data/lib/sass/logger/base.rb +11 -0
- data/lib/sass/plugin/compiler.rb +20 -50
- data/lib/sass/plugin/configuration.rb +2 -2
- data/lib/sass/railtie.rb +1 -1
- data/lib/sass/script/css_parser.rb +4 -1
- data/lib/sass/script/functions.rb +308 -81
- data/lib/sass/script/lexer.rb +63 -9
- data/lib/sass/script/parser.rb +287 -118
- data/lib/sass/script/tree/funcall.rb +35 -34
- data/lib/sass/script/tree/interpolation.rb +0 -3
- 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 +0 -8
- data/lib/sass/script/tree/operation.rb +1 -8
- 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 +17 -0
- data/lib/sass/script/value/callable.rb +25 -0
- data/lib/sass/script/value/color.rb +8 -2
- data/lib/sass/script/value/function.rb +19 -0
- data/lib/sass/script/value/helpers.rb +37 -11
- data/lib/sass/script/value/list.rb +35 -14
- data/lib/sass/script/value/map.rb +2 -2
- data/lib/sass/script/value/number.rb +3 -2
- data/lib/sass/scss/css_parser.rb +6 -1
- data/lib/sass/scss/parser.rb +145 -56
- data/lib/sass/scss/rx.rb +5 -11
- data/lib/sass/scss/static_parser.rb +20 -42
- data/lib/sass/selector.rb +4 -0
- data/lib/sass/selector/abstract_sequence.rb +7 -6
- data/lib/sass/selector/comma_sequence.rb +9 -5
- data/lib/sass/selector/pseudo.rb +20 -3
- data/lib/sass/selector/sequence.rb +35 -10
- data/lib/sass/selector/simple.rb +9 -2
- data/lib/sass/selector/simple_sequence.rb +8 -4
- data/lib/sass/source/map.rb +2 -6
- data/lib/sass/stack.rb +21 -1
- data/lib/sass/tree/charset_node.rb +1 -1
- data/lib/sass/tree/prop_node.rb +45 -53
- data/lib/sass/tree/rule_node.rb +6 -8
- 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 +4 -15
- data/lib/sass/tree/visitors/deep_copy.rb +1 -1
- data/lib/sass/tree/visitors/extend.rb +2 -8
- data/lib/sass/tree/visitors/perform.rb +23 -15
- data/lib/sass/tree/visitors/set_options.rb +1 -1
- data/lib/sass/tree/visitors/to_css.rb +49 -22
- data/lib/sass/util.rb +72 -310
- data/lib/sass/util/multibyte_string_scanner.rb +127 -131
- data/lib/sass/util/normalized_map.rb +1 -8
- data/lib/sass/version.rb +0 -4
- metadata +55 -202
- data/Rakefile +0 -453
- 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-spec.yml +0 -3
- data/test/sass/cache_test.rb +0 -131
- data/test/sass/callbacks_test.rb +0 -61
- data/test/sass/compiler_test.rb +0 -236
- data/test/sass/conversion_test.rb +0 -2188
- data/test/sass/css2sass_test.rb +0 -526
- data/test/sass/css_variable_test.rb +0 -132
- data/test/sass/data/hsl-rgb.txt +0 -319
- data/test/sass/encoding_test.rb +0 -219
- data/test/sass/engine_test.rb +0 -3447
- data/test/sass/exec_test.rb +0 -96
- data/test/sass/extend_test.rb +0 -1733
- data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
- data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
- data/test/sass/functions_test.rb +0 -1977
- data/test/sass/importer_test.rb +0 -421
- data/test/sass/logger_test.rb +0 -58
- data/test/sass/mock_importer.rb +0 -49
- data/test/sass/more_results/more1.css +0 -9
- data/test/sass/more_results/more1_with_line_comments.css +0 -26
- data/test/sass/more_results/more_import.css +0 -29
- data/test/sass/more_templates/_more_partial.sass +0 -2
- data/test/sass/more_templates/more1.sass +0 -23
- data/test/sass/more_templates/more_import.sass +0 -11
- data/test/sass/plugin_test.rb +0 -556
- data/test/sass/results/alt.css +0 -4
- data/test/sass/results/basic.css +0 -9
- data/test/sass/results/cached_import_option.css +0 -3
- data/test/sass/results/compact.css +0 -5
- data/test/sass/results/complex.css +0 -86
- data/test/sass/results/compressed.css +0 -1
- data/test/sass/results/expanded.css +0 -19
- data/test/sass/results/filename_fn.css +0 -3
- data/test/sass/results/if.css +0 -3
- data/test/sass/results/import.css +0 -31
- data/test/sass/results/import_charset.css +0 -5
- data/test/sass/results/import_charset_1_8.css +0 -5
- data/test/sass/results/import_charset_ibm866.css +0 -5
- data/test/sass/results/import_content.css +0 -1
- data/test/sass/results/line_numbers.css +0 -49
- data/test/sass/results/mixins.css +0 -95
- data/test/sass/results/multiline.css +0 -24
- data/test/sass/results/nested.css +0 -22
- data/test/sass/results/options.css +0 -1
- data/test/sass/results/parent_ref.css +0 -13
- data/test/sass/results/script.css +0 -16
- data/test/sass/results/scss_import.css +0 -31
- data/test/sass/results/scss_importee.css +0 -2
- data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
- data/test/sass/results/subdir/subdir.css +0 -3
- data/test/sass/results/units.css +0 -11
- data/test/sass/results/warn.css +0 -0
- data/test/sass/results/warn_imported.css +0 -0
- data/test/sass/script_conversion_test.rb +0 -357
- data/test/sass/script_test.rb +0 -1431
- data/test/sass/scss/css_test.rb +0 -1281
- data/test/sass/scss/rx_test.rb +0 -160
- data/test/sass/scss/scss_test.rb +0 -4205
- data/test/sass/scss/test_helper.rb +0 -37
- data/test/sass/source_map_test.rb +0 -1055
- data/test/sass/superselector_test.rb +0 -210
- data/test/sass/templates/_cached_import_option_partial.scss +0 -1
- data/test/sass/templates/_double_import_loop2.sass +0 -1
- data/test/sass/templates/_filename_fn_import.scss +0 -11
- data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
- data/test/sass/templates/_imported_charset_utf8.sass +0 -4
- data/test/sass/templates/_imported_content.sass +0 -3
- data/test/sass/templates/_partial.sass +0 -2
- data/test/sass/templates/_same_name_different_partiality.scss +0 -1
- data/test/sass/templates/alt.sass +0 -16
- data/test/sass/templates/basic.sass +0 -23
- data/test/sass/templates/bork1.sass +0 -2
- data/test/sass/templates/bork2.sass +0 -2
- data/test/sass/templates/bork3.sass +0 -2
- data/test/sass/templates/bork4.sass +0 -2
- data/test/sass/templates/bork5.sass +0 -3
- data/test/sass/templates/cached_import_option.scss +0 -3
- data/test/sass/templates/compact.sass +0 -17
- data/test/sass/templates/complex.sass +0 -305
- data/test/sass/templates/compressed.sass +0 -15
- data/test/sass/templates/double_import_loop1.sass +0 -1
- data/test/sass/templates/expanded.sass +0 -17
- data/test/sass/templates/filename_fn.scss +0 -18
- data/test/sass/templates/if.sass +0 -11
- data/test/sass/templates/import.sass +0 -12
- data/test/sass/templates/import_charset.sass +0 -9
- data/test/sass/templates/import_charset_1_8.sass +0 -6
- data/test/sass/templates/import_charset_ibm866.sass +0 -11
- data/test/sass/templates/import_content.sass +0 -4
- data/test/sass/templates/importee.less +0 -2
- data/test/sass/templates/importee.sass +0 -19
- data/test/sass/templates/line_numbers.sass +0 -13
- data/test/sass/templates/mixin_bork.sass +0 -5
- data/test/sass/templates/mixins.sass +0 -76
- data/test/sass/templates/multiline.sass +0 -20
- data/test/sass/templates/nested.sass +0 -25
- data/test/sass/templates/nested_bork1.sass +0 -2
- data/test/sass/templates/nested_bork2.sass +0 -2
- data/test/sass/templates/nested_bork3.sass +0 -2
- data/test/sass/templates/nested_bork4.sass +0 -2
- data/test/sass/templates/nested_import.sass +0 -2
- data/test/sass/templates/nested_mixin_bork.sass +0 -6
- data/test/sass/templates/options.sass +0 -2
- data/test/sass/templates/parent_ref.sass +0 -25
- 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/script.sass +0 -101
- data/test/sass/templates/scss_import.scss +0 -12
- data/test/sass/templates/scss_importee.scss +0 -1
- data/test/sass/templates/single_import_loop.sass +0 -1
- data/test/sass/templates/subdir/import_up1.scss +0 -1
- data/test/sass/templates/subdir/import_up2.scss +0 -1
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
- data/test/sass/templates/subdir/subdir.sass +0 -6
- data/test/sass/templates/units.sass +0 -11
- data/test/sass/templates/warn.sass +0 -3
- data/test/sass/templates/warn_imported.sass +0 -4
- data/test/sass/test_helper.rb +0 -8
- data/test/sass/util/multibyte_string_scanner_test.rb +0 -155
- data/test/sass/util/normalized_map_test.rb +0 -51
- data/test/sass/util/subset_map_test.rb +0 -91
- data/test/sass/util_test.rb +0 -438
- data/test/sass/value_helpers_test.rb +0 -179
- data/test/test_helper.rb +0 -110
- 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
data/lib/sass/scss/rx.rb
CHANGED
@@ -32,7 +32,7 @@ module Sass
|
|
32
32
|
# @return [String] The escaped character
|
33
33
|
# @private
|
34
34
|
def self.escape_char(c)
|
35
|
-
return "\\%06x" %
|
35
|
+
return "\\%06x" % c.ord unless c =~ %r{[ -/:-~]}
|
36
36
|
"\\#{c}"
|
37
37
|
end
|
38
38
|
|
@@ -50,15 +50,9 @@ module Sass
|
|
50
50
|
H = /[0-9a-fA-F]/
|
51
51
|
NL = /\n|\r\n|\r|\f/
|
52
52
|
UNICODE = /\\#{H}{1,6}[ \t\r\n\f]?/
|
53
|
-
s =
|
54
|
-
'\200-\377'
|
55
|
-
elsif Sass::Util.macruby?
|
56
|
-
'\u0080-\uD7FF\uE000-\uFFFD\U00010000-\U0010FFFF'
|
57
|
-
else
|
58
|
-
'\u{80}-\u{D7FF}\u{E000}-\u{FFFD}\u{10000}-\u{10FFFF}'
|
59
|
-
end
|
53
|
+
s = '\u{80}-\u{D7FF}\u{E000}-\u{FFFD}\u{10000}-\u{10FFFF}'
|
60
54
|
NONASCII = /[#{s}]/
|
61
|
-
ESCAPE = /#{UNICODE}|\\[
|
55
|
+
ESCAPE = /#{UNICODE}|\\[^0-9a-fA-F\r\n\f]/
|
62
56
|
NMSTART = /[_a-zA-Z]|#{NONASCII}|#{ESCAPE}/
|
63
57
|
NMCHAR = /[a-zA-Z0-9_-]|#{NONASCII}|#{ESCAPE}/
|
64
58
|
STRING1 = /\"((?:[^\n\r\f\\"]|\\#{NL}|#{ESCAPE})*)\"/
|
@@ -127,13 +121,13 @@ module Sass
|
|
127
121
|
OPTIONAL = /!#{W}optional/i
|
128
122
|
IDENT_START = /-|#{NMSTART}/
|
129
123
|
|
130
|
-
IDENT_HYPHEN_INTERP =
|
124
|
+
IDENT_HYPHEN_INTERP = /-+(?=#\{)/
|
131
125
|
STRING1_NOINTERP = /\"((?:[^\n\r\f\\"#]|#(?!\{)|#{ESCAPE})*)\"/
|
132
126
|
STRING2_NOINTERP = /\'((?:[^\n\r\f\\'#]|#(?!\{)|#{ESCAPE})*)\'/
|
133
127
|
STRING_NOINTERP = /#{STRING1_NOINTERP}|#{STRING2_NOINTERP}/
|
134
128
|
|
135
129
|
STATIC_COMPONENT = /#{IDENT}|#{STRING_NOINTERP}|#{HEXCOLOR}|[+-]?#{NUMBER}|\!important/i
|
136
|
-
STATIC_VALUE = %r(#{STATIC_COMPONENT}(\s*[\s
|
130
|
+
STATIC_VALUE = %r(#{STATIC_COMPONENT}(\s*[\s,\/]\s*#{STATIC_COMPONENT})*(?=[;}]))i
|
137
131
|
STATIC_SELECTOR = /(#{NMCHAR}|[ \t]|[,>+*]|[:#.]#{NMSTART}){1,50}([{])/i
|
138
132
|
end
|
139
133
|
end
|
@@ -51,10 +51,7 @@ module Sass
|
|
51
51
|
# @see Parser#initialize
|
52
52
|
# @param allow_parent_ref [Boolean] Whether to allow the
|
53
53
|
# parent-reference selector, `&`, when parsing the document.
|
54
|
-
# @comment
|
55
|
-
# rubocop:disable ParameterLists
|
56
54
|
def initialize(str, filename, importer, line = 1, offset = 1, allow_parent_ref = true)
|
57
|
-
# rubocop:enable ParameterLists
|
58
55
|
super(str, filename, importer, line, offset)
|
59
56
|
@allow_parent_ref = allow_parent_ref
|
60
57
|
end
|
@@ -74,7 +71,7 @@ module Sass
|
|
74
71
|
def var_expr; nil; end
|
75
72
|
def interp_string; (s = tok(STRING)) && [s]; end
|
76
73
|
def interp_uri; (s = tok(URI)) && [s]; end
|
77
|
-
def interp_ident
|
74
|
+
def interp_ident; (s = ident) && [s]; end
|
78
75
|
def use_css_import?; true; end
|
79
76
|
|
80
77
|
def special_directive(name, start_pos)
|
@@ -188,25 +185,25 @@ MESSAGE
|
|
188
185
|
|
189
186
|
def parent_selector
|
190
187
|
return unless @allow_parent_ref && tok(/&/)
|
191
|
-
Selector::Parent.new(
|
188
|
+
Selector::Parent.new(name)
|
192
189
|
end
|
193
190
|
|
194
191
|
def class_selector
|
195
192
|
return unless tok(/\./)
|
196
193
|
@expected = "class name"
|
197
|
-
Selector::Class.new(
|
194
|
+
Selector::Class.new(ident!)
|
198
195
|
end
|
199
196
|
|
200
197
|
def id_selector
|
201
198
|
return unless tok(/#(?!\{)/)
|
202
199
|
@expected = "id name"
|
203
|
-
Selector::Id.new(
|
200
|
+
Selector::Id.new(name!)
|
204
201
|
end
|
205
202
|
|
206
203
|
def placeholder_selector
|
207
204
|
return unless tok(/%/)
|
208
205
|
@expected = "placeholder name"
|
209
|
-
Selector::Placeholder.new(
|
206
|
+
Selector::Placeholder.new(ident!)
|
210
207
|
end
|
211
208
|
|
212
209
|
def element_name
|
@@ -221,13 +218,13 @@ MESSAGE
|
|
221
218
|
end
|
222
219
|
|
223
220
|
def qualified_name(allow_star_name = false)
|
224
|
-
name =
|
221
|
+
name = ident || tok(/\*/) || (tok?(/\|/) && "")
|
225
222
|
return unless name
|
226
223
|
return nil, name unless tok(/\|/)
|
227
224
|
|
228
|
-
return name,
|
225
|
+
return name, ident! unless allow_star_name
|
229
226
|
@expected = "identifier or *"
|
230
|
-
return name,
|
227
|
+
return name, ident || tok!(/\*/)
|
231
228
|
end
|
232
229
|
|
233
230
|
def attrib
|
@@ -245,21 +242,21 @@ MESSAGE
|
|
245
242
|
if op
|
246
243
|
@expected = "identifier or string"
|
247
244
|
ss
|
248
|
-
val =
|
245
|
+
val = ident || tok!(STRING)
|
249
246
|
ss
|
250
247
|
end
|
251
|
-
flags =
|
248
|
+
flags = ident || tok(STRING)
|
252
249
|
tok!(/\]/)
|
253
250
|
|
254
251
|
Selector::Attribute.new(name, ns, op, val, flags)
|
255
252
|
end
|
256
253
|
|
257
254
|
def attrib_name!
|
258
|
-
if (name_or_ns =
|
255
|
+
if (name_or_ns = ident)
|
259
256
|
# E, E|E
|
260
257
|
if tok(/\|(?!=)/)
|
261
258
|
ns = name_or_ns
|
262
|
-
name =
|
259
|
+
name = ident
|
263
260
|
else
|
264
261
|
name = name_or_ns
|
265
262
|
end
|
@@ -267,7 +264,7 @@ MESSAGE
|
|
267
264
|
# *|E or |E
|
268
265
|
ns = tok(/\*/) || ""
|
269
266
|
tok!(/\|/)
|
270
|
-
name =
|
267
|
+
name = ident!
|
271
268
|
end
|
272
269
|
return ns, name
|
273
270
|
end
|
@@ -276,11 +273,13 @@ MESSAGE
|
|
276
273
|
|
277
274
|
PREFIXED_SELECTOR_PSEUDO_CLASSES = %w(nth-child nth-last-child).to_set
|
278
275
|
|
276
|
+
SELECTOR_PSEUDO_ELEMENTS = %w(slotted).to_set
|
277
|
+
|
279
278
|
def pseudo
|
280
279
|
s = tok(/::?/)
|
281
280
|
return unless s
|
282
281
|
@expected = "pseudoclass or pseudoelement"
|
283
|
-
name =
|
282
|
+
name = ident!
|
284
283
|
if tok(/\(/)
|
285
284
|
ss
|
286
285
|
deprefixed = deprefix(name)
|
@@ -288,8 +287,10 @@ MESSAGE
|
|
288
287
|
sel = selector_comma_sequence
|
289
288
|
elsif s == ':' && PREFIXED_SELECTOR_PSEUDO_CLASSES.include?(deprefixed)
|
290
289
|
arg, sel = prefixed_selector_pseudo
|
290
|
+
elsif s == '::' && SELECTOR_PSEUDO_ELEMENTS.include?(deprefixed)
|
291
|
+
sel = selector_comma_sequence
|
291
292
|
else
|
292
|
-
arg = expr!(:
|
293
|
+
arg = expr!(:declaration_value).join
|
293
294
|
end
|
294
295
|
|
295
296
|
tok!(/\)/)
|
@@ -297,29 +298,6 @@ MESSAGE
|
|
297
298
|
Selector::Pseudo.new(s == ':' ? :class : :element, name, arg, sel)
|
298
299
|
end
|
299
300
|
|
300
|
-
def pseudo_args
|
301
|
-
arg = expr!(:pseudo_expr)
|
302
|
-
while tok(/,/)
|
303
|
-
arg << ',' << str {ss}
|
304
|
-
arg.concat expr!(:pseudo_expr)
|
305
|
-
end
|
306
|
-
arg
|
307
|
-
end
|
308
|
-
|
309
|
-
def pseudo_expr
|
310
|
-
res = pseudo_expr_token
|
311
|
-
return unless res
|
312
|
-
res << str {ss}
|
313
|
-
while (e = pseudo_expr_token)
|
314
|
-
res << e << str {ss}
|
315
|
-
end
|
316
|
-
res
|
317
|
-
end
|
318
|
-
|
319
|
-
def pseudo_expr_token
|
320
|
-
tok(PLUS) || tok(/[-*]/) || tok(NUMBER) || tok(STRING) || tok(IDENT)
|
321
|
-
end
|
322
|
-
|
323
301
|
def prefixed_selector_pseudo
|
324
302
|
prefix = str do
|
325
303
|
expr = str {expr!(:a_n_plus_b)}
|
@@ -364,7 +342,7 @@ MESSAGE
|
|
364
342
|
end
|
365
343
|
|
366
344
|
def keyframes_selector_component
|
367
|
-
|
345
|
+
ident || tok(PERCENTAGE)
|
368
346
|
end
|
369
347
|
|
370
348
|
@sass_script_parser = Class.new(Sass::Script::CssParser)
|
data/lib/sass/selector.rb
CHANGED
@@ -59,12 +59,11 @@ module Sass
|
|
59
59
|
end
|
60
60
|
alias_method :==, :eql?
|
61
61
|
|
62
|
-
# Whether or not this selector
|
63
|
-
#
|
64
|
-
def
|
65
|
-
@
|
66
|
-
next m.
|
67
|
-
next m.selector && m.selector.has_placeholder? if m.is_a?(Pseudo)
|
62
|
+
# Whether or not this selector should be hidden due to containing a
|
63
|
+
# placeholder.
|
64
|
+
def invisible?
|
65
|
+
@invisible ||= members.any? do |m|
|
66
|
+
next m.invisible? if m.is_a?(AbstractSequence) || m.is_a?(Pseudo)
|
68
67
|
m.is_a?(Placeholder)
|
69
68
|
end
|
70
69
|
end
|
@@ -73,6 +72,8 @@ module Sass
|
|
73
72
|
#
|
74
73
|
# @param opts [Hash] rendering options.
|
75
74
|
# @option opts [Symbol] :style The css rendering style.
|
75
|
+
# @option placeholders [Boolean] :placeholders
|
76
|
+
# Whether to include placeholder selectors. Defaults to `true`.
|
76
77
|
# @return [String]
|
77
78
|
def to_s(opts = {})
|
78
79
|
Sass::Util.abstract(self)
|
@@ -119,7 +119,8 @@ module Sass
|
|
119
119
|
if !allow_compound_target && sel.length > 1
|
120
120
|
@@compound_extend_deprecation.warn(sseq.filename, sseq.line, <<WARNING)
|
121
121
|
Extending a compound selector, #{sseq}, is deprecated and will not be supported in a future release.
|
122
|
-
|
122
|
+
Consider "@extend #{sseq.members.join(', ')}" instead.
|
123
|
+
See http://bit.ly/ExtendCompound for details.
|
123
124
|
WARNING
|
124
125
|
end
|
125
126
|
|
@@ -129,7 +130,7 @@ WARNING
|
|
129
130
|
end
|
130
131
|
|
131
132
|
extends[sel] = Sass::Tree::Visitors::Cssize::Extend.new(
|
132
|
-
member, sel, extend_node, parent_directives,
|
133
|
+
member, sel, extend_node, parent_directives, false)
|
133
134
|
end
|
134
135
|
end
|
135
136
|
end
|
@@ -158,8 +159,8 @@ WARNING
|
|
158
159
|
Sass::Script::Value::List.new(seq.members.map do |component|
|
159
160
|
next if component == "\n"
|
160
161
|
Sass::Script::Value::String.new(component.to_s)
|
161
|
-
end.compact, :space)
|
162
|
-
end, :comma)
|
162
|
+
end.compact, separator: :space)
|
163
|
+
end, separator: :comma)
|
163
164
|
end
|
164
165
|
|
165
166
|
# Returns a string representation of the sequence.
|
@@ -172,7 +173,10 @@ WARNING
|
|
172
173
|
|
173
174
|
# @see AbstractSequence#to_s
|
174
175
|
def to_s(opts = {})
|
175
|
-
@members.map
|
176
|
+
@members.map do |m|
|
177
|
+
next if opts[:placeholder] == false && m.invisible?
|
178
|
+
m.to_s(opts)
|
179
|
+
end.compact.
|
176
180
|
join(opts[:style] == :compressed ? "," : ", ").
|
177
181
|
gsub(", \n", ",\n")
|
178
182
|
end
|
data/lib/sass/selector/pseudo.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# coding: utf-8
|
1
2
|
module Sass
|
2
3
|
module Selector
|
3
4
|
# A pseudoclass (e.g. `:visited`) or pseudoelement (e.g. `::first-line`)
|
@@ -48,6 +49,18 @@ module Sass
|
|
48
49
|
@selector = selector
|
49
50
|
end
|
50
51
|
|
52
|
+
def unique?
|
53
|
+
type == :class && normalized_name == 'root'
|
54
|
+
end
|
55
|
+
|
56
|
+
# Whether or not this selector should be hidden due to containing a
|
57
|
+
# placeholder.
|
58
|
+
def invisible?
|
59
|
+
# :not() is a special case—if you eliminate all the placeholders from
|
60
|
+
# it, it should match anything.
|
61
|
+
name != 'not' && @selector && @selector.members.all? {|s| s.invisible?}
|
62
|
+
end
|
63
|
+
|
51
64
|
# Returns a copy of this with \{#selector} set to \{#new\_selector}.
|
52
65
|
#
|
53
66
|
# @param new_selector [CommaSequence]
|
@@ -77,7 +90,7 @@ module Sass
|
|
77
90
|
# more complex cases that likely aren't worth the pain.
|
78
91
|
next [] unless sel.name == name && sel.arg == arg
|
79
92
|
sel.selector.members
|
80
|
-
when 'has', 'host', 'host-context'
|
93
|
+
when 'has', 'host', 'host-context', 'slotted'
|
81
94
|
# We can't expand nested selectors here, because each layer adds an
|
82
95
|
# additional layer of semantics. For example, `:has(:has(img))`
|
83
96
|
# doesn't match `<div><img></div>` but `:has(img)` does.
|
@@ -114,10 +127,14 @@ module Sass
|
|
114
127
|
|
115
128
|
# @see Selector#to_s
|
116
129
|
def to_s(opts = {})
|
130
|
+
# :not() is a special case, because :not(<nothing>) should match
|
131
|
+
# everything.
|
132
|
+
return '' if name == 'not' && @selector && @selector.members.all? {|m| m.invisible?}
|
133
|
+
|
117
134
|
res = (syntactic_type == :class ? ":" : "::") + @name
|
118
135
|
if @arg || @selector
|
119
136
|
res << "("
|
120
|
-
res << @arg
|
137
|
+
res << Sass::Util.strip_except_escapes(@arg) if @arg
|
121
138
|
res << " " if @arg && @selector
|
122
139
|
res << @selector.to_s(opts) if @selector
|
123
140
|
res << ")"
|
@@ -161,7 +178,7 @@ module Sass
|
|
161
178
|
their_seq = Sequence.new(parents + [their_sseq])
|
162
179
|
our_seq.superselector?(their_seq)
|
163
180
|
end
|
164
|
-
when 'has', 'host', 'host-context'
|
181
|
+
when 'has', 'host', 'host-context', 'slotted'
|
165
182
|
# Like :matches, :has (et al) can be a superselector of another
|
166
183
|
# selector if its constituent selectors are a superset of those of
|
167
184
|
# another :has in the other selector. However, the :matches other case
|
@@ -66,10 +66,14 @@ module Sass
|
|
66
66
|
next [sseq_or_op] unless sseq_or_op.is_a?(SimpleSequence)
|
67
67
|
sseq_or_op.resolve_parent_refs(super_cseq).members
|
68
68
|
end).map do |path|
|
69
|
-
|
69
|
+
path_members = path.map do |seq_or_op|
|
70
70
|
next seq_or_op unless seq_or_op.is_a?(Sequence)
|
71
71
|
seq_or_op.members
|
72
|
-
end
|
72
|
+
end
|
73
|
+
if path_members.length == 2 && path_members[1][0] == "\n"
|
74
|
+
path_members[0].unshift path_members[1].shift
|
75
|
+
end
|
76
|
+
Sequence.new(path_members.flatten)
|
73
77
|
end)
|
74
78
|
end
|
75
79
|
|
@@ -115,7 +119,7 @@ module Sass
|
|
115
119
|
# specificity greater than or equal to that of the original selector.
|
116
120
|
# In order to ensure that, we record the original selector's
|
117
121
|
# (`extended.first`) original specificity.
|
118
|
-
extended.first.add_sources!([self]) if original && !
|
122
|
+
extended.first.add_sources!([self]) if original && !invisible?
|
119
123
|
|
120
124
|
extended.map {|seq| seq.members}
|
121
125
|
end
|
@@ -283,6 +287,9 @@ module Sass
|
|
283
287
|
next unless s1.first.is_a?(SimpleSequence) && s2.first.is_a?(SimpleSequence)
|
284
288
|
next s2 if parent_superselector?(s1, s2)
|
285
289
|
next s1 if parent_superselector?(s2, s1)
|
290
|
+
next unless must_unify?(s1, s2)
|
291
|
+
next unless (unified = Sequence.new(s1).unify(Sequence.new(s2)))
|
292
|
+
unified.members.first.members if unified.members.length == 1
|
286
293
|
end
|
287
294
|
|
288
295
|
diff = [[init]]
|
@@ -337,8 +344,6 @@ module Sass
|
|
337
344
|
# be nil. Otherwise, this will contained the merged selector. Array
|
338
345
|
# elements are [Sass::Util#paths]-style options; conceptually, an "or"
|
339
346
|
# of multiple selectors.
|
340
|
-
# @comment
|
341
|
-
# rubocop:disable MethodLength
|
342
347
|
def merge_final_ops(seq1, seq2, res = [])
|
343
348
|
ops1, ops2 = [], []
|
344
349
|
ops1 << seq1.pop while seq1.last.is_a?(String)
|
@@ -420,8 +425,6 @@ module Sass
|
|
420
425
|
return merge_final_ops(seq1, seq2, res)
|
421
426
|
end
|
422
427
|
end
|
423
|
-
# @comment
|
424
|
-
# rubocop:enable MethodLength
|
425
428
|
|
426
429
|
# Takes initial subsequences of `seq1` and `seq2` and returns all
|
427
430
|
# orderings of those subsequences. The initial subsequences are determined
|
@@ -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
|
@@ -597,8 +624,6 @@ module Sass
|
|
597
624
|
other.members.reject {|m| m == "\n"}.eql?(members.reject {|m| m == "\n"})
|
598
625
|
end
|
599
626
|
|
600
|
-
private
|
601
|
-
|
602
627
|
def path_has_two_subjects?(path)
|
603
628
|
subject = false
|
604
629
|
path.each do |sseq_or_op|
|
data/lib/sass/selector/simple.rb
CHANGED
@@ -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]
|
@@ -74,9 +82,8 @@ module Sass
|
|
74
82
|
def unify(sels)
|
75
83
|
return sels.first.unify([self]) if sels.length == 1 && sels.first.is_a?(Universal)
|
76
84
|
return sels if sels.any? {|sel2| eql?(sel2)}
|
77
|
-
sels_with_ix = Sass::Util.enum_with_index(sels)
|
78
85
|
if !is_a?(Pseudo) || (sels.last.is_a?(Pseudo) && sels.last.type == :element)
|
79
|
-
_, i =
|
86
|
+
_, i = sels.each_with_index.find {|sel, _| sel.is_a?(Pseudo)}
|
80
87
|
end
|
81
88
|
return sels + [self] unless i
|
82
89
|
sels[0...i] + [self] + sels[i..-1]
|