sass 3.4.25 → 3.7.4
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.
- 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]
|