haml 3.1.0 → 3.1.1

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 (87) hide show
  1. data/VERSION +1 -1
  2. data/vendor/sass/Rakefile +22 -46
  3. data/vendor/sass/VERSION +1 -1
  4. data/vendor/sass/VERSION_NAME +1 -1
  5. data/vendor/sass/bin/scss +8 -0
  6. data/vendor/sass/doc-src/SASS_CHANGELOG.md +125 -9
  7. data/vendor/sass/doc-src/SASS_REFERENCE.md +84 -8
  8. data/vendor/sass/lib/sass.rb +0 -3
  9. data/vendor/sass/lib/sass/cache_stores.rb +1 -0
  10. data/vendor/sass/lib/sass/cache_stores/base.rb +2 -2
  11. data/vendor/sass/lib/sass/cache_stores/chain.rb +33 -0
  12. data/vendor/sass/lib/sass/cache_stores/filesystem.rb +6 -4
  13. data/vendor/sass/lib/sass/cache_stores/memory.rb +8 -12
  14. data/vendor/sass/lib/sass/engine.rb +65 -56
  15. data/vendor/sass/lib/sass/environment.rb +5 -2
  16. data/vendor/sass/lib/sass/exec.rb +52 -21
  17. data/vendor/sass/lib/sass/importers/filesystem.rb +32 -9
  18. data/vendor/sass/lib/sass/less.rb +1 -1
  19. data/vendor/sass/lib/sass/plugin.rb +11 -1
  20. data/vendor/sass/lib/sass/plugin/compiler.rb +21 -12
  21. data/vendor/sass/lib/sass/plugin/rails.rb +8 -82
  22. data/vendor/sass/lib/sass/plugin/staleness_checker.rb +10 -10
  23. data/vendor/sass/lib/sass/railtie.rb +3 -2
  24. data/vendor/sass/lib/sass/script.rb +2 -25
  25. data/vendor/sass/lib/sass/script/color.rb +4 -15
  26. data/vendor/sass/lib/sass/script/funcall.rb +63 -19
  27. data/vendor/sass/lib/sass/script/functions.rb +257 -19
  28. data/vendor/sass/lib/sass/script/lexer.rb +1 -4
  29. data/vendor/sass/lib/sass/script/list.rb +2 -2
  30. data/vendor/sass/lib/sass/script/node.rb +0 -27
  31. data/vendor/sass/lib/sass/script/number.rb +1 -1
  32. data/vendor/sass/lib/sass/script/operation.rb +0 -5
  33. data/vendor/sass/lib/sass/script/parser.rb +30 -12
  34. data/vendor/sass/lib/sass/script/string.rb +2 -17
  35. data/vendor/sass/lib/sass/script/string_interpolation.rb +1 -0
  36. data/vendor/sass/lib/sass/scss/parser.rb +58 -18
  37. data/vendor/sass/lib/sass/scss/rx.rb +2 -1
  38. data/vendor/sass/lib/sass/scss/script_lexer.rb +1 -1
  39. data/vendor/sass/lib/sass/selector/comma_sequence.rb +2 -3
  40. data/vendor/sass/lib/sass/selector/sequence.rb +3 -6
  41. data/vendor/sass/lib/sass/selector/simple_sequence.rb +2 -3
  42. data/vendor/sass/lib/sass/tree/charset_node.rb +0 -15
  43. data/vendor/sass/lib/sass/tree/comment_node.rb +20 -71
  44. data/vendor/sass/lib/sass/tree/debug_node.rb +4 -22
  45. data/vendor/sass/lib/sass/tree/directive_node.rb +0 -52
  46. data/vendor/sass/lib/sass/tree/each_node.rb +8 -38
  47. data/vendor/sass/lib/sass/tree/extend_node.rb +12 -48
  48. data/vendor/sass/lib/sass/tree/for_node.rb +20 -51
  49. data/vendor/sass/lib/sass/tree/function_node.rb +27 -0
  50. data/vendor/sass/lib/sass/tree/if_node.rb +22 -57
  51. data/vendor/sass/lib/sass/tree/import_node.rb +0 -56
  52. data/vendor/sass/lib/sass/tree/media_node.rb +0 -43
  53. data/vendor/sass/lib/sass/tree/mixin_def_node.rb +12 -45
  54. data/vendor/sass/lib/sass/tree/mixin_node.rb +13 -124
  55. data/vendor/sass/lib/sass/tree/node.rb +18 -304
  56. data/vendor/sass/lib/sass/tree/prop_node.rb +24 -92
  57. data/vendor/sass/lib/sass/tree/return_node.rb +18 -0
  58. data/vendor/sass/lib/sass/tree/root_node.rb +4 -133
  59. data/vendor/sass/lib/sass/tree/rule_node.rb +21 -164
  60. data/vendor/sass/lib/sass/tree/variable_node.rb +14 -23
  61. data/vendor/sass/lib/sass/tree/visitors/base.rb +75 -0
  62. data/vendor/sass/lib/sass/tree/visitors/check_nesting.rb +134 -0
  63. data/vendor/sass/lib/sass/tree/visitors/convert.rb +255 -0
  64. data/vendor/sass/lib/sass/tree/visitors/cssize.rb +175 -0
  65. data/vendor/sass/lib/sass/tree/visitors/perform.rb +301 -0
  66. data/vendor/sass/lib/sass/tree/visitors/to_css.rb +216 -0
  67. data/vendor/sass/lib/sass/tree/warn_node.rb +4 -28
  68. data/vendor/sass/lib/sass/tree/while_node.rb +5 -35
  69. data/vendor/sass/lib/sass/util.rb +0 -50
  70. data/vendor/sass/sass.gemspec +1 -1
  71. data/vendor/sass/test/sass/conversion_test.rb +53 -102
  72. data/vendor/sass/test/sass/engine_test.rb +416 -540
  73. data/vendor/sass/test/sass/functions_test.rb +306 -4
  74. data/vendor/sass/test/sass/importer_test.rb +0 -22
  75. data/vendor/sass/test/sass/plugin_test.rb +51 -21
  76. data/vendor/sass/test/sass/results/if.css +3 -0
  77. data/vendor/sass/test/sass/script_conversion_test.rb +0 -38
  78. data/vendor/sass/test/sass/script_test.rb +19 -4
  79. data/vendor/sass/test/sass/scss/scss_test.rb +32 -11
  80. data/vendor/sass/test/sass/templates/if.sass +11 -0
  81. data/vendor/sass/test/sass/templates/nested_import.sass +2 -0
  82. data/vendor/sass/test/sass/util_test.rb +0 -21
  83. data/vendor/sass/test/test_helper.rb +0 -3
  84. metadata +268 -258
  85. data/vendor/sass/bin/css2sass +0 -13
  86. data/vendor/sass/lib/sass/cache_stores/active_support.rb +0 -28
  87. data/vendor/sass/lib/sass/importers/rails.rb +0 -75
