sass 3.2.0.alpha.88 → 3.2.0.alpha.91
Sign up to get free protection for your applications and to get access to all the features.
- data/REVISION +1 -1
- data/VERSION +1 -1
- data/lib/sass/script/lexer.rb +6 -0
- data/lib/sass/scss/parser.rb +97 -4
- data/lib/sass/scss/rx.rb +5 -0
- data/lib/sass/scss/static_parser.rb +14 -1
- data/test/sass/scss/css_test.rb +44 -0
- data/test/sass/scss/scss_test.rb +38 -0
- metadata +5 -5
data/REVISION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
0f20305d2c2cff846f830634070e60bdb790e903
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.2.0.alpha.
|
1
|
+
3.2.0.alpha.91
|
data/lib/sass/script/lexer.rb
CHANGED
@@ -114,6 +114,12 @@ module Sass
|
|
114
114
|
[:single, true] => string_re('', "'"),
|
115
115
|
[:uri, false] => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
|
116
116
|
[:uri, true] => /(#{URLCHAR}*?)(#{W}\)|#\{)/,
|
117
|
+
# Defined in https://developer.mozilla.org/en/CSS/@-moz-document as a
|
118
|
+
# non-standard version of http://www.w3.org/TR/css3-conditional/
|
119
|
+
[:url_prefix, false] => /url-prefix\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
|
120
|
+
[:url_prefix, true] => /(#{URLCHAR}*?)(#{W}\)|#\{)/,
|
121
|
+
[:domain, false] => /domain\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
|
122
|
+
[:domain, true] => /(#{URLCHAR}*?)(#{W}\)|#\{)/,
|
117
123
|
}
|
118
124
|
|
119
125
|
# @param str [String, StringScanner] The source text to lex
|
data/lib/sass/scss/parser.rb
CHANGED
@@ -122,7 +122,10 @@ module Sass
|
|
122
122
|
end
|
123
123
|
|
124
124
|
DIRECTIVES = Set[:mixin, :include, :function, :return, :debug, :warn, :for,
|
125
|
-
:each, :while, :if, :else, :extend, :import, :media, :charset, :content
|
125
|
+
:each, :while, :if, :else, :extend, :import, :media, :charset, :content,
|
126
|
+
:_moz_document]
|
127
|
+
|
128
|
+
PREFIXED_DIRECTIVES = Set[:supports]
|
126
129
|
|
127
130
|
def directive
|
128
131
|
return unless tok(/@/)
|
@@ -131,6 +134,8 @@ module Sass
|
|
131
134
|
|
132
135
|
if dir = special_directive(name)
|
133
136
|
return dir
|
137
|
+
elsif dir = prefixed_directive(name)
|
138
|
+
return dir
|
134
139
|
end
|
135
140
|
|
136
141
|
# Most at-rules take expressions (e.g. @import),
|
@@ -138,7 +143,11 @@ module Sass
|
|
138
143
|
# Some take no arguments at all.
|
139
144
|
val = expr || selector
|
140
145
|
val = val ? ["@#{name} "] + Sass::Util.strip_string_array(val) : ["@#{name}"]
|
141
|
-
|
146
|
+
directive_body(val)
|
147
|
+
end
|
148
|
+
|
149
|
+
def directive_body(value)
|
150
|
+
node = node(Sass::Tree::DirectiveNode.new(value))
|
142
151
|
|
143
152
|
if tok(/\{/)
|
144
153
|
node.has_children = true
|
@@ -154,6 +163,11 @@ module Sass
|
|
154
163
|
DIRECTIVES.include?(sym) && send("#{sym}_directive")
|
155
164
|
end
|
156
165
|
|
166
|
+
def prefixed_directive(name)
|
167
|
+
sym = name.gsub(/^-[a-z0-9]+-/i, '').gsub('-', '_').to_sym
|
168
|
+
PREFIXED_DIRECTIVES.include?(sym) && send("#{sym}_directive", name)
|
169
|
+
end
|
170
|
+
|
157
171
|
def mixin_directive
|
158
172
|
name = tok! IDENT
|
159
173
|
args = sass_script(:parse_mixin_definition_arglist)
|
@@ -386,6 +400,78 @@ module Sass
|
|
386
400
|
node(Sass::Tree::CharsetNode.new(name))
|
387
401
|
end
|
388
402
|
|
403
|
+
# The document directive is specified in
|
404
|
+
# http://www.w3.org/TR/css3-conditional/, but Gecko allows the
|
405
|
+
# `url-prefix` and `domain` functions to omit quotation marks, contrary to
|
406
|
+
# the standard.
|
407
|
+
#
|
408
|
+
# We could parse all document directives according to Mozilla's syntax,
|
409
|
+
# but if someone's using e.g. @-webkit-document we don't want them to
|
410
|
+
# think WebKit works sans quotes.
|
411
|
+
def _moz_document_directive
|
412
|
+
res = ["@-moz-document "]
|
413
|
+
loop do
|
414
|
+
res << str{ss} << expr!(:moz_document_function)
|
415
|
+
break unless c = tok(/,/)
|
416
|
+
res << c
|
417
|
+
end
|
418
|
+
directive_body(res.flatten)
|
419
|
+
end
|
420
|
+
|
421
|
+
def moz_document_function
|
422
|
+
return unless val = interp_uri || _interp_string(:url_prefix) ||
|
423
|
+
_interp_string(:domain) || function(!:allow_var) || interpolation
|
424
|
+
ss
|
425
|
+
val
|
426
|
+
end
|
427
|
+
|
428
|
+
# http://www.w3.org/TR/css3-conditional/
|
429
|
+
def supports_directive(name)
|
430
|
+
value = str {expr!(:supports_condition)}
|
431
|
+
directive_body(["@#{name} #{value}".strip])
|
432
|
+
end
|
433
|
+
|
434
|
+
def supports_condition
|
435
|
+
supports_negation || supports_operator || supports_declaration_condition
|
436
|
+
end
|
437
|
+
|
438
|
+
def supports_negation
|
439
|
+
return unless tok(/not/i)
|
440
|
+
ss
|
441
|
+
expr!(:supports_condition_in_parens)
|
442
|
+
end
|
443
|
+
|
444
|
+
def supports_operator
|
445
|
+
return unless supports_condition_in_parens
|
446
|
+
tok!(/and|or/i)
|
447
|
+
begin
|
448
|
+
ss
|
449
|
+
expr!(:supports_condition_in_parens)
|
450
|
+
end while tok(/and|or/i)
|
451
|
+
true
|
452
|
+
end
|
453
|
+
|
454
|
+
def supports_condition_in_parens
|
455
|
+
return unless tok(/\(/); ss
|
456
|
+
if supports_condition
|
457
|
+
tok!(/\)/); ss
|
458
|
+
else
|
459
|
+
supports_declaration_body
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
def supports_declaration_condition
|
464
|
+
return unless tok(/\(/); ss
|
465
|
+
supports_declaration_body
|
466
|
+
end
|
467
|
+
|
468
|
+
def supports_declaration_body
|
469
|
+
tok!(IDENT); ss
|
470
|
+
tok!(/:/); ss
|
471
|
+
expr!(:expr); ss
|
472
|
+
tok!(/\)/); ss
|
473
|
+
end
|
474
|
+
|
389
475
|
def variable
|
390
476
|
return unless tok(/\$/)
|
391
477
|
name = tok!(IDENT)
|
@@ -751,9 +837,9 @@ MESSAGE
|
|
751
837
|
|
752
838
|
def term(allow_var)
|
753
839
|
if e = tok(NUMBER) ||
|
754
|
-
|
840
|
+
interp_uri ||
|
755
841
|
function(allow_var) ||
|
756
|
-
|
842
|
+
interp_string ||
|
757
843
|
tok(UNICODERANGE) ||
|
758
844
|
interp_ident ||
|
759
845
|
tok(HEXCOLOR) ||
|
@@ -794,6 +880,10 @@ MESSAGE
|
|
794
880
|
_interp_string(:double) || _interp_string(:single)
|
795
881
|
end
|
796
882
|
|
883
|
+
def interp_uri
|
884
|
+
_interp_string(:uri)
|
885
|
+
end
|
886
|
+
|
797
887
|
def _interp_string(type)
|
798
888
|
return unless start = tok(Sass::Script::Lexer::STRING_REGULAR_EXPRESSIONS[[type, false]])
|
799
889
|
res = [start]
|
@@ -888,6 +978,9 @@ MESSAGE
|
|
888
978
|
:selector_comma_sequence => "selector",
|
889
979
|
:simple_selector_sequence => "selector",
|
890
980
|
:import_arg => "file to import (string or url())",
|
981
|
+
:moz_document_function => "matching function (e.g. url-prefix(), domain())",
|
982
|
+
:supports_condition => "@supports condition (e.g. (display: flexbox))",
|
983
|
+
:supports_condition_in_parens => "@supports condition (e.g. (display: flexbox))",
|
891
984
|
}
|
892
985
|
|
893
986
|
TOK_NAMES = Sass::Util.to_hash(
|
data/lib/sass/scss/rx.rb
CHANGED
@@ -107,6 +107,11 @@ module Sass
|
|
107
107
|
TILDE = /#{W}~/
|
108
108
|
NOT = quote(":not(", Regexp::IGNORECASE)
|
109
109
|
|
110
|
+
# Defined in https://developer.mozilla.org/en/CSS/@-moz-document as a
|
111
|
+
# non-standard version of http://www.w3.org/TR/css3-conditional/
|
112
|
+
URL_PREFIX = /url-prefix\(#{W}(?:#{STRING}|#{URL})#{W}\)/i
|
113
|
+
DOMAIN = /domain\(#{W}(?:#{STRING}|#{URL})#{W}\)/i
|
114
|
+
|
110
115
|
# Custom
|
111
116
|
HEXCOLOR = /\#[0-9a-fA-F]+/
|
112
117
|
INTERP_START = /#\{/
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'sass/script/css_parser'
|
2
|
+
|
1
3
|
module Sass
|
2
4
|
module SCSS
|
3
5
|
# A parser for a static SCSS tree.
|
@@ -24,18 +26,29 @@ module Sass
|
|
24
26
|
|
25
27
|
private
|
26
28
|
|
29
|
+
def moz_document_function
|
30
|
+
return unless val = tok(URI) || tok(URL_PREFIX) || tok(DOMAIN) ||
|
31
|
+
function(!:allow_var)
|
32
|
+
ss
|
33
|
+
[val]
|
34
|
+
end
|
35
|
+
|
27
36
|
def variable; nil; end
|
28
37
|
def script_value; nil; end
|
29
38
|
def interpolation; nil; end
|
30
39
|
def var_expr; nil; end
|
31
40
|
def interp_string; s = tok(STRING) and [s]; end
|
41
|
+
def interp_uri; s = tok(URI) and [s]; end
|
32
42
|
def interp_ident(ident = IDENT); s = tok(ident) and [s]; end
|
33
43
|
def use_css_import?; true; end
|
34
44
|
|
35
45
|
def special_directive(name)
|
36
|
-
return unless
|
46
|
+
return unless %w[media import charset -moz-document].include?(name)
|
37
47
|
super
|
38
48
|
end
|
49
|
+
|
50
|
+
@sass_script_parser = Class.new(Sass::Script::CssParser)
|
51
|
+
@sass_script_parser.send(:include, ScriptParser)
|
39
52
|
end
|
40
53
|
end
|
41
54
|
end
|
data/test/sass/scss/css_test.rb
CHANGED
@@ -586,6 +586,50 @@ CSS
|
|
586
586
|
SCSS
|
587
587
|
end
|
588
588
|
|
589
|
+
def test_moz_document_directive
|
590
|
+
assert_equal <<CSS, render(<<SCSS)
|
591
|
+
@-moz-document url(http://www.w3.org/),
|
592
|
+
url-prefix(http://www.w3.org/Style/),
|
593
|
+
domain(mozilla.org),
|
594
|
+
regexp("^https:.*") {
|
595
|
+
.foo {
|
596
|
+
a: b; } }
|
597
|
+
CSS
|
598
|
+
@-moz-document url(http://www.w3.org/),
|
599
|
+
url-prefix(http://www.w3.org/Style/),
|
600
|
+
domain(mozilla.org),
|
601
|
+
regexp("^https:.*") {
|
602
|
+
.foo {a: b}
|
603
|
+
}
|
604
|
+
SCSS
|
605
|
+
end
|
606
|
+
|
607
|
+
def test_supports
|
608
|
+
assert_equal <<CSS, render(<<SCSS)
|
609
|
+
@supports (a: b) and (c: d) or (not (d: e)) and ((not (f: g)) or (not ((h: i) and (j: k)))) {
|
610
|
+
.foo {
|
611
|
+
a: b; } }
|
612
|
+
CSS
|
613
|
+
@supports (a: b) and (c: d) or (not (d: e)) and ((not (f: g)) or (not ((h: i) and (j: k)))) {
|
614
|
+
.foo {
|
615
|
+
a: b;
|
616
|
+
}
|
617
|
+
}
|
618
|
+
SCSS
|
619
|
+
|
620
|
+
assert_equal <<CSS, render(<<SCSS)
|
621
|
+
@-prefix-supports (a: b) and (c: d) or (not (d: e)) and ((not (f: g)) or (not ((h: i) and (j: k)))) {
|
622
|
+
.foo {
|
623
|
+
a: b; } }
|
624
|
+
CSS
|
625
|
+
@-prefix-supports (a: b) and (c: d) or (not (d: e)) and ((not (f: g)) or (not ((h: i) and (j: k)))) {
|
626
|
+
.foo {
|
627
|
+
a: b;
|
628
|
+
}
|
629
|
+
}
|
630
|
+
SCSS
|
631
|
+
end
|
632
|
+
|
589
633
|
## Selectors
|
590
634
|
|
591
635
|
# Taken from http://www.w3.org/TR/css3-selectors/#selectors
|
data/test/sass/scss/scss_test.rb
CHANGED
@@ -926,6 +926,44 @@ $vals: 1 2 3;
|
|
926
926
|
SCSS
|
927
927
|
end
|
928
928
|
|
929
|
+
def test_moz_document_interpolation
|
930
|
+
assert_equal <<CSS, render(<<SCSS)
|
931
|
+
@-moz-document url(http://sass-lang.com/),
|
932
|
+
url-prefix(http://sass-lang.com/docs),
|
933
|
+
domain(sass-lang.com),
|
934
|
+
domain("sass-lang.com") {
|
935
|
+
.foo {
|
936
|
+
a: b; } }
|
937
|
+
CSS
|
938
|
+
$domain: "sass-lang.com";
|
939
|
+
@-moz-document url(http://\#{$domain}/),
|
940
|
+
url-prefix(http://\#{$domain}/docs),
|
941
|
+
domain(\#{$domain}),
|
942
|
+
\#{domain($domain)} {
|
943
|
+
.foo {a: b}
|
944
|
+
}
|
945
|
+
SCSS
|
946
|
+
end
|
947
|
+
|
948
|
+
def test_random_directive_interpolation
|
949
|
+
assert_equal <<CSS, render(<<SCSS)
|
950
|
+
@foo url(http://sass-lang.com/),
|
951
|
+
domain("sass-lang.com"),
|
952
|
+
"foobarbaz",
|
953
|
+
foobarbaz {
|
954
|
+
.foo {
|
955
|
+
a: b; } }
|
956
|
+
CSS
|
957
|
+
$domain: "sass-lang.com";
|
958
|
+
@foo url(http://\#{$domain}/),
|
959
|
+
\#{domain($domain)},
|
960
|
+
"foo\#{'ba' + 'r'}baz",
|
961
|
+
foo\#{'ba' + 'r'}baz {
|
962
|
+
.foo {a: b}
|
963
|
+
}
|
964
|
+
SCSS
|
965
|
+
end
|
966
|
+
|
929
967
|
## Errors
|
930
968
|
|
931
969
|
def test_mixin_defs_only_at_toplevel
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sass
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 592303019
|
5
5
|
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 3
|
8
8
|
- 2
|
9
9
|
- 0
|
10
10
|
- alpha
|
11
|
-
-
|
12
|
-
version: 3.2.0.alpha.
|
11
|
+
- 91
|
12
|
+
version: 3.2.0.alpha.91
|
13
13
|
platform: ruby
|
14
14
|
authors:
|
15
15
|
- Nathan Weizenbaum
|
@@ -150,7 +150,9 @@ files:
|
|
150
150
|
- lib/sass/tree/return_node.rb
|
151
151
|
- lib/sass/tree/root_node.rb
|
152
152
|
- lib/sass/tree/content_node.rb
|
153
|
+
- lib/sass/tree/css_import_node.rb
|
153
154
|
- lib/sass/tree/variable_node.rb
|
155
|
+
- lib/sass/tree/warn_node.rb
|
154
156
|
- lib/sass/tree/visitors/base.rb
|
155
157
|
- lib/sass/tree/visitors/check_nesting.rb
|
156
158
|
- lib/sass/tree/visitors/convert.rb
|
@@ -159,9 +161,7 @@ files:
|
|
159
161
|
- lib/sass/tree/visitors/perform.rb
|
160
162
|
- lib/sass/tree/visitors/set_options.rb
|
161
163
|
- lib/sass/tree/visitors/to_css.rb
|
162
|
-
- lib/sass/tree/warn_node.rb
|
163
164
|
- lib/sass/tree/while_node.rb
|
164
|
-
- lib/sass/tree/css_import_node.rb
|
165
165
|
- lib/sass/tree/trace_node.rb
|
166
166
|
- lib/sass/media.rb
|
167
167
|
- lib/sass/util/multibyte_string_scanner.rb
|