sass 3.3.14 → 3.4.0.rc.1
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/MIT-LICENSE +1 -1
- data/README.md +5 -5
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/bin/sass +1 -1
- data/bin/scss +1 -1
- data/lib/sass.rb +0 -5
- data/lib/sass/css.rb +1 -3
- data/lib/sass/engine.rb +28 -39
- data/lib/sass/environment.rb +13 -17
- data/lib/sass/error.rb +6 -9
- data/lib/sass/exec.rb +5 -771
- data/lib/sass/exec/base.rb +187 -0
- data/lib/sass/exec/sass_convert.rb +264 -0
- data/lib/sass/exec/sass_scss.rb +419 -0
- data/lib/sass/features.rb +6 -0
- data/lib/sass/importers.rb +0 -1
- data/lib/sass/importers/base.rb +5 -1
- data/lib/sass/importers/filesystem.rb +4 -21
- data/lib/sass/media.rb +1 -4
- data/lib/sass/plugin/compiler.rb +32 -136
- data/lib/sass/script/css_lexer.rb +1 -1
- data/lib/sass/script/functions.rb +363 -39
- data/lib/sass/script/lexer.rb +68 -50
- data/lib/sass/script/parser.rb +29 -14
- data/lib/sass/script/tree.rb +1 -0
- data/lib/sass/script/tree/funcall.rb +1 -1
- data/lib/sass/script/tree/interpolation.rb +19 -1
- data/lib/sass/script/tree/selector.rb +26 -0
- data/lib/sass/script/value.rb +0 -1
- data/lib/sass/script/value/bool.rb +0 -5
- data/lib/sass/script/value/color.rb +32 -12
- data/lib/sass/script/value/helpers.rb +107 -0
- data/lib/sass/script/value/list.rb +0 -15
- data/lib/sass/script/value/null.rb +0 -5
- data/lib/sass/script/value/number.rb +60 -14
- data/lib/sass/script/value/string.rb +53 -9
- data/lib/sass/scss/css_parser.rb +8 -2
- data/lib/sass/scss/parser.rb +175 -319
- data/lib/sass/scss/rx.rb +14 -5
- data/lib/sass/scss/static_parser.rb +298 -1
- data/lib/sass/selector.rb +56 -193
- data/lib/sass/selector/abstract_sequence.rb +28 -13
- data/lib/sass/selector/comma_sequence.rb +91 -12
- data/lib/sass/selector/pseudo.rb +256 -0
- data/lib/sass/selector/sequence.rb +99 -31
- data/lib/sass/selector/simple.rb +14 -25
- data/lib/sass/selector/simple_sequence.rb +101 -37
- data/lib/sass/shared.rb +1 -1
- data/lib/sass/source/map.rb +23 -9
- data/lib/sass/stack.rb +0 -6
- data/lib/sass/supports.rb +1 -1
- data/lib/sass/tree/at_root_node.rb +1 -0
- data/lib/sass/tree/directive_node.rb +7 -1
- data/lib/sass/tree/error_node.rb +18 -0
- data/lib/sass/tree/keyframe_rule_node.rb +15 -0
- data/lib/sass/tree/prop_node.rb +1 -1
- data/lib/sass/tree/rule_node.rb +11 -6
- data/lib/sass/tree/visitors/check_nesting.rb +3 -4
- data/lib/sass/tree/visitors/convert.rb +8 -17
- data/lib/sass/tree/visitors/cssize.rb +12 -24
- data/lib/sass/tree/visitors/deep_copy.rb +5 -0
- data/lib/sass/tree/visitors/perform.rb +43 -28
- data/lib/sass/tree/visitors/set_options.rb +5 -0
- data/lib/sass/tree/visitors/to_css.rb +14 -13
- data/lib/sass/util.rb +94 -90
- data/test/sass/cache_test.rb +1 -1
- data/test/sass/callbacks_test.rb +1 -1
- data/test/sass/compiler_test.rb +5 -14
- data/test/sass/conversion_test.rb +47 -1
- data/test/sass/css2sass_test.rb +3 -3
- data/test/sass/encoding_test.rb +219 -0
- data/test/sass/engine_test.rb +128 -191
- data/test/sass/exec_test.rb +2 -2
- data/test/sass/extend_test.rb +234 -17
- data/test/sass/functions_test.rb +268 -213
- data/test/sass/importer_test.rb +31 -21
- data/test/sass/logger_test.rb +1 -1
- data/test/sass/more_results/more_import.css +1 -1
- data/test/sass/plugin_test.rb +12 -11
- data/test/sass/results/compact.css +1 -1
- data/test/sass/results/complex.css +4 -4
- data/test/sass/results/expanded.css +1 -1
- data/test/sass/results/import.css +1 -1
- data/test/sass/results/import_charset_ibm866.css +2 -2
- data/test/sass/results/mixins.css +17 -17
- data/test/sass/results/nested.css +1 -1
- data/test/sass/results/parent_ref.css +2 -2
- data/test/sass/results/script.css +3 -3
- data/test/sass/results/scss_import.css +1 -1
- data/test/sass/script_conversion_test.rb +7 -4
- data/test/sass/script_test.rb +202 -79
- data/test/sass/scss/css_test.rb +95 -25
- data/test/sass/scss/rx_test.rb +4 -4
- data/test/sass/scss/scss_test.rb +363 -19
- data/test/sass/source_map_test.rb +48 -41
- data/test/sass/superselector_test.rb +191 -0
- data/test/sass/templates/scss_import.scss +2 -1
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
- data/test/sass/util/normalized_map_test.rb +1 -1
- data/test/sass/util/subset_map_test.rb +2 -2
- data/test/sass/util_test.rb +1 -1
- data/test/sass/value_helpers_test.rb +3 -3
- data/test/test_helper.rb +2 -2
- metadata +30 -7
- data/lib/sass/importers/deprecated_path.rb +0 -51
- data/lib/sass/script/value/deprecated_false.rb +0 -55
data/lib/sass/scss/rx.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
1
2
|
module Sass
|
2
3
|
module SCSS
|
3
4
|
# A module containing regular expressions used
|
@@ -63,9 +64,9 @@ module Sass
|
|
63
64
|
STRING1 = /\"((?:[^\n\r\f\\"]|\\#{NL}|#{ESCAPE})*)\"/
|
64
65
|
STRING2 = /\'((?:[^\n\r\f\\']|\\#{NL}|#{ESCAPE})*)\'/
|
65
66
|
|
66
|
-
IDENT =
|
67
|
+
IDENT = /-*#{NMSTART}#{NMCHAR}*/
|
67
68
|
NAME = /#{NMCHAR}+/
|
68
|
-
NUM =
|
69
|
+
NUM = //
|
69
70
|
STRING = /#{STRING1}|#{STRING2}/
|
70
71
|
URLCHAR = /[#%&*-~]|#{NONASCII}|#{ESCAPE}/
|
71
72
|
URL = /(#{URLCHAR}*)/
|
@@ -95,7 +96,9 @@ module Sass
|
|
95
96
|
|
96
97
|
IMPORTANT = /!#{W}important/i
|
97
98
|
|
98
|
-
|
99
|
+
UNITLESS_NUMBER = /(?:[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?\d+)?/
|
100
|
+
NUMBER = /#{UNITLESS_NUMBER}(?:#{IDENT}|%)?/
|
101
|
+
PERCENTAGE = /#{UNITLESS_NUMBER}%/
|
99
102
|
|
100
103
|
URI = /url\(#{W}(?:#{STRING}|#{URL})#{W}\)/i
|
101
104
|
FUNCTION = /#{IDENT}\(/
|
@@ -118,10 +121,16 @@ module Sass
|
|
118
121
|
INTERP_START = /#\{/
|
119
122
|
ANY = /:(-[-\w]+-)?any\(/i
|
120
123
|
OPTIONAL = /!#{W}optional/i
|
124
|
+
IDENT_START = /-|#{NMSTART}/
|
125
|
+
|
126
|
+
# A unit is like an IDENT, but disallows a hyphen followed by a digit.
|
127
|
+
# This allows "1px-2px" to be interpreted as subtraction rather than "1"
|
128
|
+
# with the unit "px-2px". It also allows "%".
|
129
|
+
UNIT = /-?#{NMSTART}(?:[a-zA-Z0-9_]|#{NONASCII}|#{ESCAPE}|-(?!\d))*|%/
|
121
130
|
|
122
131
|
IDENT_HYPHEN_INTERP = /-(#\{)/
|
123
|
-
STRING1_NOINTERP = /\"((?:[^\n\r\f\\"#]|#(?!\{)
|
124
|
-
STRING2_NOINTERP = /\'((?:[^\n\r\f\\'#]|#(?!\{)
|
132
|
+
STRING1_NOINTERP = /\"((?:[^\n\r\f\\"#]|#(?!\{)|#{ESCAPE})*)\"/
|
133
|
+
STRING2_NOINTERP = /\'((?:[^\n\r\f\\'#]|#(?!\{)|#{ESCAPE})*)\'/
|
125
134
|
STRING_NOINTERP = /#{STRING1_NOINTERP}|#{STRING2_NOINTERP}/
|
126
135
|
|
127
136
|
STATIC_COMPONENT = /#{IDENT}|#{STRING_NOINTERP}|#{HEXCOLOR}|[+-]?#{NUMBER}|\!important/i
|
@@ -41,6 +41,24 @@ module Sass
|
|
41
41
|
return type, directives
|
42
42
|
end
|
43
43
|
|
44
|
+
def parse_keyframes_selector
|
45
|
+
init_scanner!
|
46
|
+
sel = expr!(:keyframes_selector)
|
47
|
+
expected("keyframes selector") unless @scanner.eos?
|
48
|
+
sel
|
49
|
+
end
|
50
|
+
|
51
|
+
# @see Parser#initialize
|
52
|
+
# @param allow_parent_ref [Boolean] Whether to allow the
|
53
|
+
# parent-reference selector, `&`, when parsing the document.
|
54
|
+
# @comment
|
55
|
+
# rubocop:disable ParameterLists
|
56
|
+
def initialize(str, filename, importer, line = 1, offset = 1, allow_parent_ref = true)
|
57
|
+
# rubocop:enable ParameterLists
|
58
|
+
super(str, filename, importer, line, offset)
|
59
|
+
@allow_parent_ref = allow_parent_ref
|
60
|
+
end
|
61
|
+
|
44
62
|
private
|
45
63
|
|
46
64
|
def moz_document_function
|
@@ -52,7 +70,7 @@ module Sass
|
|
52
70
|
|
53
71
|
def variable; nil; end
|
54
72
|
def script_value; nil; end
|
55
|
-
def interpolation; nil; end
|
73
|
+
def interpolation(warn_for_color = false); nil; end
|
56
74
|
def var_expr; nil; end
|
57
75
|
def interp_string; (s = tok(STRING)) && [s]; end
|
58
76
|
def interp_uri; (s = tok(URI)) && [s]; end
|
@@ -64,6 +82,285 @@ module Sass
|
|
64
82
|
super
|
65
83
|
end
|
66
84
|
|
85
|
+
def selector_comma_sequence
|
86
|
+
sel = selector
|
87
|
+
return unless sel
|
88
|
+
selectors = [sel]
|
89
|
+
ws = ''
|
90
|
+
while tok(/,/)
|
91
|
+
ws << str {ss}
|
92
|
+
if (sel = selector)
|
93
|
+
selectors << sel
|
94
|
+
if ws.include?("\n")
|
95
|
+
selectors[-1] = Selector::Sequence.new(["\n"] + selectors.last.members)
|
96
|
+
end
|
97
|
+
ws = ''
|
98
|
+
end
|
99
|
+
end
|
100
|
+
Selector::CommaSequence.new(selectors)
|
101
|
+
end
|
102
|
+
|
103
|
+
def selector_string
|
104
|
+
sel = selector
|
105
|
+
return unless sel
|
106
|
+
sel.to_s
|
107
|
+
end
|
108
|
+
|
109
|
+
def selector
|
110
|
+
start_pos = source_position
|
111
|
+
# The combinator here allows the "> E" hack
|
112
|
+
val = combinator || simple_selector_sequence
|
113
|
+
return unless val
|
114
|
+
nl = str {ss}.include?("\n")
|
115
|
+
res = []
|
116
|
+
res << val
|
117
|
+
res << "\n" if nl
|
118
|
+
|
119
|
+
while (val = combinator || simple_selector_sequence)
|
120
|
+
res << val
|
121
|
+
res << "\n" if str {ss}.include?("\n")
|
122
|
+
end
|
123
|
+
seq = Selector::Sequence.new(res.compact)
|
124
|
+
|
125
|
+
if seq.members.any? {|sseq| sseq.is_a?(Selector::SimpleSequence) && sseq.subject?}
|
126
|
+
location = " of #{@filename}" if @filename
|
127
|
+
Sass::Util.sass_warn <<MESSAGE
|
128
|
+
DEPRECATION WARNING on line #{start_pos.line}, column #{start_pos.offset}#{location}:
|
129
|
+
The subject selector operator "!" is deprecated and will be removed in a future release.
|
130
|
+
This operator has been replaced by ":has()" in the CSS spec.
|
131
|
+
For example: #{seq.subjectless}
|
132
|
+
MESSAGE
|
133
|
+
end
|
134
|
+
|
135
|
+
seq
|
136
|
+
end
|
137
|
+
|
138
|
+
def combinator
|
139
|
+
tok(PLUS) || tok(GREATER) || tok(TILDE) || reference_combinator
|
140
|
+
end
|
141
|
+
|
142
|
+
def reference_combinator
|
143
|
+
return unless tok(/\//)
|
144
|
+
res = '/'
|
145
|
+
ns, name = expr!(:qualified_name)
|
146
|
+
res << ns << '|' if ns
|
147
|
+
res << name << tok!(/\//)
|
148
|
+
res
|
149
|
+
end
|
150
|
+
|
151
|
+
def simple_selector_sequence
|
152
|
+
start_pos = source_position
|
153
|
+
e = element_name || id_selector || class_selector || placeholder_selector || attrib ||
|
154
|
+
pseudo || parent_selector
|
155
|
+
return unless e
|
156
|
+
res = [e]
|
157
|
+
|
158
|
+
# The tok(/\*/) allows the "E*" hack
|
159
|
+
while (v = id_selector || class_selector || placeholder_selector ||
|
160
|
+
attrib || pseudo || (tok(/\*/) && Selector::Universal.new(nil)))
|
161
|
+
res << v
|
162
|
+
end
|
163
|
+
|
164
|
+
pos = @scanner.pos
|
165
|
+
line = @line
|
166
|
+
if (sel = str? {simple_selector_sequence})
|
167
|
+
@scanner.pos = pos
|
168
|
+
@line = line
|
169
|
+
begin
|
170
|
+
# If we see "*E", don't force a throw because this could be the
|
171
|
+
# "*prop: val" hack.
|
172
|
+
expected('"{"') if res.length == 1 && res[0].is_a?(Selector::Universal)
|
173
|
+
throw_error {expected('"{"')}
|
174
|
+
rescue Sass::SyntaxError => e
|
175
|
+
e.message << "\n\n\"#{sel}\" may only be used at the beginning of a compound selector."
|
176
|
+
raise e
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
Selector::SimpleSequence.new(res, tok(/!/), range(start_pos))
|
181
|
+
end
|
182
|
+
|
183
|
+
def parent_selector
|
184
|
+
return unless @allow_parent_ref && tok(/&/)
|
185
|
+
Selector::Parent.new(tok(NAME))
|
186
|
+
end
|
187
|
+
|
188
|
+
def class_selector
|
189
|
+
return unless tok(/\./)
|
190
|
+
@expected = "class name"
|
191
|
+
Selector::Class.new(tok!(IDENT))
|
192
|
+
end
|
193
|
+
|
194
|
+
def id_selector
|
195
|
+
return unless tok(/#(?!\{)/)
|
196
|
+
@expected = "id name"
|
197
|
+
Selector::Id.new(tok!(NAME))
|
198
|
+
end
|
199
|
+
|
200
|
+
def placeholder_selector
|
201
|
+
return unless tok(/%/)
|
202
|
+
@expected = "placeholder name"
|
203
|
+
Selector::Placeholder.new(tok!(IDENT))
|
204
|
+
end
|
205
|
+
|
206
|
+
def element_name
|
207
|
+
ns, name = Sass::Util.destructure(qualified_name(:allow_star_name))
|
208
|
+
return unless ns || name
|
209
|
+
|
210
|
+
if name == '*'
|
211
|
+
Selector::Universal.new(ns)
|
212
|
+
else
|
213
|
+
Selector::Element.new(name, ns)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def qualified_name(allow_star_name = false)
|
218
|
+
name = tok(IDENT) || tok(/\*/) || (tok?(/\|/) && "")
|
219
|
+
return unless name
|
220
|
+
return nil, name unless tok(/\|/)
|
221
|
+
|
222
|
+
return name, tok!(IDENT) unless allow_star_name
|
223
|
+
@expected = "identifier or *"
|
224
|
+
return name, tok(IDENT) || tok!(/\*/)
|
225
|
+
end
|
226
|
+
|
227
|
+
def attrib
|
228
|
+
return unless tok(/\[/)
|
229
|
+
ss
|
230
|
+
ns, name = attrib_name!
|
231
|
+
ss
|
232
|
+
|
233
|
+
op = tok(/=/) ||
|
234
|
+
tok(INCLUDES) ||
|
235
|
+
tok(DASHMATCH) ||
|
236
|
+
tok(PREFIXMATCH) ||
|
237
|
+
tok(SUFFIXMATCH) ||
|
238
|
+
tok(SUBSTRINGMATCH)
|
239
|
+
if op
|
240
|
+
@expected = "identifier or string"
|
241
|
+
ss
|
242
|
+
val = tok(IDENT) || tok!(STRING)
|
243
|
+
ss
|
244
|
+
end
|
245
|
+
flags = tok(IDENT) || tok(STRING)
|
246
|
+
tok!(/\]/)
|
247
|
+
|
248
|
+
Selector::Attribute.new(name, ns, op, val, flags)
|
249
|
+
end
|
250
|
+
|
251
|
+
def attrib_name!
|
252
|
+
if (name_or_ns = tok(IDENT))
|
253
|
+
# E, E|E
|
254
|
+
if tok(/\|(?!=)/)
|
255
|
+
ns = name_or_ns
|
256
|
+
name = tok(IDENT)
|
257
|
+
else
|
258
|
+
name = name_or_ns
|
259
|
+
end
|
260
|
+
else
|
261
|
+
# *|E or |E
|
262
|
+
ns = tok(/\*/) || ""
|
263
|
+
tok!(/\|/)
|
264
|
+
name = tok!(IDENT)
|
265
|
+
end
|
266
|
+
return ns, name
|
267
|
+
end
|
268
|
+
|
269
|
+
SELECTOR_PSEUDO_CLASSES = %w[not matches current any has host host-context].to_set
|
270
|
+
|
271
|
+
PREFIXED_SELECTOR_PSEUDO_CLASSES = %w[nth-child nth-last-child].to_set
|
272
|
+
|
273
|
+
def pseudo
|
274
|
+
s = tok(/::?/)
|
275
|
+
return unless s
|
276
|
+
@expected = "pseudoclass or pseudoelement"
|
277
|
+
name = tok!(IDENT)
|
278
|
+
if tok(/\(/)
|
279
|
+
ss
|
280
|
+
deprefixed = deprefix(name)
|
281
|
+
if s == ':' && SELECTOR_PSEUDO_CLASSES.include?(deprefixed)
|
282
|
+
sel = selector_comma_sequence
|
283
|
+
elsif s == ':' && PREFIXED_SELECTOR_PSEUDO_CLASSES.include?(deprefixed)
|
284
|
+
arg, sel = prefixed_selector_pseudo
|
285
|
+
else
|
286
|
+
arg = expr!(:pseudo_args)
|
287
|
+
end
|
288
|
+
|
289
|
+
tok!(/\)/)
|
290
|
+
end
|
291
|
+
Selector::Pseudo.new(s == ':' ? :class : :element, name, arg, sel)
|
292
|
+
end
|
293
|
+
|
294
|
+
def pseudo_args
|
295
|
+
arg = expr!(:pseudo_expr)
|
296
|
+
while tok(/,/)
|
297
|
+
arg << ',' << str {ss}
|
298
|
+
arg.concat expr!(:pseudo_expr)
|
299
|
+
end
|
300
|
+
arg
|
301
|
+
end
|
302
|
+
|
303
|
+
def pseudo_expr
|
304
|
+
res = pseudo_expr_token
|
305
|
+
return unless res
|
306
|
+
res << str {ss}
|
307
|
+
while (e = pseudo_expr_token)
|
308
|
+
res << e << str {ss}
|
309
|
+
end
|
310
|
+
res
|
311
|
+
end
|
312
|
+
|
313
|
+
def pseudo_expr_token
|
314
|
+
tok(PLUS) || tok(/[-*]/) || tok(NUMBER) || tok(STRING) || tok(IDENT)
|
315
|
+
end
|
316
|
+
|
317
|
+
def prefixed_selector_pseudo
|
318
|
+
prefix = str do
|
319
|
+
expr = str {expr!(:a_n_plus_b)}
|
320
|
+
ss
|
321
|
+
return expr, nil unless tok(/of/)
|
322
|
+
ss
|
323
|
+
end
|
324
|
+
return prefix, expr!(:selector_comma_sequence)
|
325
|
+
end
|
326
|
+
|
327
|
+
def a_n_plus_b
|
328
|
+
if (parity = tok(/even|odd/i))
|
329
|
+
return parity
|
330
|
+
end
|
331
|
+
|
332
|
+
if tok(/[+-]?[0-9]+/)
|
333
|
+
ss
|
334
|
+
return true unless tok(/n/)
|
335
|
+
else
|
336
|
+
return unless tok(/[+-]?n/i)
|
337
|
+
end
|
338
|
+
ss
|
339
|
+
|
340
|
+
return true unless tok(/[+-]/)
|
341
|
+
ss
|
342
|
+
@expected = "number"
|
343
|
+
tok!(/[0-9]+/)
|
344
|
+
true
|
345
|
+
end
|
346
|
+
|
347
|
+
def keyframes_selector
|
348
|
+
ss
|
349
|
+
str do
|
350
|
+
return unless keyframes_selector_component
|
351
|
+
ss
|
352
|
+
while tok(/,/)
|
353
|
+
ss
|
354
|
+
expr!(:keyframes_selector_component)
|
355
|
+
ss
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
def keyframes_selector_component
|
361
|
+
tok(/from|to/i) || tok(PERCENTAGE)
|
362
|
+
end
|
363
|
+
|
67
364
|
@sass_script_parser = Class.new(Sass::Script::CssParser)
|
68
365
|
@sass_script_parser.send(:include, ScriptParser)
|
69
366
|
end
|
data/lib/sass/selector.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'sass/selector/simple'
|
2
2
|
require 'sass/selector/abstract_sequence'
|
3
3
|
require 'sass/selector/comma_sequence'
|
4
|
+
require 'sass/selector/pseudo'
|
4
5
|
require 'sass/selector/sequence'
|
5
6
|
require 'sass/selector/simple_sequence'
|
6
7
|
|
@@ -27,19 +28,19 @@ module Sass
|
|
27
28
|
# The function of this is to be replaced by the parent selector
|
28
29
|
# in the nested hierarchy.
|
29
30
|
class Parent < Simple
|
30
|
-
# The identifier following the `&`.
|
31
|
+
# The identifier following the `&`. `nil` indicates no suffix.
|
31
32
|
#
|
32
|
-
# @return [
|
33
|
+
# @return [String, nil]
|
33
34
|
attr_reader :suffix
|
34
35
|
|
35
|
-
# @param name [
|
36
|
-
def initialize(suffix =
|
36
|
+
# @param name [String, nil] See \{#suffix}
|
37
|
+
def initialize(suffix = nil)
|
37
38
|
@suffix = suffix
|
38
39
|
end
|
39
40
|
|
40
|
-
# @see Selector#
|
41
|
-
def
|
42
|
-
|
41
|
+
# @see Selector#to_s
|
42
|
+
def to_s
|
43
|
+
"&" + (@suffix || '')
|
43
44
|
end
|
44
45
|
|
45
46
|
# Always raises an exception.
|
@@ -55,17 +56,17 @@ module Sass
|
|
55
56
|
class Class < Simple
|
56
57
|
# The class name.
|
57
58
|
#
|
58
|
-
# @return [
|
59
|
+
# @return [String]
|
59
60
|
attr_reader :name
|
60
61
|
|
61
|
-
# @param name [
|
62
|
+
# @param name [String] The class name
|
62
63
|
def initialize(name)
|
63
64
|
@name = name
|
64
65
|
end
|
65
66
|
|
66
|
-
# @see Selector#
|
67
|
-
def
|
68
|
-
|
67
|
+
# @see Selector#to_s
|
68
|
+
def to_s
|
69
|
+
"." + @name
|
69
70
|
end
|
70
71
|
|
71
72
|
# @see AbstractSequence#specificity
|
@@ -78,17 +79,17 @@ module Sass
|
|
78
79
|
class Id < Simple
|
79
80
|
# The id name.
|
80
81
|
#
|
81
|
-
# @return [
|
82
|
+
# @return [String]
|
82
83
|
attr_reader :name
|
83
84
|
|
84
|
-
# @param name [
|
85
|
+
# @param name [String] The id name
|
85
86
|
def initialize(name)
|
86
87
|
@name = name
|
87
88
|
end
|
88
89
|
|
89
|
-
# @see Selector#
|
90
|
-
def
|
91
|
-
|
90
|
+
# @see Selector#to_s
|
91
|
+
def to_s
|
92
|
+
"#" + @name
|
92
93
|
end
|
93
94
|
|
94
95
|
# Returns `nil` if `sels` contains an {Id} selector
|
@@ -113,17 +114,17 @@ module Sass
|
|
113
114
|
class Placeholder < Simple
|
114
115
|
# The placeholder name.
|
115
116
|
#
|
116
|
-
# @return [
|
117
|
+
# @return [String]
|
117
118
|
attr_reader :name
|
118
119
|
|
119
|
-
# @param name [
|
120
|
+
# @param name [String] The placeholder name
|
120
121
|
def initialize(name)
|
121
122
|
@name = name
|
122
123
|
end
|
123
124
|
|
124
|
-
# @see Selector#
|
125
|
-
def
|
126
|
-
|
125
|
+
# @see Selector#to_s
|
126
|
+
def to_s
|
127
|
+
"%" + @name
|
127
128
|
end
|
128
129
|
|
129
130
|
# @see AbstractSequence#specificity
|
@@ -134,22 +135,20 @@ module Sass
|
|
134
135
|
|
135
136
|
# A universal selector (`*` in CSS).
|
136
137
|
class Universal < Simple
|
137
|
-
# The selector namespace.
|
138
|
-
# `
|
139
|
-
# `[""]` means no namespace,
|
140
|
-
# `["*"]` means any namespace.
|
138
|
+
# The selector namespace. `nil` means the default namespace, `""` means no
|
139
|
+
# namespace, `"*"` means any namespace.
|
141
140
|
#
|
142
|
-
# @return [
|
141
|
+
# @return [String, nil]
|
143
142
|
attr_reader :namespace
|
144
143
|
|
145
|
-
# @param namespace [
|
144
|
+
# @param namespace [String, nil] See \{#namespace}
|
146
145
|
def initialize(namespace)
|
147
146
|
@namespace = namespace
|
148
147
|
end
|
149
148
|
|
150
|
-
# @see Selector#
|
151
|
-
def
|
152
|
-
@namespace ? @namespace
|
149
|
+
# @see Selector#to_s
|
150
|
+
def to_s
|
151
|
+
@namespace ? "#{@namespace}|*" : "*"
|
153
152
|
end
|
154
153
|
|
155
154
|
# Unification of a universal selector is somewhat complicated,
|
@@ -183,7 +182,7 @@ module Sass
|
|
183
182
|
when Universal; :universal
|
184
183
|
when Element; sels.first.name
|
185
184
|
else
|
186
|
-
return [self] + sels unless namespace.nil? || namespace ==
|
185
|
+
return [self] + sels unless namespace.nil? || namespace == '*'
|
187
186
|
return sels unless sels.empty?
|
188
187
|
return [self]
|
189
188
|
end
|
@@ -203,27 +202,25 @@ module Sass
|
|
203
202
|
class Element < Simple
|
204
203
|
# The element name.
|
205
204
|
#
|
206
|
-
# @return [
|
205
|
+
# @return [String]
|
207
206
|
attr_reader :name
|
208
207
|
|
209
|
-
# The selector namespace.
|
210
|
-
# `
|
211
|
-
# `[""]` means no namespace,
|
212
|
-
# `["*"]` means any namespace.
|
208
|
+
# The selector namespace. `nil` means the default namespace, `""` means no
|
209
|
+
# namespace, `"*"` means any namespace.
|
213
210
|
#
|
214
|
-
# @return [
|
211
|
+
# @return [String, nil]
|
215
212
|
attr_reader :namespace
|
216
213
|
|
217
|
-
# @param name [
|
218
|
-
# @param namespace [
|
214
|
+
# @param name [String] The element name
|
215
|
+
# @param namespace [String, nil] See \{#namespace}
|
219
216
|
def initialize(name, namespace)
|
220
217
|
@name = name
|
221
218
|
@namespace = namespace
|
222
219
|
end
|
223
220
|
|
224
|
-
# @see Selector#
|
225
|
-
def
|
226
|
-
@namespace ? @namespace
|
221
|
+
# @see Selector#to_s
|
222
|
+
def to_s
|
223
|
+
@namespace ? "#{@namespace}|#{@name}" : @name
|
227
224
|
end
|
228
225
|
|
229
226
|
# Unification of an element selector is somewhat complicated,
|
@@ -266,32 +263,6 @@ module Sass
|
|
266
263
|
end
|
267
264
|
end
|
268
265
|
|
269
|
-
# Selector interpolation (`#{}` in Sass).
|
270
|
-
class Interpolation < Simple
|
271
|
-
# The script to run.
|
272
|
-
#
|
273
|
-
# @return [Sass::Script::Tree::Node]
|
274
|
-
attr_reader :script
|
275
|
-
|
276
|
-
# @param script [Sass::Script::Tree::Node] The script to run
|
277
|
-
def initialize(script)
|
278
|
-
@script = script
|
279
|
-
end
|
280
|
-
|
281
|
-
# @see Selector#to_a
|
282
|
-
def to_a
|
283
|
-
[@script]
|
284
|
-
end
|
285
|
-
|
286
|
-
# Always raises an exception.
|
287
|
-
#
|
288
|
-
# @raise [Sass::SyntaxError] Interpolation selectors should be resolved before unification
|
289
|
-
# @see Selector#unify
|
290
|
-
def unify(sels)
|
291
|
-
raise Sass::SyntaxError.new("[BUG] Cannot unify interpolation selectors.")
|
292
|
-
end
|
293
|
-
end
|
294
|
-
|
295
266
|
# An attribute selector (e.g. `[href^="http://"]`).
|
296
267
|
class Attribute < Simple
|
297
268
|
# The attribute name.
|
@@ -299,12 +270,10 @@ module Sass
|
|
299
270
|
# @return [Array<String, Sass::Script::Tree::Node>]
|
300
271
|
attr_reader :name
|
301
272
|
|
302
|
-
# The attribute namespace.
|
303
|
-
# `
|
304
|
-
# `[""]` means no namespace,
|
305
|
-
# `["*"]` means any namespace.
|
273
|
+
# The attribute namespace. `nil` means the default namespace, `""` means
|
274
|
+
# no namespace, `"*"` means any namespace.
|
306
275
|
#
|
307
|
-
# @return [
|
276
|
+
# @return [String, nil]
|
308
277
|
attr_reader :namespace
|
309
278
|
|
310
279
|
# The matching operator, e.g. `"="` or `"^="`.
|
@@ -314,19 +283,19 @@ module Sass
|
|
314
283
|
|
315
284
|
# The right-hand side of the operator.
|
316
285
|
#
|
317
|
-
# @return [
|
286
|
+
# @return [String]
|
318
287
|
attr_reader :value
|
319
288
|
|
320
289
|
# Flags for the attribute selector (e.g. `i`).
|
321
290
|
#
|
322
|
-
# @return [
|
291
|
+
# @return [String]
|
323
292
|
attr_reader :flags
|
324
293
|
|
325
|
-
# @param name [
|
326
|
-
# @param namespace [
|
294
|
+
# @param name [String] The attribute name
|
295
|
+
# @param namespace [String, nil] See \{#namespace}
|
327
296
|
# @param operator [String] The matching operator, e.g. `"="` or `"^="`
|
328
|
-
# @param value [
|
329
|
-
# @param flags [
|
297
|
+
# @param value [String] See \{#value}
|
298
|
+
# @param flags [String] See \{#flags}
|
330
299
|
# @comment
|
331
300
|
# rubocop:disable ParameterLists
|
332
301
|
def initialize(name, namespace, operator, value, flags)
|
@@ -338,13 +307,13 @@ module Sass
|
|
338
307
|
@flags = flags
|
339
308
|
end
|
340
309
|
|
341
|
-
# @see Selector#
|
342
|
-
def
|
343
|
-
res =
|
344
|
-
res
|
345
|
-
res
|
346
|
-
|
347
|
-
|
310
|
+
# @see Selector#to_s
|
311
|
+
def to_s
|
312
|
+
res = "["
|
313
|
+
res << @namespace << "|" if @namespace
|
314
|
+
res << @name
|
315
|
+
res << @operator << @value if @value
|
316
|
+
res << " " << @flags if @flags
|
348
317
|
res << "]"
|
349
318
|
end
|
350
319
|
|
@@ -353,111 +322,5 @@ module Sass
|
|
353
322
|
SPECIFICITY_BASE
|
354
323
|
end
|
355
324
|
end
|
356
|
-
|
357
|
-
# A pseudoclass (e.g. `:visited`) or pseudoelement (e.g. `::first-line`) selector.
|
358
|
-
# It can have arguments (e.g. `:nth-child(2n+1)`).
|
359
|
-
class Pseudo < Simple
|
360
|
-
# Some psuedo-class-syntax selectors are actually considered
|
361
|
-
# pseudo-elements and must be treated differently. This is a list of such
|
362
|
-
# selectors
|
363
|
-
#
|
364
|
-
# @return [Array<String>]
|
365
|
-
ACTUALLY_ELEMENTS = %w[after before first-line first-letter]
|
366
|
-
|
367
|
-
# Like \{#type}, but returns the type of selector this looks like, rather
|
368
|
-
# than the type it is semantically. This only differs from type for
|
369
|
-
# selectors in \{ACTUALLY\_ELEMENTS}.
|
370
|
-
#
|
371
|
-
# @return [Symbol]
|
372
|
-
attr_reader :syntactic_type
|
373
|
-
|
374
|
-
# The name of the selector.
|
375
|
-
#
|
376
|
-
# @return [Array<String, Sass::Script::Tree::Node>]
|
377
|
-
attr_reader :name
|
378
|
-
|
379
|
-
# The argument to the selector,
|
380
|
-
# or `nil` if no argument was given.
|
381
|
-
#
|
382
|
-
# This may include SassScript nodes that will be run during resolution.
|
383
|
-
# Note that this should not include SassScript nodes
|
384
|
-
# after resolution has taken place.
|
385
|
-
#
|
386
|
-
# @return [Array<String, Sass::Script::Tree::Node>, nil]
|
387
|
-
attr_reader :arg
|
388
|
-
|
389
|
-
# @param type [Symbol] See \{#type}
|
390
|
-
# @param name [Array<String, Sass::Script::Tree::Node>] The name of the selector
|
391
|
-
# @param arg [nil, Array<String, Sass::Script::Tree::Node>] The argument to the selector,
|
392
|
-
# or nil if no argument was given
|
393
|
-
def initialize(type, name, arg)
|
394
|
-
@syntactic_type = type
|
395
|
-
@name = name
|
396
|
-
@arg = arg
|
397
|
-
end
|
398
|
-
|
399
|
-
# The type of the selector. `:class` if this is a pseudoclass selector,
|
400
|
-
# `:element` if it's a pseudoelement.
|
401
|
-
#
|
402
|
-
# @return [Symbol]
|
403
|
-
def type
|
404
|
-
ACTUALLY_ELEMENTS.include?(name.first) ? :element : syntactic_type
|
405
|
-
end
|
406
|
-
|
407
|
-
# @see Selector#to_a
|
408
|
-
def to_a
|
409
|
-
res = [syntactic_type == :class ? ":" : "::"] + @name
|
410
|
-
(res << "(").concat(Sass::Util.strip_string_array(@arg)) << ")" if @arg
|
411
|
-
res
|
412
|
-
end
|
413
|
-
|
414
|
-
# Returns `nil` if this is a pseudoelement selector
|
415
|
-
# and `sels` contains a pseudoelement selector different than this one.
|
416
|
-
#
|
417
|
-
# @see Selector#unify
|
418
|
-
def unify(sels)
|
419
|
-
return if type == :element && sels.any? do |sel|
|
420
|
-
sel.is_a?(Pseudo) && sel.type == :element &&
|
421
|
-
(sel.name != name || sel.arg != arg)
|
422
|
-
end
|
423
|
-
super
|
424
|
-
end
|
425
|
-
|
426
|
-
# @see AbstractSequence#specificity
|
427
|
-
def specificity
|
428
|
-
type == :class ? SPECIFICITY_BASE : 1
|
429
|
-
end
|
430
|
-
end
|
431
|
-
|
432
|
-
# A pseudoclass selector whose argument is itself a selector
|
433
|
-
# (e.g. `:not(.foo)` or `:-moz-all(.foo, .bar)`).
|
434
|
-
class SelectorPseudoClass < Simple
|
435
|
-
# The name of the pseudoclass.
|
436
|
-
#
|
437
|
-
# @return [String]
|
438
|
-
attr_reader :name
|
439
|
-
|
440
|
-
# The selector argument.
|
441
|
-
#
|
442
|
-
# @return [Selector::Sequence]
|
443
|
-
attr_reader :selector
|
444
|
-
|
445
|
-
# @param name [String] The name of the pseudoclass
|
446
|
-
# @param selector [Selector::CommaSequence] The selector argument
|
447
|
-
def initialize(name, selector)
|
448
|
-
@name = name
|
449
|
-
@selector = selector
|
450
|
-
end
|
451
|
-
|
452
|
-
# @see Selector#to_a
|
453
|
-
def to_a
|
454
|
-
[":", @name, "("] + @selector.to_a + [")"]
|
455
|
-
end
|
456
|
-
|
457
|
-
# @see AbstractSequence#specificity
|
458
|
-
def specificity
|
459
|
-
SPECIFICITY_BASE
|
460
|
-
end
|
461
|
-
end
|
462
325
|
end
|
463
326
|
end
|