haml 3.1.8 → 3.2.0.alpha.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of haml might be problematic. Click here for more details.

Files changed (148) hide show
  1. data/CONTRIBUTING +1 -1
  2. data/README.md +2 -2
  3. data/REVISION +1 -1
  4. data/Rakefile +16 -41
  5. data/VERSION +1 -1
  6. data/VERSION_NAME +1 -1
  7. data/lib/haml/buffer.rb +1 -5
  8. data/lib/haml/compiler.rb +7 -8
  9. data/lib/haml/exec.rb +1 -1
  10. data/lib/haml/helpers.rb +3 -5
  11. data/lib/haml/helpers/action_view_mods.rb +5 -21
  12. data/lib/haml/parser.rb +1 -1
  13. data/lib/haml/template.rb +1 -3
  14. data/lib/haml/util.rb +1 -1
  15. data/test/haml/engine_test.rb +12 -51
  16. data/test/haml/helper_test.rb +8 -25
  17. data/test/haml/html2haml_test.rb +1 -1
  18. data/test/haml/results/whitespace_handling.xhtml +50 -46
  19. data/test/haml/template_test.rb +2 -28
  20. data/test/haml/templates/partial_layout.haml +1 -4
  21. data/test/linked_rails.rb +4 -4
  22. data/vendor/sass/VERSION +1 -1
  23. data/vendor/sass/doc-src/SASS_CHANGELOG.md +2 -115
  24. data/vendor/sass/doc-src/SASS_REFERENCE.md +4 -12
  25. data/vendor/sass/lib/sass.rb +0 -1
  26. data/vendor/sass/lib/sass/cache_stores/base.rb +1 -3
  27. data/vendor/sass/lib/sass/cache_stores/filesystem.rb +0 -2
  28. data/vendor/sass/lib/sass/css.rb +1 -2
  29. data/vendor/sass/lib/sass/engine.rb +23 -39
  30. data/vendor/sass/lib/sass/environment.rb +0 -11
  31. data/vendor/sass/lib/sass/exec.rb +1 -14
  32. data/vendor/sass/lib/sass/importers/base.rb +1 -2
  33. data/vendor/sass/lib/sass/importers/filesystem.rb +13 -18
  34. data/vendor/sass/lib/sass/less.rb +2 -2
  35. data/vendor/sass/lib/sass/plugin.rb +8 -4
  36. data/vendor/sass/lib/sass/plugin/compiler.rb +17 -42
  37. data/vendor/sass/lib/sass/plugin/configuration.rb +2 -0
  38. data/vendor/sass/lib/sass/railtie.rb +1 -1
  39. data/vendor/sass/lib/sass/script/funcall.rb +1 -14
  40. data/vendor/sass/lib/sass/script/functions.rb +1 -44
  41. data/vendor/sass/lib/sass/script/interpolation.rb +0 -9
  42. data/vendor/sass/lib/sass/script/lexer.rb +1 -6
  43. data/vendor/sass/lib/sass/script/list.rb +0 -7
  44. data/vendor/sass/lib/sass/script/literal.rb +0 -5
  45. data/vendor/sass/lib/sass/script/node.rb +0 -8
  46. data/vendor/sass/lib/sass/script/number.rb +5 -28
  47. data/vendor/sass/lib/sass/script/operation.rb +0 -8
  48. data/vendor/sass/lib/sass/script/parser.rb +5 -12
  49. data/vendor/sass/lib/sass/script/string_interpolation.rb +0 -9
  50. data/vendor/sass/lib/sass/script/unary_operation.rb +0 -7
  51. data/vendor/sass/lib/sass/script/variable.rb +0 -5
  52. data/vendor/sass/lib/sass/scss/parser.rb +38 -78
  53. data/vendor/sass/lib/sass/scss/rx.rb +1 -2
  54. data/vendor/sass/lib/sass/scss/static_parser.rb +2 -2
  55. data/vendor/sass/lib/sass/shared.rb +1 -1
  56. data/vendor/sass/lib/sass/tree/comment_node.rb +11 -24
  57. data/vendor/sass/lib/sass/tree/debug_node.rb +1 -1
  58. data/vendor/sass/lib/sass/tree/each_node.rb +1 -1
  59. data/vendor/sass/lib/sass/tree/extend_node.rb +1 -1
  60. data/vendor/sass/lib/sass/tree/for_node.rb +2 -2
  61. data/vendor/sass/lib/sass/tree/function_node.rb +1 -1
  62. data/vendor/sass/lib/sass/tree/if_node.rb +14 -1
  63. data/vendor/sass/lib/sass/tree/mixin_def_node.rb +1 -1
  64. data/vendor/sass/lib/sass/tree/mixin_node.rb +2 -2
  65. data/vendor/sass/lib/sass/tree/node.rb +5 -2
  66. data/vendor/sass/lib/sass/tree/prop_node.rb +9 -2
  67. data/vendor/sass/lib/sass/tree/return_node.rb +1 -1
  68. data/vendor/sass/lib/sass/tree/rule_node.rb +2 -9
  69. data/vendor/sass/lib/sass/tree/variable_node.rb +1 -1
  70. data/vendor/sass/lib/sass/tree/visitors/check_nesting.rb +18 -17
  71. data/vendor/sass/lib/sass/tree/visitors/convert.rb +5 -10
  72. data/vendor/sass/lib/sass/tree/visitors/perform.rb +19 -50
  73. data/vendor/sass/lib/sass/tree/visitors/to_css.rb +15 -9
  74. data/vendor/sass/lib/sass/tree/warn_node.rb +1 -1
  75. data/vendor/sass/lib/sass/tree/while_node.rb +1 -1
  76. data/vendor/sass/lib/sass/util.rb +6 -58
  77. data/vendor/sass/sass.gemspec +1 -2
  78. data/vendor/sass/test/sass/cache_test.rb +0 -15
  79. data/vendor/sass/test/sass/conversion_test.rb +6 -2
  80. data/vendor/sass/test/sass/css2sass_test.rb +0 -9
  81. data/vendor/sass/test/sass/engine_test.rb +26 -124
  82. data/vendor/sass/test/sass/functions_test.rb +0 -13
  83. data/vendor/sass/test/sass/importer_test.rb +0 -110
  84. data/vendor/sass/test/sass/plugin_test.rb +13 -16
  85. data/vendor/sass/test/sass/script_conversion_test.rb +0 -2
  86. data/vendor/sass/test/sass/script_test.rb +0 -18
  87. data/vendor/sass/test/sass/scss/css_test.rb +1 -7
  88. data/vendor/sass/test/sass/scss/scss_test.rb +13 -37
  89. data/vendor/sass/test/sass/test_helper.rb +1 -1
  90. data/vendor/sass/test/sass/util_test.rb +0 -12
  91. data/vendor/sass/vendor/fssm/LICENSE +1 -1
  92. data/vendor/sass/vendor/fssm/README.markdown +27 -55
  93. data/vendor/sass/vendor/fssm/Rakefile +54 -6
  94. data/vendor/sass/vendor/fssm/VERSION.yml +5 -0
  95. data/vendor/sass/vendor/fssm/example.rb +3 -6
  96. data/vendor/sass/vendor/fssm/fssm.gemspec +70 -17
  97. data/vendor/sass/vendor/fssm/lib/fssm.rb +3 -7
  98. data/vendor/sass/vendor/fssm/lib/fssm/backends/fsevents.rb +1 -1
  99. data/vendor/sass/vendor/fssm/lib/fssm/backends/inotify.rb +2 -2
  100. data/vendor/sass/vendor/fssm/lib/fssm/backends/polling.rb +2 -2
  101. data/vendor/sass/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +10 -10
  102. data/vendor/sass/vendor/fssm/lib/fssm/monitor.rb +9 -19
  103. data/vendor/sass/vendor/fssm/lib/fssm/path.rb +21 -24
  104. data/vendor/sass/vendor/fssm/lib/fssm/pathname.rb +479 -13
  105. data/vendor/sass/vendor/fssm/lib/fssm/state/directory.rb +11 -29
  106. data/vendor/sass/vendor/fssm/lib/fssm/state/file.rb +1 -1
  107. data/vendor/sass/vendor/fssm/lib/fssm/support.rb +12 -41
  108. data/vendor/sass/vendor/fssm/lib/fssm/tree.rb +6 -6
  109. data/vendor/sass/vendor/fssm/profile/prof-cache.rb +3 -3
  110. data/vendor/sass/vendor/fssm/profile/prof-pathname.rb +7 -7
  111. data/vendor/sass/vendor/fssm/spec/path_spec.rb +15 -36
  112. data/vendor/sass/vendor/fssm/spec/spec_helper.rb +6 -6
  113. metadata +78 -125
  114. data/lib/haml/helpers/rails_323_textarea_fix.rb +0 -41
  115. data/test/gemfiles/Gemfile.rails-2.0.x +0 -8
  116. data/test/gemfiles/Gemfile.rails-2.0.x.lock +0 -38
  117. data/test/gemfiles/Gemfile.rails-2.1.x +0 -8
  118. data/test/gemfiles/Gemfile.rails-2.1.x.lock +0 -38
  119. data/test/gemfiles/Gemfile.rails-2.2.x +0 -8
  120. data/test/gemfiles/Gemfile.rails-2.2.x.lock +0 -38
  121. data/test/gemfiles/Gemfile.rails-2.3.x +0 -8
  122. data/test/gemfiles/Gemfile.rails-2.3.x.lock +0 -40
  123. data/test/gemfiles/Gemfile.rails-3.0.x +0 -8
  124. data/test/gemfiles/Gemfile.rails-3.0.x.lock +0 -85
  125. data/test/gemfiles/Gemfile.rails-3.1.x +0 -8
  126. data/test/gemfiles/Gemfile.rails-3.1.x.lock +0 -97
  127. data/test/gemfiles/Gemfile.rails-3.2.x +0 -8
  128. data/test/gemfiles/Gemfile.rails-3.2.x.lock +0 -95
  129. data/test/gemfiles/Gemfile.rails-xss-2.3.x +0 -9
  130. data/test/gemfiles/Gemfile.rails-xss-2.3.x.lock +0 -42
  131. data/vendor/sass/lib/sass/logger.rb +0 -15
  132. data/vendor/sass/lib/sass/logger/base.rb +0 -32
  133. data/vendor/sass/lib/sass/logger/log_level.rb +0 -49
  134. data/vendor/sass/lib/sass/tree/visitors/deep_copy.rb +0 -87
  135. data/vendor/sass/lib/sass/tree/visitors/set_options.rb +0 -97
  136. data/vendor/sass/test/Gemfile +0 -4
  137. data/vendor/sass/test/Gemfile.lock +0 -19
  138. data/vendor/sass/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
  139. data/vendor/sass/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
  140. data/vendor/sass/test/sass/logger_test.rb +0 -58
  141. data/vendor/sass/test/sass/templates/bork5.sass +0 -3
  142. data/vendor/sass/test/sass/templates/nested_bork5.sass +0 -2
  143. data/vendor/sass/vendor/fssm/Gemfile +0 -3
  144. data/vendor/sass/vendor/fssm/lib/fssm/backends/rbfsevent.rb +0 -42
  145. data/vendor/sass/vendor/fssm/lib/fssm/version.rb +0 -3
  146. data/vendor/sass/vendor/fssm/profile/prof-pathname-rubinius.rb +0 -35
  147. data/vendor/sass/vendor/fssm/spec/count_down_latch.rb +0 -151
  148. data/vendor/sass/vendor/fssm/spec/monitor_spec.rb +0 -202