@@ -13,7 +13,7 @@ module Sass::Tree
13
13
 
14
14
  # The name of the property
15
15
  # after any interpolated SassScript has been resolved.
16
- # Only set once \{Tree::Node#perform} has been called.
16
+ # Only set once \{Tree::Visitors::Perform} has been run.
17
17
  #
18
18
  # @return [String]
19
19
  attr_accessor :resolved_name
@@ -23,9 +23,14 @@ 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
- # Only set once \{Tree::Node#perform} has been called.
33
+ # Only set once \{Tree::Visitors::Perform} has been run.
29
34
  #
30
35
  # @return [String]
31
36
  attr_accessor :resolved_value
@@ -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
 
@@ -74,85 +81,22 @@ module Sass::Tree
74
81
  "\nIf #{declaration.dump} should be a selector, use \"\\#{declaration}\" instead."
75
82
  end
76
83
 
77
- protected
78
-
79
- # @see Node#to_src
80
- def to_src(tabs, opts, fmt)
81
- res = declaration(tabs, opts, fmt)
82
- return res + "#{semi fmt}\n" if children.empty?
83
- res + children_to_src(tabs, opts, fmt).rstrip + semi(fmt) + "\n"
84
- end
85
-
86
- # Computes the CSS for the property.
87
- #
88
- # @param tabs [Fixnum] The level of indentation for the CSS
89
- # @return [String] The resulting CSS
90
- def _to_s(tabs)
91
- tab_str = ' ' * (tabs - 1 + self.tabs)
92
- if style == :compressed
93
- "#{tab_str}#{resolved_name}:#{resolved_value}"
94
- else
95
- "#{tab_str}#{resolved_name}: #{resolved_value};"
96
- end
97
- end
98
-
99
- # Converts nested properties into flat properties.
84
+ # Computes the Sass or SCSS code for the variable declaration.
85
+ # This is like \{#to\_scss} or \{#to\_sass},
86
+ # except it doesn't print any child properties or a trailing semicolon.
100
87
  #
