sass 3.3.0 → 3.4.25
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/.yardopts +3 -1
- data/CODE_OF_CONDUCT.md +10 -0
- data/CONTRIBUTING.md +148 -0
- data/MIT-LICENSE +1 -1
- data/README.md +76 -62
- data/Rakefile +104 -24
- 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/extra/sass-spec-ref.sh +32 -0
- data/extra/update_watch.rb +1 -1
- data/lib/sass/cache_stores/filesystem.rb +9 -5
- data/lib/sass/cache_stores/memory.rb +4 -5
- data/lib/sass/callbacks.rb +2 -2
- data/lib/sass/css.rb +12 -13
- data/lib/sass/deprecation.rb +55 -0
- data/lib/sass/engine.rb +106 -70
- data/lib/sass/environment.rb +39 -19
- data/lib/sass/error.rb +17 -20
- data/lib/sass/exec/base.rb +199 -0
- data/lib/sass/exec/sass_convert.rb +283 -0
- data/lib/sass/exec/sass_scss.rb +440 -0
- data/lib/sass/exec.rb +5 -771
- data/lib/sass/features.rb +9 -2
- data/lib/sass/importers/base.rb +8 -3
- data/lib/sass/importers/filesystem.rb +30 -38
- data/lib/sass/logger/base.rb +8 -2
- data/lib/sass/logger/delayed.rb +50 -0
- data/lib/sass/logger.rb +8 -3
- data/lib/sass/media.rb +1 -4
- data/lib/sass/plugin/compiler.rb +224 -90
- data/lib/sass/plugin/configuration.rb +38 -22
- data/lib/sass/plugin/merb.rb +2 -2
- data/lib/sass/plugin/rack.rb +3 -3
- data/lib/sass/plugin/rails.rb +1 -1
- data/lib/sass/plugin/staleness_checker.rb +4 -4
- data/lib/sass/plugin.rb +6 -5
- data/lib/sass/script/css_lexer.rb +1 -1
- data/lib/sass/script/css_parser.rb +2 -3
- data/lib/sass/script/css_variable_warning.rb +52 -0
- data/lib/sass/script/functions.rb +739 -318
- data/lib/sass/script/lexer.rb +134 -54
- data/lib/sass/script/parser.rb +252 -56
- data/lib/sass/script/tree/funcall.rb +13 -6
- data/lib/sass/script/tree/interpolation.rb +127 -4
- data/lib/sass/script/tree/list_literal.rb +31 -4
- data/lib/sass/script/tree/literal.rb +4 -0
- data/lib/sass/script/tree/node.rb +21 -3
- data/lib/sass/script/tree/operation.rb +54 -1
- data/lib/sass/script/tree/selector.rb +26 -0
- data/lib/sass/script/tree/string_interpolation.rb +59 -38
- data/lib/sass/script/tree/variable.rb +1 -1
- data/lib/sass/script/tree.rb +1 -0
- data/lib/sass/script/value/base.rb +17 -14
- data/lib/sass/script/value/bool.rb +0 -5
- data/lib/sass/script/value/color.rb +78 -42
- data/lib/sass/script/value/helpers.rb +119 -2
- data/lib/sass/script/value/list.rb +0 -15
- data/lib/sass/script/value/map.rb +1 -1
- data/lib/sass/script/value/null.rb +0 -5
- data/lib/sass/script/value/number.rb +112 -31
- data/lib/sass/script/value/string.rb +102 -13
- data/lib/sass/script/value.rb +0 -1
- data/lib/sass/script.rb +3 -3
- data/lib/sass/scss/css_parser.rb +24 -4
- data/lib/sass/scss/parser.rb +290 -383
- data/lib/sass/scss/rx.rb +17 -9
- data/lib/sass/scss/static_parser.rb +306 -4
- data/lib/sass/scss.rb +0 -2
- data/lib/sass/selector/abstract_sequence.rb +35 -18
- data/lib/sass/selector/comma_sequence.rb +114 -19
- data/lib/sass/selector/pseudo.rb +266 -0
- data/lib/sass/selector/sequence.rb +146 -40
- data/lib/sass/selector/simple.rb +22 -33
- data/lib/sass/selector/simple_sequence.rb +122 -39
- data/lib/sass/selector.rb +57 -197
- data/lib/sass/shared.rb +2 -2
- data/lib/sass/source/map.rb +31 -14
- data/lib/sass/source/position.rb +4 -4
- data/lib/sass/stack.rb +2 -8
- data/lib/sass/supports.rb +10 -13
- data/lib/sass/tree/at_root_node.rb +1 -0
- data/lib/sass/tree/charset_node.rb +1 -1
- data/lib/sass/tree/comment_node.rb +1 -1
- data/lib/sass/tree/css_import_node.rb +9 -1
- data/lib/sass/tree/directive_node.rb +8 -2
- data/lib/sass/tree/error_node.rb +18 -0
- data/lib/sass/tree/extend_node.rb +1 -1
- data/lib/sass/tree/function_node.rb +9 -0
- data/lib/sass/tree/import_node.rb +6 -5
- data/lib/sass/tree/keyframe_rule_node.rb +15 -0
- data/lib/sass/tree/node.rb +5 -3
- data/lib/sass/tree/prop_node.rb +6 -7
- data/lib/sass/tree/rule_node.rb +26 -11
- data/lib/sass/tree/visitors/check_nesting.rb +56 -32
- data/lib/sass/tree/visitors/convert.rb +59 -44
- data/lib/sass/tree/visitors/cssize.rb +34 -30
- data/lib/sass/tree/visitors/deep_copy.rb +6 -1
- data/lib/sass/tree/visitors/extend.rb +15 -13
- data/lib/sass/tree/visitors/perform.rb +87 -50
- data/lib/sass/tree/visitors/set_options.rb +15 -1
- data/lib/sass/tree/visitors/to_css.rb +72 -43
- data/lib/sass/util/multibyte_string_scanner.rb +0 -2
- data/lib/sass/util/normalized_map.rb +0 -1
- data/lib/sass/util/subset_map.rb +2 -3
- data/lib/sass/util.rb +334 -154
- data/lib/sass/version.rb +7 -7
- data/lib/sass.rb +10 -8
- data/test/sass/cache_test.rb +62 -20
- data/test/sass/callbacks_test.rb +1 -1
- data/test/sass/compiler_test.rb +24 -11
- data/test/sass/conversion_test.rb +241 -50
- data/test/sass/css2sass_test.rb +73 -5
- data/test/sass/css_variable_test.rb +132 -0
- data/test/sass/encoding_test.rb +219 -0
- data/test/sass/engine_test.rb +343 -260
- data/test/sass/exec_test.rb +12 -2
- data/test/sass/extend_test.rb +333 -44
- data/test/sass/functions_test.rb +353 -260
- data/test/sass/importer_test.rb +40 -21
- data/test/sass/logger_test.rb +1 -1
- data/test/sass/more_results/more_import.css +1 -1
- data/test/sass/more_templates/more1.sass +10 -10
- data/test/sass/more_templates/more_import.sass +2 -2
- data/test/sass/plugin_test.rb +24 -21
- 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 +5 -5
- data/test/sass/results/scss_import.css +1 -1
- data/test/sass/script_conversion_test.rb +71 -39
- data/test/sass/script_test.rb +714 -123
- data/test/sass/scss/css_test.rb +213 -30
- data/test/sass/scss/rx_test.rb +8 -4
- data/test/sass/scss/scss_test.rb +766 -22
- data/test/sass/source_map_test.rb +263 -95
- data/test/sass/superselector_test.rb +210 -0
- data/test/sass/templates/_partial.sass +1 -1
- data/test/sass/templates/basic.sass +10 -10
- data/test/sass/templates/bork1.sass +1 -1
- data/test/sass/templates/bork5.sass +1 -1
- data/test/sass/templates/compact.sass +10 -10
- data/test/sass/templates/complex.sass +187 -187
- data/test/sass/templates/compressed.sass +10 -10
- data/test/sass/templates/expanded.sass +10 -10
- data/test/sass/templates/import.sass +2 -2
- data/test/sass/templates/importee.sass +3 -3
- data/test/sass/templates/mixins.sass +22 -22
- data/test/sass/templates/multiline.sass +4 -4
- data/test/sass/templates/nested.sass +13 -13
- data/test/sass/templates/parent_ref.sass +12 -12
- data/test/sass/templates/script.sass +70 -70
- data/test/sass/templates/scss_import.scss +2 -1
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +1 -1
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +2 -2
- data/test/sass/templates/subdir/subdir.sass +3 -3
- data/test/sass/templates/units.sass +10 -10
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +11 -3
- 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 +46 -45
- data/test/sass/value_helpers_test.rb +5 -7
- data/test/sass-spec.yml +3 -0
- data/test/test_helper.rb +7 -6
- data/vendor/listen/CHANGELOG.md +1 -228
- data/vendor/listen/Gemfile +5 -15
- data/vendor/listen/README.md +111 -77
- data/vendor/listen/Rakefile +0 -42
- data/vendor/listen/lib/listen/adapter.rb +195 -82
- data/vendor/listen/lib/listen/adapters/bsd.rb +27 -64
- data/vendor/listen/lib/listen/adapters/darwin.rb +21 -58
- data/vendor/listen/lib/listen/adapters/linux.rb +23 -55
- data/vendor/listen/lib/listen/adapters/polling.rb +25 -34
- data/vendor/listen/lib/listen/adapters/windows.rb +50 -46
- data/vendor/listen/lib/listen/directory_record.rb +96 -61
- data/vendor/listen/lib/listen/listener.rb +135 -37
- data/vendor/listen/lib/listen/turnstile.rb +9 -5
- data/vendor/listen/lib/listen/version.rb +1 -1
- data/vendor/listen/lib/listen.rb +33 -19
- data/vendor/listen/listen.gemspec +6 -0
- data/vendor/listen/spec/listen/adapter_spec.rb +43 -77
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +8 -8
- data/vendor/listen/spec/listen/directory_record_spec.rb +81 -56
- data/vendor/listen/spec/listen/listener_spec.rb +128 -39
- data/vendor/listen/spec/listen_spec.rb +15 -21
- data/vendor/listen/spec/spec_helper.rb +4 -0
- data/vendor/listen/spec/support/adapter_helper.rb +52 -15
- data/vendor/listen/spec/support/directory_record_helper.rb +7 -5
- data/vendor/listen/spec/support/listeners_helper.rb +30 -7
- metadata +310 -300
- data/CONTRIBUTING +0 -3
- data/ext/mkrf_conf.rb +0 -27
- data/lib/sass/script/value/deprecated_false.rb +0 -55
- data/lib/sass/scss/script_lexer.rb +0 -15
- data/lib/sass/scss/script_parser.rb +0 -25
- data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
- data/vendor/listen/lib/listen/multi_listener.rb +0 -143
- data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
- data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
data/lib/sass/script/lexer.rb
CHANGED
@@ -19,13 +19,13 @@ module Sass
|
|
19
19
|
# `source_range`: \[`Sass::Source::Range`\]
|
20
20
|
# : The range in the source file in which the token appeared.
|
21
21
|
#
|
22
|
-
# `pos`: \[`
|
22
|
+
# `pos`: \[`Integer`\]
|
23
23
|
# : The scanner position at which the SassScript token appeared.
|
24
24
|
Token = Struct.new(:type, :value, :source_range, :pos)
|
25
25
|
|
26
26
|
# The line number of the lexer's current position.
|
27
27
|
#
|
28
|
-
# @return [
|
28
|
+
# @return [Integer]
|
29
29
|
def line
|
30
30
|
return @line unless @tok
|
31
31
|
@tok.source_range.start_pos.line
|
@@ -34,7 +34,7 @@ module Sass
|
|
34
34
|
# The number of bytes into the current line
|
35
35
|
# of the lexer's current position (1-based).
|
36
36
|
#
|
37
|
-
# @return [
|
37
|
+
# @return [Integer]
|
38
38
|
def offset
|
39
39
|
return @offset unless @tok
|
40
40
|
@tok.source_range.start_pos.offset
|
@@ -71,8 +71,8 @@ module Sass
|
|
71
71
|
OPERATORS_REVERSE = Sass::Util.map_hash(OPERATORS) {|k, v| [v, k]}
|
72
72
|
|
73
73
|
TOKEN_NAMES = Sass::Util.map_hash(OPERATORS_REVERSE) {|k, v| [k, v.inspect]}.merge(
|
74
|
-
|
75
|
-
|
74
|
+
:const => "variable (e.g. $foo)",
|
75
|
+
:ident => "identifier (e.g. middle)")
|
76
76
|
|
77
77
|
# A list of operator strings ordered with longer names first
|
78
78
|
# so that `>` and `<` don't clobber `>=` and `<=`.
|
@@ -80,7 +80,9 @@ module Sass
|
|
80
80
|
|
81
81
|
# A sub-list of {OP_NAMES} that only includes operators
|
82
82
|
# with identifier names.
|
83
|
-
IDENT_OP_NAMES = OP_NAMES.select {|k,
|
83
|
+
IDENT_OP_NAMES = OP_NAMES.select {|k, _v| k =~ /^\w+/}
|
84
|
+
|
85
|
+
PARSEABLE_NUMBER = /(?:(\d*\.\d+)|(\d+))(?:[eE]([+-]?\d+))?(#{UNIT})?/
|
84
86
|
|
85
87
|
# A hash of regular expressions that are used for tokenizing.
|
86
88
|
REGULAR_EXPRESSIONS = {
|
@@ -89,9 +91,11 @@ module Sass
|
|
89
91
|
:single_line_comment => SINGLE_LINE_COMMENT,
|
90
92
|
:variable => /(\$)(#{IDENT})/,
|
91
93
|
:ident => /(#{IDENT})(\()?/,
|
92
|
-
:number =>
|
93
|
-
:unary_minus_number =>
|
94
|
+
:number => PARSEABLE_NUMBER,
|
95
|
+
:unary_minus_number => /-#{PARSEABLE_NUMBER}/,
|
94
96
|
:color => HEXCOLOR,
|
97
|
+
:id => /##{IDENT}/,
|
98
|
+
:selector => /&/,
|
95
99
|
:ident_op => /(#{Regexp.union(*IDENT_OP_NAMES.map do |s|
|
96
100
|
Regexp.new(Regexp.escape(s) + "(?!#{NMCHAR}|\Z)")
|
97
101
|
end)})/,
|
@@ -102,7 +106,7 @@ module Sass
|
|
102
106
|
private
|
103
107
|
|
104
108
|
def string_re(open, close)
|
105
|
-
/#{open}((?:\\.|\#(?!\{)|[^#{close}\\#])*)(#{close}|#\{)/
|
109
|
+
/#{open}((?:\\.|\#(?!\{)|[^#{close}\\#])*)(#{close}|#\{)/m
|
106
110
|
end
|
107
111
|
end
|
108
112
|
|
@@ -138,12 +142,12 @@ module Sass
|
|
138
142
|
}
|
139
143
|
|
140
144
|
# @param str [String, StringScanner] The source text to lex
|
141
|
-
# @param line [
|
145
|
+
# @param line [Integer] The 1-based line on which the SassScript appears.
|
142
146
|
# Used for error reporting and sourcemap building
|
143
|
-
# @param offset [
|
147
|
+
# @param offset [Integer] The 1-based character (not byte) offset in the line in the source.
|
144
148
|
# Used for error reporting and sourcemap building
|
145
149
|
# @param options [{Symbol => Object}] An options hash;
|
146
|
-
# see {file:SASS_REFERENCE.md#
|
150
|
+
# see {file:SASS_REFERENCE.md#Options the Sass options documentation}
|
147
151
|
def initialize(str, line, offset, options)
|
148
152
|
@scanner = str.is_a?(StringScanner) ? str : Sass::Util::MultibyteStringScanner.new(str)
|
149
153
|
@line = line
|
@@ -151,6 +155,8 @@ module Sass
|
|
151
155
|
@options = options
|
152
156
|
@interpolation_stack = []
|
153
157
|
@prev = nil
|
158
|
+
@tok = nil
|
159
|
+
@next_tok = nil
|
154
160
|
end
|
155
161
|
|
156
162
|
# Moves the lexer forward one token.
|
@@ -175,6 +181,13 @@ module Sass
|
|
175
181
|
end
|
176
182
|
end
|
177
183
|
|
184
|
+
# Returns the given character.
|
185
|
+
#
|
186
|
+
# @return [String]
|
187
|
+
def char(pos = @scanner.pos)
|
188
|
+
@scanner.string[pos, 1]
|
189
|
+
end
|
190
|
+
|
178
191
|
# Returns the next token without moving the lexer forward.
|
179
192
|
#
|
180
193
|
# @return [Token] The next token
|
@@ -185,16 +198,16 @@ module Sass
|
|
185
198
|
# Rewinds the underlying StringScanner
|
186
199
|
# to before the token returned by \{#peek}.
|
187
200
|
def unpeek!
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
end
|
201
|
+
return unless @tok
|
202
|
+
@scanner.pos = @tok.pos
|
203
|
+
@line = @tok.source_range.start_pos.line
|
204
|
+
@offset = @tok.source_range.start_pos.offset
|
193
205
|
end
|
194
206
|
|
195
207
|
# @return [Boolean] Whether or not there's more source text to lex.
|
196
208
|
def done?
|
197
|
-
|
209
|
+
return if @next_tok
|
210
|
+
whitespace unless after_interpolation? && !@interpolation_stack.empty?
|
198
211
|
@scanner.eos? && @tok.nil?
|
199
212
|
end
|
200
213
|
|
@@ -231,6 +244,11 @@ module Sass
|
|
231
244
|
private
|
232
245
|
|
233
246
|
def read_token
|
247
|
+
if (tok = @next_tok)
|
248
|
+
@next_tok = nil
|
249
|
+
return tok
|
250
|
+
end
|
251
|
+
|
234
252
|
return if done?
|
235
253
|
start_pos = source_position
|
236
254
|
value = token
|
@@ -246,13 +264,19 @@ module Sass
|
|
246
264
|
end
|
247
265
|
|
248
266
|
def token
|
249
|
-
if after_interpolation? && (
|
250
|
-
|
267
|
+
if after_interpolation? && (interp = @interpolation_stack.pop)
|
268
|
+
interp_type, interp_value = interp
|
269
|
+
if interp_type == :special_fun
|
270
|
+
return special_fun_body(interp_value)
|
271
|
+
else
|
272
|
+
raise "[BUG]: Unknown interp_type #{interp_type}" unless interp_type == :string
|
273
|
+
return string(interp_value, true)
|
274
|
+
end
|
251
275
|
end
|
252
276
|
|
253
|
-
variable || string(:double, false) || string(:single, false) || number || color ||
|
254
|
-
string(:uri, false) || raw(UNICODERANGE) || special_fun || special_val ||
|
255
|
-
ident || op
|
277
|
+
variable || string(:double, false) || string(:single, false) || number || id || color ||
|
278
|
+
selector || string(:uri, false) || raw(UNICODERANGE) || special_fun || special_val ||
|
279
|
+
ident_op || ident || op
|
256
280
|
end
|
257
281
|
|
258
282
|
def variable
|
@@ -271,18 +295,28 @@ module Sass
|
|
271
295
|
end
|
272
296
|
|
273
297
|
def string(re, open)
|
298
|
+
line, offset = @line, @offset
|
274
299
|
return unless scan(STRING_REGULAR_EXPRESSIONS[re][open])
|
300
|
+
if @scanner[0] =~ /([^\\]|^)\n/
|
301
|
+
filename = @options[:filename]
|
302
|
+
Sass::Util.sass_warn <<MESSAGE
|
303
|
+
DEPRECATION WARNING on line #{line}, column #{offset}#{" of #{filename}" if filename}:
|
304
|
+
Unescaped multiline strings are deprecated and will be removed in a future version of Sass.
|
305
|
+
To include a newline in a string, use "\\a" or "\\a " as in CSS.
|
306
|
+
MESSAGE
|
307
|
+
end
|
308
|
+
|
275
309
|
if @scanner[2] == '#{' # '
|
276
|
-
@
|
277
|
-
@offset
|
278
|
-
@
|
310
|
+
@interpolation_stack << [:string, re]
|
311
|
+
start_pos = Sass::Source::Position.new(@line, @offset - 2)
|
312
|
+
@next_tok = Token.new(:string_interpolation, range(start_pos), @scanner.pos - 2)
|
279
313
|
end
|
280
314
|
str =
|
281
315
|
if re == :uri
|
282
316
|
url = "#{'url(' unless open}#{@scanner[1]}#{')' unless @scanner[2] == '#{'}"
|
283
317
|
Script::Value::String.new(url)
|
284
318
|
else
|
285
|
-
Script::Value::String.new(@scanner[1]
|
319
|
+
Script::Value::String.new(Sass::Script::Value::String.value(@scanner[1]), :string)
|
286
320
|
end
|
287
321
|
[:string, str]
|
288
322
|
end
|
@@ -296,10 +330,12 @@ module Sass
|
|
296
330
|
# minus logic in the parser instead.
|
297
331
|
if @scanner.peek(1) == '-'
|
298
332
|
return if @scanner.pos == 0
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
333
|
+
unary_minus_allowed =
|
334
|
+
case @scanner.string[@scanner.pos - 1, 1]
|
335
|
+
when /\s/; true
|
336
|
+
when '/'; @scanner.pos != 1 && @scanner.string[@scanner.pos - 2, 1] == '*'
|
337
|
+
else; false
|
338
|
+
end
|
303
339
|
|
304
340
|
return unless unary_minus_allowed
|
305
341
|
return unless scan(REGULAR_EXPRESSIONS[:unary_minus_number])
|
@@ -310,37 +346,80 @@ module Sass
|
|
310
346
|
end
|
311
347
|
|
312
348
|
value = (@scanner[1] ? @scanner[1].to_f : @scanner[2].to_i) * (minus ? -1 : 1)
|
313
|
-
|
349
|
+
value *= 10**@scanner[3].to_i if @scanner[3]
|
350
|
+
script_number = Script::Value::Number.new(value, Array(@scanner[4]))
|
314
351
|
[:number, script_number]
|
315
352
|
end
|
316
353
|
|
354
|
+
def id
|
355
|
+
# Colors and ids are tough to tell apart, because they overlap but
|
356
|
+
# neither is a superset of the other. "#xyz" is an id but not a color,
|
357
|
+
# "#000" is a color but not an id, "#abc" is both, and "#0" is neither.
|
358
|
+
# We need to handle all these cases correctly.
|
359
|
+
#
|
360
|
+
# To do so, we first try to parse something as an id. If this works and
|
361
|
+
# the id is also a valid color, we return the color. Otherwise, we
|
362
|
+
# return the id. If it didn't parse as an id, we then try to parse it as
|
363
|
+
# a color. If *this* works, we return the color, and if it doesn't we
|
364
|
+
# give up and throw an error.
|
365
|
+
#
|
366
|
+
# IDs in properties are used in the Basic User Interface Module
|
367
|
+
# (http://www.w3.org/TR/css3-ui/).
|
368
|
+
return unless scan(REGULAR_EXPRESSIONS[:id])
|
369
|
+
if @scanner[0] =~ /^\#[0-9a-fA-F]+$/ && (@scanner[0].length == 4 || @scanner[0].length == 7)
|
370
|
+
return [:color, Script::Value::Color.from_hex(@scanner[0])]
|
371
|
+
end
|
372
|
+
[:ident, @scanner[0]]
|
373
|
+
end
|
374
|
+
|
317
375
|
def color
|
318
|
-
|
319
|
-
return unless
|
320
|
-
|
321
|
-
Colors must have either three or six digits: '#{s}'
|
322
|
-
MESSAGE
|
323
|
-
script_color = Script::Value::Color.from_hex(s)
|
376
|
+
return unless @scanner.match?(REGULAR_EXPRESSIONS[:color])
|
377
|
+
return unless @scanner[0].length == 4 || @scanner[0].length == 7
|
378
|
+
script_color = Script::Value::Color.from_hex(scan(REGULAR_EXPRESSIONS[:color]))
|
324
379
|
[:color, script_color]
|
325
380
|
end
|
326
381
|
|
382
|
+
def selector
|
383
|
+
start_pos = source_position
|
384
|
+
return unless scan(REGULAR_EXPRESSIONS[:selector])
|
385
|
+
script_selector = Script::Tree::Selector.new
|
386
|
+
script_selector.source_range = range(start_pos)
|
387
|
+
[:selector, script_selector]
|
388
|
+
end
|
389
|
+
|
327
390
|
def special_fun
|
328
|
-
|
329
|
-
return unless
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
391
|
+
prefix = scan(/((-[\w-]+-)?(calc|element)|expression|progid:[a-z\.]*)\(/i)
|
392
|
+
return unless prefix
|
393
|
+
special_fun_body(1, prefix)
|
394
|
+
end
|
395
|
+
|
396
|
+
def special_fun_body(parens, prefix = nil)
|
397
|
+
str = prefix || ''
|
398
|
+
while (scanned = scan(/.*?([()]|\#\{)/m))
|
399
|
+
str << scanned
|
400
|
+
if scanned[-1] == ?(
|
401
|
+
parens += 1
|
402
|
+
next
|
403
|
+
elsif scanned[-1] == ?)
|
404
|
+
parens -= 1
|
405
|
+
next unless parens == 0
|
406
|
+
else
|
407
|
+
raise "[BUG] Unreachable" unless @scanner[1] == '#{' # '
|
408
|
+
str.slice!(-2..-1)
|
409
|
+
@interpolation_stack << [:special_fun, parens]
|
410
|
+
start_pos = Sass::Source::Position.new(@line, @offset - 2)
|
411
|
+
@next_tok = Token.new(:string_interpolation, range(start_pos), @scanner.pos - 2)
|
412
|
+
end
|
413
|
+
|
414
|
+
return [:special_fun, Sass::Script::Value::String.new(str)]
|
415
|
+
end
|
416
|
+
|
417
|
+
scan(/.*/)
|
418
|
+
expected!('")"')
|
340
419
|
end
|
341
420
|
|
342
421
|
def special_val
|
343
|
-
return unless scan(
|
422
|
+
return unless scan(/!#{W}important/i)
|
344
423
|
[:string, Script::Value::String.new("!important")]
|
345
424
|
end
|
346
425
|
|
@@ -353,8 +432,9 @@ MESSAGE
|
|
353
432
|
def op
|
354
433
|
op = scan(REGULAR_EXPRESSIONS[:op])
|
355
434
|
return unless op
|
356
|
-
|
357
|
-
|
435
|
+
name = OPERATORS[op]
|
436
|
+
@interpolation_stack << nil if name == :begin_interpolation
|
437
|
+
[name]
|
358
438
|
end
|
359
439
|
|
360
440
|
def raw(rx)
|
@@ -368,7 +448,7 @@ MESSAGE
|
|
368
448
|
return unless str
|
369
449
|
c = str.count("\n")
|
370
450
|
@line += c
|
371
|
-
@offset = (c == 0 ? @offset + str.size : str.size - str.rindex("\n")
|
451
|
+
@offset = (c == 0 ? @offset + str.size : str.size - str.rindex("\n"))
|
372
452
|
str
|
373
453
|
end
|
374
454
|
|