sass 3.4.24 → 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/cache_stores/filesystem.rb +1 -1
- data/lib/sass/css.rb +2 -3
- data/lib/sass/deprecation.rb +55 -0
- data/lib/sass/engine.rb +52 -34
- data/lib/sass/environment.rb +27 -6
- 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 +21 -51
- data/lib/sass/plugin/configuration.rb +2 -2
- data/lib/sass/plugin/rack.rb +2 -2
- data/lib/sass/plugin/staleness_checker.rb +1 -1
- data/lib/sass/plugin.rb +1 -1
- data/lib/sass/railtie.rb +1 -1
- data/lib/sass/script/css_parser.rb +4 -1
- data/lib/sass/script/functions.rb +310 -83
- data/lib/sass/script/lexer.rb +64 -10
- data/lib/sass/script/parser.rb +291 -121
- 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 +1 -9
- data/lib/sass/script/tree/operation.rb +43 -23
- data/lib/sass/script/value/arg_list.rb +1 -1
- data/lib/sass/script/value/base.rb +18 -1
- 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/script/value/string.rb +5 -12
- data/lib/sass/script/value.rb +2 -0
- data/lib/sass/script.rb +1 -1
- 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 +27 -42
- data/lib/sass/selector/abstract_sequence.rb +7 -6
- data/lib/sass/selector/comma_sequence.rb +21 -5
- data/lib/sass/selector/pseudo.rb +20 -3
- data/lib/sass/selector/sequence.rb +35 -10
- data/lib/sass/selector/simple.rb +10 -2
- data/lib/sass/selector/simple_sequence.rb +8 -4
- data/lib/sass/selector.rb +4 -0
- 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/node.rb +2 -2
- data/lib/sass/tree/prop_node.rb +45 -53
- data/lib/sass/tree/rule_node.rb +13 -6
- 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 +2 -2
- data/lib/sass/tree/visitors/extend.rb +2 -8
- data/lib/sass/tree/visitors/perform.rb +26 -17
- data/lib/sass/tree/visitors/set_options.rb +1 -1
- data/lib/sass/tree/visitors/to_css.rb +49 -22
- data/lib/sass/util/multibyte_string_scanner.rb +127 -131
- data/lib/sass/util/normalized_map.rb +1 -8
- data/lib/sass/util.rb +72 -310
- data/lib/sass/version.rb +0 -4
- data/lib/sass.rb +3 -10
- metadata +60 -206
- data/Rakefile +0 -424
- 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/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 -3441
- data/test/sass/exec_test.rb +0 -96
- data/test/sass/extend_test.rb +0 -1727
- 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 -1974
- 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 -1422
- 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 -4190
- 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 -147
- 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/sass-spec.yml +0 -3
- 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/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/lib/listen.rb +0 -54
- 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
@@ -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)
|
@@ -144,6 +141,13 @@ MESSAGE
|
|
144
141
|
ns, name = expr!(:qualified_name)
|
145
142
|
res << ns << '|' if ns
|
146
143
|
res << name << tok!(%r{/})
|
144
|
+
|
145
|
+
location = " of #{@filename}" if @filename
|
146
|
+
Sass::Util.sass_warn <<MESSAGE
|
147
|
+
DEPRECATION WARNING on line #{@line}, column #{@offset}#{location}:
|
148
|
+
The reference combinator #{res} is deprecated and will be removed in a future release.
|
149
|
+
MESSAGE
|
150
|
+
|
147
151
|
res
|
148
152
|
end
|
149
153
|
|
@@ -181,25 +185,25 @@ MESSAGE
|
|
181
185
|
|
182
186
|
def parent_selector
|
183
187
|
return unless @allow_parent_ref && tok(/&/)
|
184
|
-
Selector::Parent.new(
|
188
|
+
Selector::Parent.new(name)
|
185
189
|
end
|
186
190
|
|
187
191
|
def class_selector
|
188
192
|
return unless tok(/\./)
|
189
193
|
@expected = "class name"
|
190
|
-
Selector::Class.new(
|
194
|
+
Selector::Class.new(ident!)
|
191
195
|
end
|
192
196
|
|
193
197
|
def id_selector
|
194
198
|
return unless tok(/#(?!\{)/)
|
195
199
|
@expected = "id name"
|
196
|
-
Selector::Id.new(
|
200
|
+
Selector::Id.new(name!)
|
197
201
|
end
|
198
202
|
|
199
203
|
def placeholder_selector
|
200
204
|
return unless tok(/%/)
|
201
205
|
@expected = "placeholder name"
|
202
|
-
Selector::Placeholder.new(
|
206
|
+
Selector::Placeholder.new(ident!)
|
203
207
|
end
|
204
208
|
|
205
209
|
def element_name
|
@@ -214,13 +218,13 @@ MESSAGE
|
|
214
218
|
end
|
215
219
|
|
216
220
|
def qualified_name(allow_star_name = false)
|
217
|
-
name =
|
221
|
+
name = ident || tok(/\*/) || (tok?(/\|/) && "")
|
218
222
|
return unless name
|
219
223
|
return nil, name unless tok(/\|/)
|
220
224
|
|
221
|
-
return name,
|
225
|
+
return name, ident! unless allow_star_name
|
222
226
|
@expected = "identifier or *"
|
223
|
-
return name,
|
227
|
+
return name, ident || tok!(/\*/)
|
224
228
|
end
|
225
229
|
|
226
230
|
def attrib
|
@@ -238,21 +242,21 @@ MESSAGE
|
|
238
242
|
if op
|
239
243
|
@expected = "identifier or string"
|
240
244
|
ss
|
241
|
-
val =
|
245
|
+
val = ident || tok!(STRING)
|
242
246
|
ss
|
243
247
|
end
|
244
|
-
flags =
|
248
|
+
flags = ident || tok(STRING)
|
245
249
|
tok!(/\]/)
|
246
250
|
|
247
251
|
Selector::Attribute.new(name, ns, op, val, flags)
|
248
252
|
end
|
249
253
|
|
250
254
|
def attrib_name!
|
251
|
-
if (name_or_ns =
|
255
|
+
if (name_or_ns = ident)
|
252
256
|
# E, E|E
|
253
257
|
if tok(/\|(?!=)/)
|
254
258
|
ns = name_or_ns
|
255
|
-
name =
|
259
|
+
name = ident
|
256
260
|
else
|
257
261
|
name = name_or_ns
|
258
262
|
end
|
@@ -260,7 +264,7 @@ MESSAGE
|
|
260
264
|
# *|E or |E
|
261
265
|
ns = tok(/\*/) || ""
|
262
266
|
tok!(/\|/)
|
263
|
-
name =
|
267
|
+
name = ident!
|
264
268
|
end
|
265
269
|
return ns, name
|
266
270
|
end
|
@@ -269,11 +273,13 @@ MESSAGE
|
|
269
273
|
|
270
274
|
PREFIXED_SELECTOR_PSEUDO_CLASSES = %w(nth-child nth-last-child).to_set
|
271
275
|
|
276
|
+
SELECTOR_PSEUDO_ELEMENTS = %w(slotted).to_set
|
277
|
+
|
272
278
|
def pseudo
|
273
279
|
s = tok(/::?/)
|
274
280
|
return unless s
|
275
281
|
@expected = "pseudoclass or pseudoelement"
|
276
|
-
name =
|
282
|
+
name = ident!
|
277
283
|
if tok(/\(/)
|
278
284
|
ss
|
279
285
|
deprefixed = deprefix(name)
|
@@ -281,8 +287,10 @@ MESSAGE
|
|
281
287
|
sel = selector_comma_sequence
|
282
288
|
elsif s == ':' && PREFIXED_SELECTOR_PSEUDO_CLASSES.include?(deprefixed)
|
283
289
|
arg, sel = prefixed_selector_pseudo
|
290
|
+
elsif s == '::' && SELECTOR_PSEUDO_ELEMENTS.include?(deprefixed)
|
291
|
+
sel = selector_comma_sequence
|
284
292
|
else
|
285
|
-
arg = expr!(:
|
293
|
+
arg = expr!(:declaration_value).join
|
286
294
|
end
|
287
295
|
|
288
296
|
tok!(/\)/)
|
@@ -290,29 +298,6 @@ MESSAGE
|
|
290
298
|
Selector::Pseudo.new(s == ':' ? :class : :element, name, arg, sel)
|
291
299
|
end
|
292
300
|
|
293
|
-
def pseudo_args
|
294
|
-
arg = expr!(:pseudo_expr)
|
295
|
-
while tok(/,/)
|
296
|
-
arg << ',' << str {ss}
|
297
|
-
arg.concat expr!(:pseudo_expr)
|
298
|
-
end
|
299
|
-
arg
|
300
|
-
end
|
301
|
-
|
302
|
-
def pseudo_expr
|
303
|
-
res = pseudo_expr_token
|
304
|
-
return unless res
|
305
|
-
res << str {ss}
|
306
|
-
while (e = pseudo_expr_token)
|
307
|
-
res << e << str {ss}
|
308
|
-
end
|
309
|
-
res
|
310
|
-
end
|
311
|
-
|
312
|
-
def pseudo_expr_token
|
313
|
-
tok(PLUS) || tok(/[-*]/) || tok(NUMBER) || tok(STRING) || tok(IDENT)
|
314
|
-
end
|
315
|
-
|
316
301
|
def prefixed_selector_pseudo
|
317
302
|
prefix = str do
|
318
303
|
expr = str {expr!(:a_n_plus_b)}
|
@@ -357,7 +342,7 @@ MESSAGE
|
|
357
342
|
end
|
358
343
|
|
359
344
|
def keyframes_selector_component
|
360
|
-
|
345
|
+
ident || tok(PERCENTAGE)
|
361
346
|
end
|
362
347
|
|
363
348
|
@sass_script_parser = Class.new(Sass::Script::CssParser)
|
@@ -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)
|
@@ -2,6 +2,8 @@ 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
|
+
|
5
7
|
# The comma-separated selector sequences
|
6
8
|
# represented by this class.
|
7
9
|
#
|
@@ -96,8 +98,11 @@ module Sass
|
|
96
98
|
# The node that caused this extension.
|
97
99
|
# @param parent_directives [Array<Sass::Tree::DirectiveNode>]
|
98
100
|
# The parent directives containing `extend_node`.
|
101
|
+
# @param allow_compound_target [Boolean]
|
102
|
+
# Whether `extendee` is allowed to contain compound selectors.
|
99
103
|
# @raise [Sass::SyntaxError] if this extension is invalid.
|
100
|
-
def populate_extends(extends, extendee, extend_node = nil, parent_directives = []
|
104
|
+
def populate_extends(extends, extendee, extend_node = nil, parent_directives = [],
|
105
|
+
allow_compound_target = false)
|
101
106
|
extendee.members.each do |seq|
|
102
107
|
if seq.members.size > 1
|
103
108
|
raise Sass::SyntaxError.new("Can't extend #{seq}: can't extend nested selectors")
|
@@ -111,13 +116,21 @@ module Sass
|
|
111
116
|
end
|
112
117
|
|
113
118
|
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
|
+
Consider "@extend #{sseq.members.join(', ')}" instead.
|
123
|
+
See http://bit.ly/ExtendCompound for details.
|
124
|
+
WARNING
|
125
|
+
end
|
126
|
+
|
114
127
|
members.each do |member|
|
115
128
|
unless member.members.last.is_a?(Sass::Selector::SimpleSequence)
|
116
129
|
raise Sass::SyntaxError.new("#{member} can't extend: invalid selector")
|
117
130
|
end
|
118
131
|
|
119
132
|
extends[sel] = Sass::Tree::Visitors::Cssize::Extend.new(
|
120
|
-
member, sel, extend_node, parent_directives,
|
133
|
+
member, sel, extend_node, parent_directives, false)
|
121
134
|
end
|
122
135
|
end
|
123
136
|
end
|
@@ -146,8 +159,8 @@ module Sass
|
|
146
159
|
Sass::Script::Value::List.new(seq.members.map do |component|
|
147
160
|
next if component == "\n"
|
148
161
|
Sass::Script::Value::String.new(component.to_s)
|
149
|
-
end.compact, :space)
|
150
|
-
end, :comma)
|
162
|
+
end.compact, separator: :space)
|
163
|
+
end, separator: :comma)
|
151
164
|
end
|
152
165
|
|
153
166
|
# Returns a string representation of the sequence.
|
@@ -160,7 +173,10 @@ module Sass
|
|
160
173
|
|
161
174
|
# @see AbstractSequence#to_s
|
162
175
|
def to_s(opts = {})
|
163
|
-
@members.map
|
176
|
+
@members.map do |m|
|
177
|
+
next if opts[:placeholder] == false && m.invisible?
|
178
|
+
m.to_s(opts)
|
179
|
+
end.compact.
|
164
180
|
join(opts[:style] == :compressed ? "," : ", ").
|
165
181
|
gsub(", \n", ",\n")
|
166
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]
|
@@ -72,10 +80,10 @@ 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)
|
83
|
+
return sels.first.unify([self]) if sels.length == 1 && sels.first.is_a?(Universal)
|
75
84
|
return sels if sels.any? {|sel2| eql?(sel2)}
|
76
|
-
sels_with_ix = Sass::Util.enum_with_index(sels)
|
77
85
|
if !is_a?(Pseudo) || (sels.last.is_a?(Pseudo) && sels.last.type == :element)
|
78
|
-
_, i =
|
86
|
+
_, i = sels.each_with_index.find {|sel, _| sel.is_a?(Pseudo)}
|
79
87
|
end
|
80
88
|
return sels + [self] unless i
|
81
89
|
sels[0...i] + [self] + sels[i..-1]
|
@@ -163,7 +163,7 @@ module Sass
|
|
163
163
|
next sel if seen.include?([sel])
|
164
164
|
extended = sel.selector.do_extend(extends, parent_directives, replace, seen, false)
|
165
165
|
next sel if extended == sel.selector
|
166
|
-
extended.members.reject! {|seq| seq.
|
166
|
+
extended.members.reject! {|seq| seq.invisible?}
|
167
167
|
|
168
168
|
# For `:not()`, we usually want to get rid of any complex
|
169
169
|
# selectors because that will cause the selector to fail to
|
@@ -184,17 +184,16 @@ 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 {...},
|
191
191
|
# seq is A, sels is B, and self is C
|
192
192
|
|
193
193
|
self_without_sel = Sass::Util.array_minus(members, sels)
|
194
|
-
group.each {|e| e.
|
194
|
+
group.each {|e| e.success = true}
|
195
195
|
unified = seq.members.last.unify(SimpleSequence.new(self_without_sel, subject?))
|
196
196
|
next unless unified
|
197
|
-
group.each {|e| e.result = :succeeded}
|
198
197
|
group.each {|e| check_directives_match!(e, parent_directives)}
|
199
198
|
new_seq = Sequence.new(seq.members[0...-1] + [unified])
|
200
199
|
new_seq.add_sources!(sources + [seq])
|
@@ -287,6 +286,11 @@ module Sass
|
|
287
286
|
# @see Simple#to_s
|
288
287
|
def to_s(opts = {})
|
289
288
|
res = @members.map {|m| m.to_s(opts)}.join
|
289
|
+
|
290
|
+
# :not(%foo) may resolve to the empty string, but it should match every
|
291
|
+
# selector so we replace it with "*".
|
292
|
+
res = '*' if res.empty?
|
293
|
+
|
290
294
|
res << '!' if subject?
|
291
295
|
res
|
292
296
|
end
|
data/lib/sass/selector.rb
CHANGED
data/lib/sass/source/map.rb
CHANGED
@@ -84,8 +84,6 @@ module Sass::Source
|
|
84
84
|
# @return [String] The JSON string.
|
85
85
|
# @raise [ArgumentError] If neither `:css_uri` nor `:css_path` and
|
86
86
|
# `:sourcemap_path` are specified.
|
87
|
-
# @comment
|
88
|
-
# rubocop:disable MethodLength
|
89
87
|
def to_json(options)
|
90
88
|
css_uri, css_path, sourcemap_path =
|
91
89
|
options[:css_uri], options[:css_path], options[:sourcemap_path]
|
@@ -93,8 +91,8 @@ module Sass::Source
|
|
93
91
|
raise ArgumentError.new("Sass::Source::Map#to_json requires either " \
|
94
92
|
"the :css_uri option or both the :css_path and :soucemap_path options.")
|
95
93
|
end
|
96
|
-
css_path &&= Sass::Util.pathname(
|
97
|
-
sourcemap_path &&= Sass::Util.pathname(
|
94
|
+
css_path &&= Sass::Util.pathname(File.absolute_path(css_path))
|
95
|
+
sourcemap_path &&= Sass::Util.pathname(File.absolute_path(sourcemap_path))
|
98
96
|
css_uri ||= Sass::Util.file_uri_from_path(
|
99
97
|
Sass::Util.relative_path_from(css_path, sourcemap_path.dirname))
|
100
98
|
|
@@ -197,8 +195,6 @@ module Sass::Source
|
|
197
195
|
result << "\n}"
|
198
196
|
result
|
199
197
|
end
|
200
|
-
# @comment
|
201
|
-
# rubocop:enable MethodLength
|
202
198
|
|
203
199
|
private
|
204
200
|
|
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
@@ -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
|