101
- # @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
102
- # The extensions defined for this tree
103
- # @param parent [PropNode, nil] The parent node of this node,
104
- # or nil if the parent isn't a {PropNode}
105
- # @raise [Sass::SyntaxError] if the property uses invalid syntax
106
- def _cssize(extends, parent)
107
- node = super
108
- result = node.children.dup
109
- if !node.resolved_value.empty? || node.children.empty?
110
- node.send(:check!)
111
- result.unshift(node)
88
+ # @param opts [{Symbol => Object}] The options hash for the tree.
89
+ # @param fmt [Symbol] `:scss` or `:sass`.
90
+ def declaration(opts = {:old => @prop_syntax == :old}, fmt = :sass)
91
+ name = self.name.map {|n| n.is_a?(String) ? n : "\#{#{n.to_sass(opts)}}"}.join
92
+ if name[0] == ?:
93
+ raise Sass::SyntaxError.new("The \"#{name}: #{self.class.val_to_sass(value, opts)}\" hack is not allowed in the Sass indented syntax")
112
94
  end
113
- result
114
- end
115
95
 
116
- # Updates the name and indentation of this node based on the parent name
117
- # and nesting level.
118
- #
119
- # @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
120
- # The extensions defined for this tree
121
- # @param parent [PropNode, nil] The parent node of this node,
122
- # or nil if the parent isn't a {PropNode}
123
- def cssize!(extends, parent)
124
- self.resolved_name = "#{parent.resolved_name}-#{resolved_name}" if parent
125
- self.tabs = parent.tabs + (parent.resolved_value.empty? ? 0 : 1) if parent && style == :nested
126
- super
127
- end
128
-
129
- # Runs any SassScript that may be embedded in the property,
130
- # and invludes the parent property, if any.
131
- #
132
- # @param environment [Sass::Environment] The lexical environment containing
133
- # variable and mixin values
134
- def perform!(environment)
135
- @resolved_name = run_interp(@name, environment)
136
- val = @value.perform(environment)
137
- @resolved_value =
138
- if @value.context == :equals && val.is_a?(Sass::Script::String)
139
- val.value
140
- else
141
- val.to_s
142
- end
143
- super
144
- end
145
-
146
- # Returns an error message if the given child node is invalid,
147
- # and false otherwise.
148
- #
149
- # {PropNode} only allows other {PropNode}s and {CommentNode}s as children.
150
- # @param child [Tree::Node] A potential child node
151
- # @return [String] An error message if the child is invalid, or nil otherwise
152
- def invalid_child?(child)
153
- if !child.is_a?(PropNode) && !child.is_a?(CommentNode)
154
- "Illegal nesting: Only properties may be nested beneath properties."
155
- end
96
+ old = opts[:old] && fmt == :sass
97
+ initial = old ? ':' : ''
98
+ mid = old ? '' : ':'
99
+ "#{initial}#{name}#{mid} #{self.class.val_to_sass(value, opts)}#{' !important' if important}".rstrip
156
100
  end
157
101
 
158
102
  private
@@ -167,18 +111,6 @@ module Sass::Tree
167
111
  end
168
112
  end
169
113
 
