haml-edge 3.1.41 → 3.1.42

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.
data/EDGE_GEM_VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.41
1
+ 3.1.42
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.41
1
+ 3.1.42
data/lib/sass/engine.rb CHANGED
@@ -509,16 +509,7 @@ WARNING
509
509
  # If value begins with url( or ",
510
510
  # it's a CSS @import rule and we don't want to touch it.
511
511
  if directive == "import"
512
- raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath import directives.",
513
- :line => @line + 1) unless line.children.empty?
514
- if (match = value.match(Sass::SCSS::RX::STRING) || value.match(Sass::SCSS::RX::URI)) &&
515
- !match.post_match.strip.empty? && match.post_match.strip[0] != ?,
516
- return Tree::DirectiveNode.new("@import #{value}")
517
- end
518
- value.split(/,\s*/).map do |f|
519
- f = $1 || $2 || $3 if f =~ Sass::SCSS::RX::STRING || f =~ Sass::SCSS::RX::URI
520
- Tree::ImportNode.new(f)
521
- end
512
+ parse_import(line, value)
522
513
  elsif directive == "mixin"
523
514
  parse_mixin_definition(line)
524
515
  elsif directive == "include"
@@ -597,6 +588,32 @@ WARNING
597
588
  nil
598
589
  end
599
590
 