@@ -112,7 +112,6 @@ module Sass
112
112
  INTERP_START = /#\{/
113
113
  MOZ_ANY = quote(":-moz-any(", Regexp::IGNORECASE)
114
114
 
115
- IDENT_HYPHEN_INTERP = /-(?=#\{)/
116
115
  STRING1_NOINTERP = /\"((?:[^\n\r\f\\"#]|#(?!\{)|\\#{NL}|#{ESCAPE})*)\"/
117
116
  STRING2_NOINTERP = /\'((?:[^\n\r\f\\'#]|#(?!\{)|\\#{NL}|#{ESCAPE})*)\'/
118
117
  STRING_NOINTERP = /#{STRING1_NOINTERP}|#{STRING2_NOINTERP}/
@@ -120,7 +119,7 @@ module Sass
120
119
  # We could use it for 1.9 only, but I don't want to introduce a cross-version
121
120
  # behavior difference.
122
121
  # In any case, almost all CSS idents will be matched by this.
123
- STATIC_VALUE = /(-?#{NMSTART}|#{STRING_NOINTERP}|\s(?!%)|#[a-f0-9]|[,%]|#{NUM}|\!important)+(?=[;}])/i
122
+ STATIC_VALUE = /(-?#{NMSTART}|#{STRING_NOINTERP}|\s(?!%)|#[a-f0-9]|[,%]|#{NUM})+(?=[;}])/i
124
123
 
125
124
  STATIC_SELECTOR = /(#{NMCHAR}|\s|[,>+*]|[:#.]#{NMSTART})+(?=[{])/i
126
125
  end
@@ -13,12 +13,12 @@ module Sass
13
13
  # Used for error reporting.
14
14
  # @return [Selector::CommaSequence] The parsed selector
15
15
  # @raise [Sass::SyntaxError] if there's a syntax error in the selector
16
- def parse_selector
16
+ def parse_selector(filename)
17
17
  init_scanner!
18
18
  seq = expr!(:selector_comma_sequence)
19
19
  expected("selector") unless @scanner.eos?
20
20
  seq.line = @line
21
- seq.filename = @filename
21
+ seq.filename = filename
22
22
  seq
23
23
  end
24
24
 
@@ -17,7 +17,7 @@ module Sass
17
17
  # @return [String] The text remaining in the scanner after all `#{`s have been processed
18
18
  def handle_interpolation(str)
19
19
  scan = StringScanner.new(str)
20
- yield scan while scan.scan(/(.*?)(\\*)\#\{/m)
20
+ yield scan while scan.scan(/(.*?)(\\*)\#\{/)
21
21
  scan.rest
22
22
  end
23
23
 
@@ -6,18 +6,9 @@ module Sass::Tree
6
6
  # @see Sass::Tree
7
7
  class CommentNode < Node
8
8
  # The text of the comment, not including `/*` and `*/`.
9
- # Interspersed with {Sass::Script::Node}s representing `#{}`-interpolation
10
- # if this is a loud comment.
11
- #
12
- # @return [Array<String, Sass::Script::Node>]
13
- attr_accessor :value
14
-
15
- # The text of the comment
16
- # after any interpolated SassScript has been resolved.
17
- # Only set once \{Tree::Visitors::Perform} has been run.
18
9
  #
19
10
  # @return [String]
20
- attr_accessor :resolved_value
11
+ attr_accessor :value
21
12
 
22
13
  # Whether the comment is loud.
23
14
  #
@@ -32,13 +23,14 @@ module Sass::Tree
32
23
  # @return [Boolean]
33
24
  attr_accessor :silent
34
25
 
35
- # @param value [Array<String, Sass::Script::Node>] See \{#value}
26
+ # @param value [String] See \{#value}
36
27
  # @param silent [Boolean] See \{#silent}
37
- # @param loud [Boolean] See \{#loud}
38
- def initialize(value, silent, loud)
39
- @value = Sass::Util.with_extracted_values(value) {|str| normalize_indentation str}
28
+ def initialize(value, silent)
29
+ @lines = []
40
30
  @silent = silent
41
- @loud = loud
31
+ @value = normalize_indentation value
32
+ @loud = @value =~ %r{^(/[\/\*])?!}
33
+ @value.sub!("#{$1}!", $1.to_s) if @loud
42
34
  super()
43
35
  end
44
36
 
@@ -48,7 +40,7 @@ module Sass::Tree
48
40
  # @return [Boolean] Whether or not this node and the other object
49
41
  # are the same
50
42
  def ==(other)
51
- self.class == other.class && value == other.value && silent == other.silent && loud == other.loud
43
+ self.class == other.class && value == other.value && silent == other.silent
52
44
  end
53
45
 
54
46
  # Returns `true` if this is a silent comment
@@ -65,14 +57,9 @@ module Sass::Tree
65
57
  end
66
58
  end
67
59
 
68
- # Returns the number of lines in the comment.
69
- #
70
- # @return [Fixnum]
71
- def lines
72
- @value.inject(0) do |s, e|
73
- next s + e.count("\n") if e.is_a?(String)
74
- next s
75
- end
60
+ # Returns whether this comment should be interpolated for dynamic comment generation.
61
+ def evaluated?
62
+ @loud
76
63
  end
77
64
 
78
65
  private
@@ -6,7 +6,7 @@ module Sass
6
6
  class DebugNode < Node
7
7
  # The expression to print.
8
8
  # @return [Script::Node]
9
- attr_accessor :expr
9
+ attr_reader :expr
10
10
 
11
11
  # @param expr [Script::Node] The expression to print
12
12
  def initialize(expr)
@@ -11,7 +11,7 @@ module Sass::Tree
11
11
 
12
12
  # The parse tree for the list.
13
13
  # @param [Script::Node]
14
- attr_accessor :list
14
+ attr_reader :list
15
15
 
16
16
  # @param var [String] The name of the loop variable
17
17
  # @param list [Script::Node] The parse tree for the list
@@ -15,7 +15,7 @@ module Sass::Tree
15
15
  # representing `#{}`-interpolation.
16
16
  #
17
17
  # @return [Array<String, Sass::Script::Node>]
18
- attr_accessor :selector
18
+ attr_reader :selector
19
19
 
20
20
  # @param selector [Array<String, Sass::Script::Node>]
21
21
  # The CSS selector to extend,
@@ -11,11 +11,11 @@ module Sass::Tree
11
11
 
12
12
  # The parse tree for the initial expression.
13
13
  # @return [Script::Node]
14
- attr_accessor :from
14
+ attr_reader :from
15
15
 
16
16
  # The parse tree for the final expression.
17
17
  # @return [Script::Node]
18
- attr_accessor :to
18
+ attr_reader :to
19
19
 
20
20
  # Whether to include `to` in the loop or stop just before.
21
21
  # @return [Boolean]
@@ -13,7 +13,7 @@ module Sass
13
13
  # the default value of the argument
14
14
  #
15
15
  # @return [Array<Script::Node>]
16
- attr_accessor :args
16
+ attr_reader :args
17
17
 
18
18
  # @param name [String] The function name
19
19
  # @param args [Array<(Script::Node, Script::Node)>] The arguments for the function.
@@ -13,7 +13,7 @@ module Sass::Tree
13
13
  # If this is nil, this is an `@else` node, not an `@else if`.
14
14
  #
15
15
  # @return [Script::Expr]
16
- attr_accessor :expr
16
+ attr_reader :expr
17
17
 
18
18
  # The next {IfNode} in the if-else list, or `nil`.
19
19
  #
@@ -35,6 +35,12 @@ module Sass::Tree
35
35
  @last_else = node
36
36
  end
37
37
 
38
+ # @see Node#options=
39
+ def options=(options)
40
+ super
41
+ self.else.options = options if self.else
42
+ end
43
+
38
44
  def _dump(f)
39
45
  Marshal.dump([self.expr, self.else, self.children])
40
46
  end
@@ -48,5 +54,12 @@ module Sass::Tree
48
54
  node.else ? node.else.instance_variable_get('@last_else') : node)
49
55
  node
50
56
  end
57
+
58
+ # @see Node#deep_copy
59
+ def deep_copy
60
+ node = super
61
+ node.else = self.else.deep_copy if self.else
62
+ node
63
+ end
51
64
  end
52
65
  end
@@ -13,7 +13,7 @@ module Sass
13
13
  # and the parse tree for the default value of the argument.
14
14
  #
15
15
  # @return [Array<(Script::Node, Script::Node)>]
16
- attr_accessor :args
16
+ attr_reader :args
17
17
 
18
18
  # @param name [String] The mixin name
19
19
  # @param args [Array<(Script::Node, Script::Node)>] See \{#args}
@@ -13,11 +13,11 @@ module Sass::Tree
13
13
 
14
14
  # The arguments to the mixin.
15
15
  # @return [Array<Script::Node>]
16
- attr_accessor :args
16
+ attr_reader :args
17
17
 
18
18
  # A hash from keyword argument names to values.
19
19
  # @return [{String => Script::Node}]
20
- attr_accessor :keywords
20
+ attr_reader :keywords
21
21
 
22
22
  # @param name [String] The name of the mixin
23
23
  # @param args [Array<Script::Node>] See \{#args}
@@ -65,7 +65,8 @@ module Sass
65
65
  # @param options [{Symbol => Object}] The options
66
66
  # @see #options
67
67
  def options=(options)
68
- Sass::Tree::Visitors::SetOptions.visit(self, options)
68
+ children.each {|c| c.options = options}
69
+ @options = options
69
70
  end
70
71
 
71
72
  # @private
@@ -184,7 +185,9 @@ module Sass
184
185
  #
185
186
  # @return [Node]
186
187
  def deep_copy
187
- Sass::Tree::Visitors::DeepCopy.visit(self)
188
+ node = dup
189
+ node.children = children.map {|c| c.deep_copy}
190
+ node
188
191
  end
189
192
 
190
193
  protected
@@ -23,6 +23,11 @@ module Sass::Tree
23
23
  # @return [Sass::Script::Node]
24
24
  attr_accessor :value
25
25
 
26
+ # Whether the property was marked as !important.
27
+ #
28
+ # @return [Boolean]
29
+ attr_accessor :important
30
+
26
31
  # The value of the property
27
32
  # after any interpolated SassScript has been resolved.
28
33
  # Only set once \{Tree::Visitors::Perform} has been run.
@@ -44,14 +49,16 @@ module Sass::Tree
44
49
 
45
50
  # @param name [Array<String, Sass::Script::Node>] See \{#name}
46
51
  # @param value [Sass::Script::Node] See \{#value}
52
+ # @param important [Boolean] whether this is an !important property
47
53
  # @param prop_syntax [Symbol] `:new` if this property uses `a: b`-style syntax,
48
54
  # `:old` if it uses `:a b`-style syntax
49
- def initialize(name, value, prop_syntax)
55
+ def initialize(name, value, important, prop_syntax)
50
56
  @name = Sass::Util.strip_string_array(
51
57
  Sass::Util.merge_adjacent_strings(name))
52
58
  @value = value
53
59
  @tabs = 0
54
60
  @prop_syntax = prop_syntax
61
+ @important = important
55
62
  super()
56
63
  end
57
64
 
@@ -89,7 +96,7 @@ module Sass::Tree
89
96
  old = opts[:old] && fmt == :sass
90
97
  initial = old ? ':' : ''
91
98
  mid = old ? '' : ':'
92
- "#{initial}#{name}#{mid} #{self.class.val_to_sass(value, opts)}".rstrip
99
+ "#{initial}#{name}#{mid} #{self.class.val_to_sass(value, opts)}#{' !important' if important}".rstrip
93
100
  end
94
101
 
95
102
  private
@@ -6,7 +6,7 @@ module Sass
6
6
  class ReturnNode < Node
7
7
  # The expression to return.
8
8
  # @type [Script::Node]
9
- attr_accessor :expr
9
+ attr_reader :expr
10
10
 
11
11
  # @param expr [Script::Node] The expression to return
12
12
  def initialize(expr)
@@ -50,13 +50,6 @@ module Sass::Tree
50
50
  # @return [Boolean]
51
51
  attr_accessor :group_end
52
52
 
53
- # The stack trace.
54
- # This is only readable in a CSS tree as it is written during the perform step
55
- # and only when the :trace_selectors option is set.
56
- #
57
- # @return [Array<String>]
58
- attr_accessor :stack_trace
59
-
60
53
  # @param rule [Array<String, Sass::Script::Node>]
61
54
  # The CSS rule. See \{#rule}
62
55
  def initialize(rule)
@@ -128,8 +121,8 @@ module Sass::Tree
128
121
  if @rule.all? {|t| t.kind_of?(String)}
129
122
  # We don't use real filename/line info because we don't have it yet.
130
123
  # When we get it, we'll set it on the parsed rules if possible.
131
- parser = Sass::SCSS::StaticParser.new(@rule.join.strip, '', 1)
132
- @parsed_rules = parser.parse_selector rescue nil
124
+ parser = Sass::SCSS::StaticParser.new(@rule.join.strip, 1)
125
+ @parsed_rules = parser.parse_selector('') rescue nil
133
126
  end
134
127
  end
135
128
  end
@@ -10,7 +10,7 @@ module Sass
10
10
 
11
11
  # The parse tree for the variable value.
12
12
  # @return [Script::Node]
13
- attr_accessor :expr
13
+ attr_reader :expr
14
14
 
15
15
  # Whether this is a guarded variable assignment (`!default`).
16
16
  # @return [Boolean]
@@ -17,11 +17,11 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
17
17
  raise e
18
18
  end
19
19
 
20
- CONTROL_NODES = [Sass::Tree::EachNode, Sass::Tree::ForNode, Sass::Tree::IfNode, Sass::Tree::WhileNode]
21
- SCRIPT_NODES = [Sass::Tree::ImportNode, Sass::Tree::MixinNode] + CONTROL_NODES
20
+ PARENT_CLASSES = [ Sass::Tree::EachNode, Sass::Tree::ForNode, Sass::Tree::IfNode,
21
+ Sass::Tree::ImportNode, Sass::Tree::MixinNode, Sass::Tree::WhileNode]
22
22
  def visit_children(parent)
23
23
  old_parent = @parent
24
- @parent = parent unless is_any_of?(parent, SCRIPT_NODES)
24
+ @parent = parent unless is_any_of?(parent, PARENT_CLASSES)
25
25
  old_real_parent, @real_parent = @real_parent, parent
26
26
  super
27
27
  ensure
@@ -48,9 +48,9 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
48
48
  "@charset may only be used at the root of a document." unless parent.is_a?(Sass::Tree::RootNode)
49
49
  end
50
50
 
51
- VALID_EXTEND_PARENTS = [Sass::Tree::RuleNode, Sass::Tree::MixinDefNode]
51
+ INVALID_EXTEND_PARENTS = [Sass::Tree::RuleNode, Sass::Tree::MixinDefNode]
52
52
  def invalid_extend_parent?(parent, child)
53
- unless is_any_of?(parent, VALID_EXTEND_PARENTS)
53
+ unless is_any_of?(parent, INVALID_EXTEND_PARENTS)
54
54
  "Extend directives may only be used within rules."
55
55
  end
56
56
  end
@@ -59,22 +59,23 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
59
59
  "Functions may only be defined at the root of a document." unless parent.is_a?(Sass::Tree::RootNode)
60
60
  end
61
61
 
62
- VALID_FUNCTION_CHILDREN = [
63
- Sass::Tree::CommentNode, Sass::Tree::DebugNode, Sass::Tree::ReturnNode,
64
- Sass::Tree::VariableNode, Sass::Tree::WarnNode
65
- ] + CONTROL_NODES
62
+ INVALID_FUNCTION_CHILDREN = [
63
+ Sass::Tree::CommentNode, Sass::Tree::DebugNode, Sass::Tree::EachNode,
64
+ Sass::Tree::ForNode, Sass::Tree::IfNode, Sass::Tree::ReturnNode,
65
+ Sass::Tree::VariableNode, Sass::Tree::WarnNode, Sass::Tree::WhileNode
66
+ ]
66
67
  def invalid_function_child?(parent, child)
67
- unless is_any_of?(child, VALID_FUNCTION_CHILDREN)
68
+ unless is_any_of?(child, INVALID_FUNCTION_CHILDREN)
68
69
  "Functions can only contain variable declarations and control directives."
69
70
  end
70
71
  end
71
72
 
72
- VALID_IMPORT_PARENTS = [
73
+ INVALID_IMPORT_PARENTS = [
73
74
  Sass::Tree::IfNode, Sass::Tree::ForNode, Sass::Tree::WhileNode,
74
75
  Sass::Tree::EachNode, Sass::Tree::MixinDefNode
75
76
  ]
76
77
  def invalid_import_parent?(parent, child)
77
- if is_any_of?(@real_parent, VALID_IMPORT_PARENTS)
78
+ if is_any_of?(@real_parent, INVALID_IMPORT_PARENTS)
78
79
  return "Import directives may not be used within control directives or mixins."
79
80
  end
80
81
  return if parent.is_a?(Sass::Tree::RootNode)
@@ -97,17 +98,17 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
97
98
  "Mixins may only be defined at the root of a document." unless parent.is_a?(Sass::Tree::RootNode)
98
99
  end
99
100
 
100
- VALID_PROP_CHILDREN = [Sass::Tree::CommentNode, Sass::Tree::PropNode, Sass::Tree::MixinNode] + CONTROL_NODES
101
+ INVALID_PROP_CHILDREN = [Sass::Tree::CommentNode, Sass::Tree::PropNode]
101
102
  def invalid_prop_child?(parent, child)
102
- unless is_any_of?(child, VALID_PROP_CHILDREN)
103
+ unless is_any_of?(child, INVALID_PROP_CHILDREN)
103
104
  "Illegal nesting: Only properties may be nested beneath properties."
104
105
  end
105
106
  end
106
107
 
107
- VALID_PROP_PARENTS = [Sass::Tree::RuleNode, Sass::Tree::PropNode,
108
- Sass::Tree::MixinDefNode, Sass::Tree::DirectiveNode]
108
+ INVALID_PROP_PARENTS = [Sass::Tree::RuleNode, Sass::Tree::PropNode,
109
+ Sass::Tree::MixinDefNode, Sass::Tree::DirectiveNode]
109
110
  def invalid_prop_parent?(parent, child)
110
- unless is_any_of?(parent, VALID_PROP_PARENTS)
111
+ unless is_any_of?(parent, INVALID_PROP_PARENTS)
111
112
  "Properties are only allowed within rules, directives, or other properties." + child.pseudo_class_selector_message
112
113
  end
113
114
  end
@@ -32,7 +32,7 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
32
32
  visit(child) +
33
33
  if nxt &&
34
34
  (child.is_a?(Sass::Tree::CommentNode) &&
35
- child.line + child.lines + 1 == nxt.line) ||
35
+ child.line + child.value.count("\n") + 1 == nxt.line) ||
36
36
  (child.is_a?(Sass::Tree::ImportNode) && nxt.is_a?(Sass::Tree::ImportNode) &&
37
37
  child.line + 1 == nxt.line) ||
38
38
  (child.is_a?(Sass::Tree::VariableNode) && nxt.is_a?(Sass::Tree::VariableNode) &&
@@ -49,13 +49,8 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
49
49
  end
50
50
 
51
51
  def visit_comment(node)
52
- value = node.value.map do |r|
53
- next r if r.is_a?(String)
54
- "\#{#{r.to_sass(@options)}}"
55
- end.join
56
-
57
52
  content = if @format == :sass
58
- content = value.gsub(/\*\/$/, '').rstrip
53
+ content = node.value.gsub(/\*\/$/, '').rstrip
59
54
  if content =~ /\A[ \t]/
60
55
  # Re-indent SCSS comments like this:
61
56
  # /* foo
@@ -83,11 +78,11 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
83
78
  content.gsub!(/^/, tab_str)
84
79
  content.rstrip + "\n"
85
80
  else
86
- spaces = (' ' * [@tabs - value[/^ */].size, 0].max)
81
+ spaces = (' ' * [@tabs - node.value[/^ */].size, 0].max)
87
82
  content = if node.silent
88
- value.gsub(/^[\/ ]\*/, '//').gsub(/ *\*\/$/, '')
83
+ node.value.gsub(/^[\/ ]\*/, '//').gsub(/ *\*\/$/, '')
89
84
  else
90
- value
85
+ node.value
91
86
  end.gsub(/^/, spaces) + "\n"
92
87
  content
93
88
  end
@@ -53,10 +53,12 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
53
53
  # Removes this node from the tree if it's a silent comment.
54
54
  def visit_comment(node)
55
55
  return [] if node.invisible?
56
- check_for_loud_silent_comment node
57
- check_for_comment_interp node
58
- node.resolved_value = run_interp_no_strip(node.value)
59
- node.resolved_value.gsub!(/\\([\\#])/, '\1')
56
+ if node.evaluated?
57
+ node.value.gsub!(/(^|[^\\])\#\{([^}]*)\}/) do |md|
58
+ $1+Sass::Script.parse($2, node.line, 0, node.options).perform(@environment).to_s
59
+ end
60
+ node.value = run_interp([Sass::Script::String.new(node.value)])
61
+ end
60
62
  node
61
63
  end
62
64
 
@@ -87,8 +89,8 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
87
89
  # Runs SassScript interpolation in the selector,
88
90
  # and then parses the result into a {Sass::Selector::CommaSequence}.
89
91
  def visit_extend(node)
90
- parser = Sass::SCSS::CssParser.new(run_interp(node.selector), node.filename, node.line)
91
- node.resolved_selector = parser.parse_selector
92
+ parser = Sass::SCSS::CssParser.new(run_interp(node.selector), node.line)
93
+ node.resolved_selector = parser.parse_selector(node.filename)
92
94
  node
93
95
  end
94
96
 
@@ -140,7 +142,6 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
140
142
 
141
143
  @environment.push_frame(:filename => node.filename, :line => node.line)
142
144
  root = node.imported_file.to_tree
143
- Sass::Tree::Visitors::CheckNesting.visit(root)
144
145
  node.children = root.children.map {|c| visit(c)}.flatten
145
146
  node
146
147
  rescue Sass::SyntaxError => e
@@ -224,13 +225,8 @@ END
224
225
  # Runs SassScript interpolation in the selector,
225
226
  # and then parses the result into a {Sass::Selector::CommaSequence}.
226
227
  def visit_rule(node)
227
- parser = Sass::SCSS::StaticParser.new(run_interp(node.rule), node.filename, node.line)
228
- node.parsed_rules ||= parser.parse_selector
229
- if node.options[:trace_selectors]
230
- @environment.push_frame(:filename => node.filename, :line => node.line)
231
- node.stack_trace = @environment.stack_trace
232
- @environment.pop_frame
233
- end
228
+ parser = Sass::SCSS::StaticParser.new(run_interp(node.rule), node.line)
229
+ node.parsed_rules ||= parser.parse_selector(node.filename)
234
230
  yield
235
231
  end
236
232
 
@@ -247,10 +243,13 @@ END
247
243
  @environment.push_frame(:filename => node.filename, :line => node.line)
248
244
  res = node.expr.perform(@environment)
249
245
  res = res.value if res.is_a?(Sass::Script::String)
250
- msg = "WARNING: #{res}\n "
251
- msg << @environment.stack_trace.join("\n ")
252
- # JRuby doesn't automatically add a newline for #warn
253
- msg << (RUBY_PLATFORM =~ /java/ ? "\n\n" : "\n")
246
+ msg = "WARNING: #{res}\n"
247
+ @environment.stack.reverse.each_with_index do |entry, i|
248
+ msg << " #{i == 0 ? "on" : "from"} line #{entry[:line]}" <<
249
+ " of #{entry[:filename] || "an unknown file"}"
250
+ msg << ", in `#{entry[:mixin]}'" if entry[:mixin]
251
+ msg << "\n"
252
+ end
254
253
  Sass::Util.sass_warn msg
255
254
  []
256
255
  ensure
@@ -276,18 +275,14 @@ END
276
275
 
277
276
  private
278
277
 
279
- def run_interp_no_strip(text)
278
+ def run_interp(text)
280
279
  text.map do |r|
281
280
  next r if r.is_a?(String)
282
281
  val = r.perform(@environment)
283
282
  # Interpolated strings should never render with quotes
284
283
  next val.value if val.is_a?(Sass::Script::String)
285
284
  val.to_s
286
- end.join
287
- end
288
-
289
- def run_interp(text)
290
- run_interp_no_strip(text).strip
285
+ end.join.strip
291
286
  end
292
287
 
293
288
  def handle_include_loop!(node)
@@ -303,30 +298,4 @@ END
303
298
  end.join("\n")
304
299
  raise Sass::SyntaxError.new(msg)
305
300
  end
306
-
307
- def check_for_loud_silent_comment(node)
308
- return unless node.loud && node.silent
309
- Sass::Util.sass_warn <<MESSAGE
310
- WARNING:
311
- On line #{node.line}#{" of '#{node.filename}'" if node.filename}
312
- `//` comments will no longer be allowed to use the `!` flag in Sass 3.2.
313
- Please change to `/*` comments.
314
- MESSAGE
315
- end
316
-
317
- def check_for_comment_interp(node)
318
- return if node.loud
319
- node.value.each do |e|
320
- next unless e.is_a?(String)
321
- e.scan(/(\\*)#\{/) do |esc|
322
- Sass::Util.sass_warn <<MESSAGE if esc.first.size.even?
323
- WARNING:
324
- On line #{node.line}#{" of '#{node.filename}'" if node.filename}
325
- Comments will evaluate the contents of interpolations (\#{ ... }) in Sass 3.2.
326
- Please escape the interpolation by adding a backslash before the `#`.
327
- MESSAGE
328
- return
329
- end
330
- end
331
- end
332
301
  end