170
- def declaration(tabs = 0, opts = {:old => @prop_syntax == :old}, fmt = :sass)
171
- name = self.name.map {|n| n.is_a?(String) ? n : "\#{#{n.to_sass(opts)}}"}.join
172
- if name[0] == ?:
173
- raise Sass::SyntaxError.new("The \"#{name}: #{self.class.val_to_sass(value, opts)}\" hack is not allowed in the Sass indented syntax")
174
- end
175
-
176
- old = opts[:old] && fmt == :sass
177
- initial = old ? ':' : ''
178
- mid = old ? '' : ':'
179
- "#{' ' * tabs}#{initial}#{name}#{mid} #{self.class.val_to_sass(value, opts)}".rstrip
180
- end
181
-
182
114
  class << self
183
115
  # @private
184
116
  def val_to_sass(value, opts)
@@ -211,7 +143,7 @@ module Sass::Tree
211
143
  unless node.is_a?(Sass::Script::Operation) && node.operator == :div &&
212
144
  node.operand1.is_a?(Sass::Script::Number) &&
213
145
  node.operand2.is_a?(Sass::Script::Number) &&
214
- (node.context == :equals || !node.operand1.original || !node.operand2.original)
146
+ (!node.operand1.original || !node.operand2.original)
215
147
  return node
216
148
  end
217
149
 
@@ -0,0 +1,18 @@
1
+ module Sass
2
+ module Tree
3
+ # A dynamic node representing returning from a function.
4
+ #
5
+ # @see Sass::Tree
6
+ class ReturnNode < Node
7
+ # The expression to return.
8
+ # @type [Script::Node]
9
+ attr_reader :expr
10
+
11
+ # @param expr [Script::Node] The expression to return
12
+ def initialize(expr)
13
+ @expr = expr
14
+ super()
15
+ end
16
+ end
17
+ end
18
+ end
@@ -13,145 +13,16 @@ module Sass
13
13
  @template = template
14
14
  end
15
15
 
16
- # @see Node#to_s
17
- def to_s(*args)
18
- super
19
- rescue Sass::SyntaxError => e
20
- e.sass_template ||= @template
21
- raise e
22
- end
23
-
24
16
  # Runs the dynamic Sass code *and* computes the CSS for the tree.
25
- #
26
- # @see #perform
27
17
  # @see #to_s
28
18
  def render
29
- result, extends = perform(Environment.new).cssize
19
+ Visitors::CheckNesting.visit(self)
20
+ result = Visitors::Perform.visit(self)
21
+ Visitors::CheckNesting.visit(result) # Check again to validate mixins
22
+ result, extends = Visitors::Cssize.visit(result)
30
23
  result = result.do_extend(extends) unless extends.empty?
31
24
  result.to_s
32
25
  end