591
+ def parse_import(line, value)
592
+ raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath import directives.",
593
+ :line => @line + 1) unless line.children.empty?
594
+
595
+ if (match = value.match(Sass::SCSS::RX::STRING) || value.match(Sass::SCSS::RX::URI)) &&
596
+ match.offset(0).first == 0 && !match.post_match.strip.empty? &&
597
+ match.post_match.strip[0] != ?,
598
+ # @import "filename" media-type
599
+ return Tree::DirectiveNode.new("@import #{value}")
600
+ end
601
+
602
+ value.split(/,\s*/).map do |f|
603
+ if f =~ Sass::SCSS::RX::URI
604
+ # All url()s are literal CSS @imports
605
+ next Tree::DirectiveNode.new("@import #{f}")
606
+ elsif f =~ Sass::SCSS::RX::STRING
607
+ f = $1 || $2
608
+ end
609
+
610
+ # http:// URLs are always literal CSS imports
611
+ next Tree::DirectiveNode.new("@import url(#{f})") if f =~ /^http:\/\//
612
+
613
+ Tree::ImportNode.new(f)
614
+ end
615
+ end
616
+
600
617
  MIXIN_DEF_RE = /^(?:=|@mixin)\s*(#{Sass::SCSS::RX::IDENT})(.*)$/
601
618
  def parse_mixin_definition(line)
602
619
  name, arg_string = line.text.scan(MIXIN_DEF_RE).first
@@ -292,7 +292,7 @@ MESSAGE
292
292
  end
293
293
 
294
294
  def special_fun
295
- return unless str1 = scan(/(calc|expression|progid:[a-z\.]*)\(/i)
295
+ return unless str1 = scan(/((-[\w-]+-)?calc|expression|progid:[a-z\.]*)\(/i)
296
296
  str2, _ = Haml::Shared.balance(@scanner, ?(, ?), 1)
297
297
  c = str2.count("\n")
298
298
  old_line = @line
@@ -200,13 +200,13 @@ module Sass
200
200
 
201
201
  def import_directive
202
202
  @expected = "string or url()"
203
- arg = tok(STRING) || tok!(URI)
203
+ arg = tok(STRING) || (uri = tok!(URI))
204
204
  path = @scanner[1] || @scanner[2] || @scanner[3]
205
205
  ss
206
206
 
207
207
  media = str {media_query_list}.strip
208
208
 
209
- if !media.strip.empty? || use_css_import?
209
+ if uri || path =~ /^http:\/\// || !media.strip.empty? || use_css_import?
210
210
  return node(Sass::Tree::DirectiveNode.new("@import #{arg} #{media}".strip))
211
211
  end
212
212
 
@@ -381,6 +381,17 @@ module Sass
381
381
  sel.to_a
382
382
  end
383
383
 
384
+ def selector_comma_sequence
385
+ return unless sel = _selector
386
+ selectors = [sel]
387
+ while tok(/,/)
388
+ ws = str{ss}
389
+ selectors << expr!(:_selector)
390
+ selectors[-1] = Selector::Sequence.new(["\n"] + selectors.last.members) if ws.include?("\n")
391
+ end
392
+ Selector::CommaSequence.new(selectors)
393
+ end
394
+
384
395
  def _selector
385
396
  # The combinator here allows the "> E" hack
386
397
  return unless val = combinator || simple_selector_sequence
@@ -533,12 +544,12 @@ MESSAGE
533
544
  end
534
545
 
535
546
  def negation
536
- return unless tok(NOT)
547
+ return unless name = tok(NOT) || tok(MOZ_ANY)
537
548
  ss
538
549
  @expected = "selector"
539
- sel = element_name || id_selector || class_selector || attrib || expr!(:pseudo)
550
+ sel = selector_comma_sequence
540
551
  tok!(/\)/)
541
- Selector::Negation.new(sel)
552
+ Selector::SelectorPseudoClass.new(name[1...-1], sel)
542
553
  end
543
554
 
544
555
  def declaration
@@ -722,7 +733,7 @@ MESSAGE
722
733
  :interp_ident => "identifier",
723
734
  :interp_name => "identifier",
724
735
  :expr => "expression (e.g. 1px, bold)",
725
- :_selector => "selector",
736
+ :selector_comma_sequence => "selector",
726
737
  :simple_selector_sequence => "selector",
727
738
  }
728
739
 
data/lib/sass/scss/rx.rb CHANGED
@@ -109,6 +109,7 @@ module Sass
109
109
  # Custom
110
110
  HEXCOLOR = /\#[0-9a-fA-F]+/
111
111
  INTERP_START = /#\{/
112
+ MOZ_ALL = quote(":-moz-any(", Regexp::IGNORECASE)
112
113
 
113
114
  STRING1_NOINTERP = /\"((?:[^\n\r\f\\"#]|#(?!\{)|\\#{NL}|#{ESCAPE})*)\"/
114
115
  STRING2_NOINTERP = /\'((?:[^\n\r\f\\'#]|#(?!\{)|\\#{NL}|#{ESCAPE})*)\'/
@@ -17,14 +17,8 @@ module Sass
17
17
  # @raise [Sass::SyntaxError] if there's a syntax error in the selector
18
18
  def parse_selector(filename)
19
19
  init_scanner!
20
- selectors = [expr!(:_selector)]
21
- while tok(/,/)
22
- ws = str{ss}
23
- selectors << expr!(:_selector)
24
- selectors[-1] = Selector::Sequence.new(["\n"] + selectors.last.members) if ws.include?("\n")
25
- end
20
+ seq = expr!(:selector_comma_sequence)
26
21
  expected("selector") unless @scanner.eos?
27
- seq = Selector::CommaSequence.new(selectors)
28
22
  seq.line = @line
29
23
  seq.filename = filename
30
24
  seq
@@ -61,6 +61,13 @@ module Sass
61
61
  members.map {|m| m.inspect}.join(", ")
62
62
  end
63
63
 
64
+ # @see Simple#to_a
65
+ def to_a
66
+ arr = Haml::Util.intersperse(@members.map {|m| m.to_a}, ", ").flatten
67
+ arr.delete("\n")
68
+ arr
69
+ end
70
+
64
71
  private
65
72
 
66
73
  def _hash
@@ -78,10 +78,10 @@ module Sass
78
78
  return sels if sels.any? {|sel2| eql?(sel2)}
79
79
  sels_with_ix = Haml::Util.enum_with_index(sels)
80
80
  _, i =
81
- if self.is_a?(Pseudo) || self.is_a?(Negation)
81
+ if self.is_a?(Pseudo) || self.is_a?(SelectorPseudoClass)
82
82
  sels_with_ix.find {|sel, _| sel.is_a?(Pseudo) && sels.last.type == :element}
83
83
  else
84
- sels_with_ix.find {|sel, _| sel.is_a?(Pseudo) || sel.is_a?(Negation)}
84
+ sels_with_ix.find {|sel, _| sel.is_a?(Pseudo) || sel.is_a?(SelectorPseudoClass)}
85
85
  end
86
86
  return sels + [self] unless i
87
87
  return sels[0...i] + [self] + sels[i..-1]
data/lib/sass/selector.rb CHANGED
@@ -332,21 +332,29 @@ module Sass
332
332
  end
333
333
  end
334
334
 
335
- # A negation pseudoclass selector (e.g. `:not(.foo)`).
336
- class Negation < Simple
337
- # The selector to negate.
335
+ # A pseudoclass selector whose argument is itself a selector
336
+ # (e.g. `:not(.foo)` or `:-moz-all(.foo, .bar)`).
337
+ class SelectorPseudoClass < Simple
338
+ # The name of the pseudoclass.
338
339
  #
339
- # @return [Selector]
340
+ # @return [String]
341
+ attr_reader :name
342
+
343
+ # The selector argument.
344
+ #
345
+ # @return [Selector::Sequence]
340
346
  attr_reader :selector
341
347
 
342
- # @param [Selector] The selector to negate
343
- def initialize(selector)
348
+ # @param [String] The name of the pseudoclass
349
+ # @param [Selector::Sequence] The selector argument
350
+ def initialize(name, selector)
351
+ @name = name
344
352
  @selector = selector
345
353
  end
346
354
 
347
355
  # @see Selector#to_a
348
356
  def to_a
349
- [":not("] + @selector.to_a + [")"]
357
+ [":", @name, "("] + @selector.to_a + [")"]
350
358
  end
351
359
  end
352
360
  end
@@ -671,11 +671,15 @@ SCSS
671
671
  assert_renders <<SASS, <<SCSS
672
672
  @import foo
673
673
 
674
+ @import url(bar.css)
675
+
674
676
  foo
675
677
  bar: baz
676
678
  SASS
677
679
  @import "foo";
678
680
 
681
+ @import url(bar.css);
682
+
679
683
  foo {
680
684
  bar: baz; }
681
685
  SCSS
@@ -683,11 +687,15 @@ SCSS
683
687
  assert_renders <<SASS, <<SCSS
684
688
  @import foo.css
685
689
 
690
+ @import url(bar.css)
691
+
686
692
  foo
687
693
  bar: baz
688
694
  SASS
689
695
  @import "foo.css";
690
696
 
697
+ @import url(bar.css);
698
+
691
699
  foo {
692
700
  bar: baz; }
693
701
  SCSS
@@ -695,7 +703,6 @@ SCSS
695
703
 
696
704
  def test_import_as_directive_in_sass
697
705
  assert_equal "@import foo.css\n", to_sass('@import "foo.css"')
698
- assert_equal "@import foo.css\n", to_sass('@import url(foo.css)')
699
706
  end
700
707
 
701
708
  def test_import_as_directive_in_scss
@@ -487,8 +487,21 @@ CSS
487
487
  end
488
488
 
489
489
  def test_css_import
490
- assert_equal("@import url(./fonts.css) screen;\n", render("@import url(./fonts.css) screen"))
491
- assert_equal("@import \"./fonts.css\" screen;\n", render("@import \"./fonts.css\" screen"))
490
+ assert_equal("@import url(./fonts.css);\n", render("@import \"./fonts.css\""))
491
+ end
492
+
493
+ def test_media_import
494
+ assert_equal("@import \"./fonts.sass\" all;\n",
495
+ render("@import \"./fonts.sass\" all"))
496
+ end
497
+
498
+ def test_http_import
499
+ assert_equal("@import url(http://fonts.googleapis.com/css?family=Droid+Sans);\n",
500
+ render("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\""))
501
+ end
502
+
503
+ def test_url_import
504
+ assert_equal("@import url(fonts.sass);\n", render("@import url(fonts.sass)"))
492
505
  end
493
506
 
494
507
  def test_sass_import
@@ -382,7 +382,10 @@ SCSS
382
382
  def test_calc_function
383
383
  assert_parses <<SCSS
384
384
  foo {
385
- a: 12px calc(100%/3 - 2*1em - 2*1px); }
385
+ a: 12px calc(100%/3 - 2*1em - 2*1px);
386
+ b: 12px -moz-calc(100%/3 - 2*1em - 2*1px);
387
+ b: 12px -webkit-calc(100%/3 - 2*1em - 2*1px);
388
+ b: 12px -foobar-calc(100%/3 - 2*1em - 2*1px); }
386
389
  SCSS