33
-
34
- # @see Node#perform
35
- def perform(environment)
36
- environment.options = @options if environment.options.nil? || environment.options.empty?
37
- super
38
- rescue Sass::SyntaxError => e
39
- e.sass_template ||= @template
40
- raise e
41
- end
42
-
43
- # Like {Node#cssize}, except that this method
44
- # will create its own `extends` map if necessary,
45
- # and it returns that map along with the cssized tree.
46
- #
47
- # @return [(Tree::Node, Sass::Util::SubsetMap)] The resulting tree of static nodes
48
- # *and* the extensions defined for this tree
49
- def cssize(extends = Sass::Util::SubsetMap.new, parent = nil)
50
- return super(extends, parent), extends
51
- rescue Sass::SyntaxError => e
52
- e.sass_template ||= @template
53
- raise e
54
- end
55
-
56
- # @see \{Node#perform!}
57
- def perform!(environment)
58
- environment.options = @options if environment.options.nil? || environment.options.empty?
59
- super
60
- end
61
-
62
- # Converts a node to Sass code that will generate it.
63
- #
64
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
65
- # @return [String] The Sass code corresponding to the node
66
- def to_sass(opts = {})
67
- to_src(opts, :sass)
68
- end
69
-
70
- # Converts a node to SCSS code that will generate it.
71
- #
72
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
73
- # @return [String] The SCSS code corresponding to the node
74
- def to_scss(opts = {})
75
- to_src(opts, :scss)
76
- end
77
-
78
- protected
79
-
80
- # @see Node#to_src
81
- def to_src(opts, fmt)
82
- Sass::Util.enum_cons(children + [nil], 2).map do |child, nxt|
83
- child.send("to_#{fmt}", 0, opts) +
84
- if nxt &&
85
- (child.is_a?(CommentNode) && child.line + child.value.count("\n") + 1 == nxt.line) ||
86
- (child.is_a?(ImportNode) && nxt.is_a?(ImportNode) && child.line + 1 == nxt.line) ||
87
- (child.is_a?(VariableNode) && nxt.is_a?(VariableNode) && child.line + 1 == nxt.line)
88
- ""
89
- else
90
- "\n"
91
- end
92
- end.join.rstrip + "\n"
93
- end
94
-
95
- # Computes the CSS corresponding to this Sass tree.
96
- #
97
- # @param args [Array] ignored
98
- # @return [String] The resulting CSS
99
- # @see Sass::Tree
100
- def _to_s(*args)
101
- result = String.new
102
- children.each do |child|
103
- next if child.invisible?
104
- child_str = child.to_s(1)
105
- result << child_str + (style == :compressed ? '' : "\n")
106
- end
107
- result.rstrip!
108
- return "" if result.empty?
109
- result << "\n"
110
- unless Sass::Util.ruby1_8? || result.ascii_only?
111
- if children.first.is_a?(CharsetNode)
112
- begin
113
- encoding = children.first.name
114
- # Default to big-endian encoding, because we have to decide somehow
115
- encoding << 'BE' if encoding =~ /\Autf-(16|32)\Z/i
116
- result = result.encode(Encoding.find(encoding))
117
- rescue EncodingError
118
- end
119
- end
120
-
121
- result = "@charset \"#{result.encoding.name}\";#{
122
- style == :compressed ? '' : "\n"
123
- }".encode(result.encoding) + result
124
- end
125
- result
126
- end
127
-
128
- # In Ruby 1.8, ensures that there's only one @charset directive
129
- # and that it's at the top of the document.
130
- #
131
- # @see Node#cssize
132
- def cssize!(extends, parent)
133
- super
134
-
135
- # In Ruby 1.9 we can make all @charset nodes invisible
136
- # and infer the final @charset from the encoding of the final string.
137
- if Sass::Util.ruby1_8? && parent.nil?
138
- charset = self.children.find {|c| c.is_a?(CharsetNode)}
139
- self.children.reject! {|c| c.is_a?(CharsetNode)}
140
- self.children.unshift charset if charset
141
- end
142
- end
143
-
144
- # Returns an error message if the given child node is invalid,
145
- # and false otherwise.
146
- #
147
- # Only property nodes are invalid at root level.
148
- #
149
- # @see Node#invalid_child?
150
- def invalid_child?(child)
151
- return unless child.is_a?(Tree::PropNode)
152
- "Properties aren't allowed at the root of a document." +
153
- child.pseudo_class_selector_message
154
- end
155
26
  end
156
27
  end
157
28
  end
@@ -27,7 +27,7 @@ module Sass::Tree
27
27
 
28
28
  # The CSS selector for this rule,
29
29
  # without any unresolved interpolation or parent references.
30
- # It's only set once {Tree::Node#cssize} has been called.
30
+ # It's only set once {Tree::Visitors::Cssize} has been run.
31
31
  #
32
32
  # @return [Selector::CommaSequence]
33
33
  attr_accessor :resolved_rules
@@ -56,9 +56,22 @@ module Sass::Tree
56
56
  merged = Sass::Util.merge_adjacent_strings(rule)
57
57
  @rule = Sass::Util.strip_string_array(merged)
58
58
  @tabs = 0
59
+ try_to_parse_non_interpolated_rules
59
60
  super()
60
61
  end
61
62
 
63
+ # If we've precached the parsed selector, set the line on it, too.
64
+ def line=(line)
65
+ @parsed_rules.line = line if @parsed_rules
66
+ super
67
+ end
68
+
69
+ # If we've precached the parsed selector, set the filename on it, too.
70
+ def filename=(filename)
71
+ @parsed_rules.filename = filename if @parsed_rules
72
+ super
73
+ end
74
+
62
75
  # Compares the contents of two rules.
63
76
  #
64
77
  # @param other [Object] The object to compare with
@@ -74,6 +87,7 @@ module Sass::Tree
74
87
  def add_rules(node)
75
88
  @rule = Sass::Util.strip_string_array(
76
89
  Sass::Util.merge_adjacent_strings(@rule + ["\n"] + node.rule))
90
+ try_to_parse_non_interpolated_rules
77
91
  end
78
92
 
79
93
  # @return [Boolean] Whether or not this rule is continued on the next line
@@ -82,26 +96,6 @@ module Sass::Tree
82
96
  last.is_a?(String) && last[-1] == ?,
83
97
  end
84
98
 
85
- # @see Node#to_sass
86
- def to_sass(tabs, opts = {})
87
- name = selector_to_sass(rule, opts)
88
- name = "\\" + name if name[0] == ?:
89
- name.gsub(/^/, ' ' * tabs) + children_to_src(tabs, opts, :sass)
90
- end
91
-
92
- # @see Node#to_scss
93
- def to_scss(tabs, opts = {})
94
- name = selector_to_scss(rule, tabs, opts)
95
- res = name + children_to_src(tabs, opts, :scss)
96
-
97
- if children.last.is_a?(CommentNode) && children.last.silent
98
- res.slice!(-3..-1)
99
- res << "\n" << (' ' * tabs) << "}\n"
100
- end
101
-
102
- res
103
- end
104
-
105
99
  # Extends this Rule's selector with the given `extends`.
106
100
  #
107
101
  # @see Node#do_extend
@@ -111,132 +105,6 @@ module Sass::Tree
111
105
  node
112
106
  end
113
107
 
114
- protected
115
-
116
- # Computes the CSS for the rule.
117
- #
118
- # @param tabs [Fixnum] The level of indentation for the CSS
119
- # @return [String] The resulting CSS
120
- def _to_s(tabs)
121
- output_style = style
122
- tabs = tabs + self.tabs
123
-
124
- rule_separator = output_style == :compressed ? ',' : ', '
125
- line_separator =
126
- case output_style
127
- when :nested, :expanded; "\n"
128
- when :compressed; ""
129
- else; " "
130
- end
131
- rule_indent = ' ' * (tabs - 1)
132
- per_rule_indent, total_indent = [:nested, :expanded].include?(output_style) ? [rule_indent, ''] : ['', rule_indent]
133
-
134
- total_rule = total_indent + resolved_rules.members.
135
- map {|seq| seq.to_a.join.gsub(/([^,])\n/m, style == :compressed ? '\1 ' : "\\1\n")}.
136
- join(rule_separator).split("\n").map do |line|
137
- per_rule_indent + line.strip
138
- end.join(line_separator)
139
-
140
- to_return = ''
141
- old_spaces = ' ' * (tabs - 1)
142
- spaces = ' ' * tabs
143
- if output_style != :compressed
144
- if @options[:debug_info]
145
- to_return << debug_info_rule.to_s(tabs) << "\n"
146
- elsif @options[:line_comments]
147
- to_return << "#{old_spaces}/* line #{line}"
148
-
149
- if filename
150
- relative_filename = if @options[:css_filename]
151
- begin
152
- Pathname.new(filename).relative_path_from(
153
- Pathname.new(File.dirname(@options[:css_filename]))).to_s
154
- rescue ArgumentError
155
- nil
156
- end
157
- end
158
- relative_filename ||= filename
159
- to_return << ", #{relative_filename}"
160
- end
161
-
162
- to_return << " */\n"
163
- end
164
- end
165
-
166
- if output_style == :compact
167
- properties = children.map { |a| a.to_s(1) }.join(' ')
168
- to_return << "#{total_rule} { #{properties} }#{"\n" if group_end}"
169
- elsif output_style == :compressed
170
- properties = children.map { |a| a.to_s(1) }.join(';')
171
- to_return << "#{total_rule}{#{properties}}"
172
- else
173
- properties = children.map { |a| a.to_s(tabs + 1) }.join("\n")
174
- end_props = (output_style == :expanded ? "\n" + old_spaces : ' ')
175
- to_return << "#{total_rule} {\n#{properties}#{end_props}}#{"\n" if group_end}"
176
- end
177
-
178
- to_return
179
- end
180
-
181
- # Runs SassScript interpolation in the selector,
182
- # and then parses the result into a {Sass::Selector::CommaSequence}.
183
- #
184
- # @param environment [Sass::Environment] The lexical environment containing
185
- # variable and mixin values
186
- def perform!(environment)
187
- @parsed_rules = Sass::SCSS::StaticParser.new(run_interp(@rule, environment), self.line).
188
- parse_selector(self.filename)
189
- super
190
- end
191
-
192
- # Converts nested rules into a flat list of rules.
193
- #
194
- # @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
195
- # The extensions defined for this tree
196
- # @param parent [RuleNode, nil] The parent node of this node,
197
- # or nil if the parent isn't a {RuleNode}
198
- def _cssize(extends, parent)
199
- node = super
200
- rules = node.children.select {|c| c.is_a?(RuleNode) || c.is_a?(MediaNode)}
201
- props = node.children.reject {|c| c.is_a?(RuleNode) || c.is_a?(MediaNode) || c.invisible?}
202
-
203
- unless props.empty?
204
- node.children = props
205
- rules.each {|r| r.tabs += 1} if style == :nested
206
- rules.unshift(node)
207
- end
208
-
209
- rules.last.group_end = true unless parent || rules.empty?
210
-
211
- rules
212
- end
213
-
214
- # Resolves parent references and nested selectors,
215
- # and updates the indentation based on the parent's indentation.
216
- #
217
- # @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
218
- # The extensions defined for this tree
219
- # @param parent [RuleNode, nil] The parent node of this node,
220
- # or nil if the parent isn't a {RuleNode}
221
- # @raise [Sass::SyntaxError] if the rule has no parents but uses `&`
222
- def cssize!(extends, parent)
223
- # It's possible for resolved_rules to be set if we've duplicated this node during @media bubbling
224
- self.resolved_rules ||= @parsed_rules.resolve_parent_refs(parent && parent.resolved_rules)
225
- super
226
- end
227
-
228
- # Returns an error message if the given child node is invalid,
229
- # and false otherwise.
230
- #
231
- # {ExtendNode}s are valid within {RuleNode}s.
232
- #
233
- # @param child [Tree::Node] A potential child node.
234
- # @return [Boolean, String] Whether or not the child node is valid,
235
- # as well as the error message to display if it is invalid
236
- def invalid_child?(child)
237
- super unless child.is_a?(ExtendNode)
238
- end
239
-
240
108
  # A hash that will be associated with this rule in the CSS document