387
390
  end
388
391
 
@@ -703,6 +706,18 @@ SCSS
703
706
 
704
707
  assert_selector_parses(':not(:hover)')
705
708
  assert_selector_parses(':not(:nth-child(2n + 3))')
709
+
710
+ # Not technically allowed, but what the heck
711
+ assert_selector_parses(':not(:not(#foo))')
712
+ assert_selector_parses(':not(a#foo.bar)')
713
+ assert_selector_parses(':not(#foo .bar > baz)')
714
+ assert_selector_parses(':not(h1, h2, h3)')
715
+ end
716
+
717
+ def test_moz_any_selector
718
+ assert_selector_parses(':-moz-any(h1, h2, h3)')
719
+ assert_selector_parses(':-moz-any(.foo)')
720
+ assert_selector_parses(':-moz-any(foo bar, .baz > .bang)')
706
721
  end
707
722
 
708
723
  def test_namespaced_selectors
@@ -212,11 +212,24 @@ SCSS
212
212
  def test_css_import_directive
213
213
  assert_equal "@import url(foo.css);\n", render('@import "foo.css";')
214
214
  assert_equal "@import url(foo.css);\n", render("@import 'foo.css';")
215
- assert_equal "@import url(foo.css);\n", render('@import url("foo.css");')
216
- assert_equal "@import url(foo.css);\n", render("@import url('foo.css');")
215
+ assert_equal "@import url(\"foo.css\");\n", render('@import url("foo.css");')
216
+ assert_equal "@import url('foo.css');\n", render("@import url('foo.css');")
217
217
  assert_equal "@import url(foo.css);\n", render('@import url(foo.css);')
218
218
  end
219
219
 
220
+ def test_media_import
221
+ assert_equal("@import \"./fonts.sass\" all;\n", render("@import \"./fonts.sass\" all;"))
222
+ end
223
+
224
+ def test_http_import
225
+ assert_equal("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\";\n",
226
+ render("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\";"))
227
+ end
228
+
229
+ def test_url_import
230
+ assert_equal("@import url(fonts.sass);\n", render("@import url(fonts.sass);"))
231
+ end
232
+
220
233
  def test_block_comment_in_script
221
234
  assert_equal <<CSS, render(<<SCSS)
222
235
  foo {
@@ -4,7 +4,7 @@ $preconst: hello
4
4
  pre-mixin: here
5
5
 
6
6
  @import importee.sass, scss_importee, "basic.sass", basic.css, ../results/complex.css
7
- @import url(partial.sass)
7
+ @import partial.sass
8
8
 
9
9
  nonimported
10
10
  :myconst $preconst
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml-edge
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.41
4
+ version: 3.1.42
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Weizenbaum