241
109
  # if the {file:SASS_REFERENCE.md#debug_info-option `:debug_info` option} is enabled.
242
110
  # This data is used by e.g. [the FireSass Firebug extension](https://addons.mozilla.org/en-US/firefox/addon/103988).
@@ -249,24 +117,13 @@ module Sass::Tree
249
117
 
250
118
  private
251
119
 
252
- def debug_info_rule
253
- node = DirectiveNode.new("@media -sass-debug-info")
254
- debug_info.map {|k, v| [k.to_s, v.to_s]}.sort.each do |k, v|
255
- rule = RuleNode.new([""])
256
- rule.resolved_rules = Sass::Selector::CommaSequence.new(
257
- [Sass::Selector::Sequence.new(
258
- [Sass::Selector::SimpleSequence.new(
259
- [Sass::Selector::Element.new(k.to_s.gsub(/[^\w-]/, "\\\\\\0"), nil)])
260
- ])
261
- ])
262
- prop = PropNode.new([""], "", :new)
263
- prop.resolved_name = "font-family"
264
- prop.resolved_value = Sass::SCSS::RX.escape_ident(v.to_s)
265
- rule << prop
266
- node << rule
120
+ def try_to_parse_non_interpolated_rules
121
+ if @rule.all? {|t| t.kind_of?(String)}
122
+ # We don't use real filename/line info because we don't have it yet.
123
+ # When we get it, we'll set it on the parsed rules if possible.
124
+ parser = Sass::SCSS::StaticParser.new(@rule.join.strip, 1)
125
+ @parsed_rules = parser.parse_selector('') rescue nil
267
126
  end
268
- node.options = @options.merge(:debug_info => false, :line_comments => false, :style => :compressed)
269
- node
270
127
  end
271
128
  end
272
129
  end