haml 3.0.25 → 3.1.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 (212) hide show
  1. data/.yardopts +1 -1
  2. data/CONTRIBUTING +0 -1
  3. data/EDGE_GEM_VERSION +1 -0
  4. data/MIT-LICENSE +1 -1
  5. data/README.md +10 -175
  6. data/Rakefile +56 -84
  7. data/VERSION +1 -1
  8. data/VERSION_NAME +1 -1
  9. data/init.rb +1 -1
  10. data/lib/haml.rb +14 -12
  11. data/lib/haml/engine.rb +1 -1
  12. data/lib/haml/exec.rb +19 -316
  13. data/lib/haml/helpers/action_view_extensions.rb +1 -1
  14. data/lib/haml/html.rb +69 -76
  15. data/lib/haml/precompiler.rb +34 -41
  16. data/lib/haml/railtie.rb +4 -6
  17. data/lib/haml/template/plugin.rb +6 -16
  18. data/lib/haml/util.rb +91 -107
  19. data/lib/haml/version.rb +7 -0
  20. data/test/benchmark.rb +2 -9
  21. data/test/haml/engine_test.rb +195 -92
  22. data/test/haml/html2haml/erb_tests.rb +0 -14
  23. data/test/haml/util_test.rb +32 -0
  24. data/test/test_helper.rb +0 -39
  25. metadata +96 -324
  26. data/bin/css2sass +0 -13
  27. data/bin/sass +0 -8
  28. data/bin/sass-convert +0 -7
  29. data/extra/haml-mode.el +0 -753
  30. data/extra/sass-mode.el +0 -207
  31. data/lib/haml/util/subset_map.rb +0 -101
  32. data/lib/sass.rb +0 -29
  33. data/lib/sass/callbacks.rb +0 -52
  34. data/lib/sass/css.rb +0 -294
  35. data/lib/sass/engine.rb +0 -720
  36. data/lib/sass/environment.rb +0 -143
  37. data/lib/sass/error.rb +0 -198
  38. data/lib/sass/files.rb +0 -160
  39. data/lib/sass/less.rb +0 -382
  40. data/lib/sass/plugin.rb +0 -279
  41. data/lib/sass/plugin/configuration.rb +0 -221
  42. data/lib/sass/plugin/generic.rb +0 -15
  43. data/lib/sass/plugin/merb.rb +0 -37
  44. data/lib/sass/plugin/rack.rb +0 -47
  45. data/lib/sass/plugin/rails.rb +0 -32
  46. data/lib/sass/plugin/staleness_checker.rb +0 -123
  47. data/lib/sass/repl.rb +0 -58
  48. data/lib/sass/script.rb +0 -63
  49. data/lib/sass/script/bool.rb +0 -18
  50. data/lib/sass/script/color.rb +0 -491
  51. data/lib/sass/script/css_lexer.rb +0 -29
  52. data/lib/sass/script/css_parser.rb +0 -31
  53. data/lib/sass/script/funcall.rb +0 -77
  54. data/lib/sass/script/functions.rb +0 -861
  55. data/lib/sass/script/interpolation.rb +0 -70
  56. data/lib/sass/script/lexer.rb +0 -337
  57. data/lib/sass/script/literal.rb +0 -236
  58. data/lib/sass/script/node.rb +0 -112
  59. data/lib/sass/script/number.rb +0 -423
  60. data/lib/sass/script/operation.rb +0 -95
  61. data/lib/sass/script/parser.rb +0 -401
  62. data/lib/sass/script/string.rb +0 -67
  63. data/lib/sass/script/string_interpolation.rb +0 -93
  64. data/lib/sass/script/unary_operation.rb +0 -57
  65. data/lib/sass/script/variable.rb +0 -48
  66. data/lib/sass/scss.rb +0 -17
  67. data/lib/sass/scss/css_parser.rb +0 -46
  68. data/lib/sass/scss/parser.rb +0 -855
  69. data/lib/sass/scss/rx.rb +0 -126
  70. data/lib/sass/scss/sass_parser.rb +0 -11
  71. data/lib/sass/scss/script_lexer.rb +0 -15
  72. data/lib/sass/scss/script_parser.rb +0 -25
  73. data/lib/sass/scss/static_parser.rb +0 -40
  74. data/lib/sass/selector.rb +0 -361
  75. data/lib/sass/selector/abstract_sequence.rb +0 -62
  76. data/lib/sass/selector/comma_sequence.rb +0 -82
  77. data/lib/sass/selector/sequence.rb +0 -237
  78. data/lib/sass/selector/simple.rb +0 -113
  79. data/lib/sass/selector/simple_sequence.rb +0 -136
  80. data/lib/sass/tree/charset_node.rb +0 -37
  81. data/lib/sass/tree/comment_node.rb +0 -128
  82. data/lib/sass/tree/debug_node.rb +0 -36
  83. data/lib/sass/tree/directive_node.rb +0 -75
  84. data/lib/sass/tree/extend_node.rb +0 -65
  85. data/lib/sass/tree/for_node.rb +0 -55
  86. data/lib/sass/tree/if_node.rb +0 -69
  87. data/lib/sass/tree/import_node.rb +0 -102
  88. data/lib/sass/tree/mixin_def_node.rb +0 -48
  89. data/lib/sass/tree/mixin_node.rb +0 -111
  90. data/lib/sass/tree/node.rb +0 -464
  91. data/lib/sass/tree/prop_node.rb +0 -220
  92. data/lib/sass/tree/root_node.rb +0 -163
  93. data/lib/sass/tree/rule_node.rb +0 -261
  94. data/lib/sass/tree/variable_node.rb +0 -39
  95. data/lib/sass/tree/warn_node.rb +0 -42
  96. data/lib/sass/tree/while_node.rb +0 -36
  97. data/test/haml/util/subset_map_test.rb +0 -91
  98. data/test/sass/callbacks_test.rb +0 -61
  99. data/test/sass/conversion_test.rb +0 -1218
  100. data/test/sass/css2sass_test.rb +0 -364
  101. data/test/sass/data/hsl-rgb.txt +0 -319
  102. data/test/sass/engine_test.rb +0 -2267
  103. data/test/sass/extend_test.rb +0 -1348
  104. data/test/sass/functions_test.rb +0 -556
  105. data/test/sass/less_conversion_test.rb +0 -653
  106. data/test/sass/more_results/more1.css +0 -9
  107. data/test/sass/more_results/more1_with_line_comments.css +0 -26
  108. data/test/sass/more_results/more_import.css +0 -29
  109. data/test/sass/more_templates/_more_partial.sass +0 -2
  110. data/test/sass/more_templates/more1.sass +0 -23
  111. data/test/sass/more_templates/more_import.sass +0 -11
  112. data/test/sass/plugin_test.rb +0 -433
  113. data/test/sass/results/alt.css +0 -4
  114. data/test/sass/results/basic.css +0 -9
  115. data/test/sass/results/compact.css +0 -5
  116. data/test/sass/results/complex.css +0 -86
  117. data/test/sass/results/compressed.css +0 -1
  118. data/test/sass/results/expanded.css +0 -19
  119. data/test/sass/results/import.css +0 -31
  120. data/test/sass/results/import_charset.css +0 -4
  121. data/test/sass/results/import_charset_1_8.css +0 -4
  122. data/test/sass/results/import_charset_ibm866.css +0 -4
  123. data/test/sass/results/line_numbers.css +0 -49
  124. data/test/sass/results/mixins.css +0 -95
  125. data/test/sass/results/multiline.css +0 -24
  126. data/test/sass/results/nested.css +0 -22
  127. data/test/sass/results/options.css +0 -1
  128. data/test/sass/results/parent_ref.css +0 -13
  129. data/test/sass/results/script.css +0 -16
  130. data/test/sass/results/scss_import.css +0 -31
  131. data/test/sass/results/scss_importee.css +0 -2
  132. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
  133. data/test/sass/results/subdir/subdir.css +0 -3
  134. data/test/sass/results/units.css +0 -11
  135. data/test/sass/results/warn.css +0 -0
  136. data/test/sass/results/warn_imported.css +0 -0
  137. data/test/sass/script_conversion_test.rb +0 -314
  138. data/test/sass/script_test.rb +0 -470
  139. data/test/sass/scss/css_test.rb +0 -916
  140. data/test/sass/scss/rx_test.rb +0 -156
  141. data/test/sass/scss/scss_test.rb +0 -1122
  142. data/test/sass/scss/test_helper.rb +0 -37
  143. data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
  144. data/test/sass/templates/_imported_charset_utf8.sass +0 -4
  145. data/test/sass/templates/_partial.sass +0 -2
  146. data/test/sass/templates/alt.sass +0 -16
  147. data/test/sass/templates/basic.sass +0 -23
  148. data/test/sass/templates/bork1.sass +0 -2
  149. data/test/sass/templates/bork2.sass +0 -2
  150. data/test/sass/templates/bork3.sass +0 -2
  151. data/test/sass/templates/bork4.sass +0 -2
  152. data/test/sass/templates/compact.sass +0 -17
  153. data/test/sass/templates/complex.sass +0 -305
  154. data/test/sass/templates/compressed.sass +0 -15
  155. data/test/sass/templates/expanded.sass +0 -17
  156. data/test/sass/templates/import.sass +0 -12
  157. data/test/sass/templates/import_charset.sass +0 -7
  158. data/test/sass/templates/import_charset_1_8.sass +0 -4
  159. data/test/sass/templates/import_charset_ibm866.sass +0 -9
  160. data/test/sass/templates/importee.less +0 -2
  161. data/test/sass/templates/importee.sass +0 -19
  162. data/test/sass/templates/line_numbers.sass +0 -13
  163. data/test/sass/templates/mixin_bork.sass +0 -5
  164. data/test/sass/templates/mixins.sass +0 -76
  165. data/test/sass/templates/multiline.sass +0 -20
  166. data/test/sass/templates/nested.sass +0 -25
  167. data/test/sass/templates/nested_bork1.sass +0 -2
  168. data/test/sass/templates/nested_bork2.sass +0 -2
  169. data/test/sass/templates/nested_bork3.sass +0 -2
  170. data/test/sass/templates/nested_bork4.sass +0 -2
  171. data/test/sass/templates/nested_mixin_bork.sass +0 -6
  172. data/test/sass/templates/options.sass +0 -2
  173. data/test/sass/templates/parent_ref.sass +0 -25
  174. data/test/sass/templates/script.sass +0 -101
  175. data/test/sass/templates/scss_import.scss +0 -11
  176. data/test/sass/templates/scss_importee.scss +0 -1
  177. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
  178. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
  179. data/test/sass/templates/subdir/subdir.sass +0 -6
  180. data/test/sass/templates/units.sass +0 -11
  181. data/test/sass/templates/warn.sass +0 -3
  182. data/test/sass/templates/warn_imported.sass +0 -4
  183. data/vendor/fssm/LICENSE +0 -20
  184. data/vendor/fssm/README.markdown +0 -55
  185. data/vendor/fssm/Rakefile +0 -59
  186. data/vendor/fssm/VERSION.yml +0 -5
  187. data/vendor/fssm/example.rb +0 -9
  188. data/vendor/fssm/fssm.gemspec +0 -77
  189. data/vendor/fssm/lib/fssm.rb +0 -33
  190. data/vendor/fssm/lib/fssm/backends/fsevents.rb +0 -36
  191. data/vendor/fssm/lib/fssm/backends/inotify.rb +0 -26
  192. data/vendor/fssm/lib/fssm/backends/polling.rb +0 -25
  193. data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +0 -131
  194. data/vendor/fssm/lib/fssm/monitor.rb +0 -26
  195. data/vendor/fssm/lib/fssm/path.rb +0 -91
  196. data/vendor/fssm/lib/fssm/pathname.rb +0 -502
  197. data/vendor/fssm/lib/fssm/state/directory.rb +0 -57
  198. data/vendor/fssm/lib/fssm/state/file.rb +0 -24
  199. data/vendor/fssm/lib/fssm/support.rb +0 -63
  200. data/vendor/fssm/lib/fssm/tree.rb +0 -176
  201. data/vendor/fssm/profile/prof-cache.rb +0 -40
  202. data/vendor/fssm/profile/prof-fssm-pathname.html +0 -1231
  203. data/vendor/fssm/profile/prof-pathname.rb +0 -68
  204. data/vendor/fssm/profile/prof-plain-pathname.html +0 -988
  205. data/vendor/fssm/profile/prof.html +0 -2379
  206. data/vendor/fssm/spec/path_spec.rb +0 -75
  207. data/vendor/fssm/spec/root/duck/quack.txt +0 -0
  208. data/vendor/fssm/spec/root/file.css +0 -0
  209. data/vendor/fssm/spec/root/file.rb +0 -0
  210. data/vendor/fssm/spec/root/file.yml +0 -0
  211. data/vendor/fssm/spec/root/moo/cow.txt +0 -0
  212. data/vendor/fssm/spec/spec_helper.rb +0 -14
@@ -1,220 +0,0 @@
1
- module Sass::Tree
2
- # A static node reprenting a CSS property.
3
- #
4
- # @see Sass::Tree
5
- class PropNode < Node
6
- # The name of the property,
7
- # interspersed with {Sass::Script::Node}s
8
- # representing `#{}`-interpolation.
9
- # Any adjacent strings will be merged together.
10
- #
11
- # @return [Array<String, Sass::Script::Node>]
12
- attr_accessor :name
13
-
14
- # The name of the property
15
- # after any interpolated SassScript has been resolved.
16
- # Only set once \{Tree::Node#perform} has been called.
17
- #
18
- # @return [String]
19
- attr_accessor :resolved_name
20
-
21
- # The value of the property.
22
- #
23
- # @return [Sass::Script::Node]
24
- attr_accessor :value
25
-
26
- # The value of the property
27
- # after any interpolated SassScript has been resolved.
28
- # Only set once \{Tree::Node#perform} has been called.
29
- #
30
- # @return [String]
31
- attr_accessor :resolved_value
32
-
33
- # How deep this property is indented
34
- # relative to a normal property.
35
- # This is only greater than 0 in the case that:
36
- #
37
- # * This node is in a CSS tree
38
- # * The style is :nested
39
- # * This is a child property of another property
40
- # * The parent property has a value, and thus will be rendered
41
- #
42
- # @return [Fixnum]
43
- attr_accessor :tabs
44
-
45
- # @param name [Array<String, Sass::Script::Node>] See \{#name}
46
- # @param value [Sass::Script::Node] See \{#value}
47
- # @param prop_syntax [Symbol] `:new` if this property uses `a: b`-style syntax,
48
- # `:old` if it uses `:a b`-style syntax
49
- def initialize(name, value, prop_syntax)
50
- @name = Haml::Util.strip_string_array(
51
- Haml::Util.merge_adjacent_strings(name))
52
- @value = value
53
- @tabs = 0
54
- @prop_syntax = prop_syntax
55
- super()
56
- end
57
-
58
- # Compares the names and values of two properties.
59
- #
60
- # @param other [Object] The object to compare with
61
- # @return [Boolean] Whether or not this node and the other object
62
- # are the same
63
- def ==(other)
64
- self.class == other.class && name == other.name && value == other.value && super
65
- end
66
-
67
- # Returns a appropriate message indicating how to escape pseudo-class selectors.
68
- # This only applies for old-style properties with no value,
69
- # so returns the empty string if this is new-style.
70
- #
71
- # @return [String] The message
72
- def pseudo_class_selector_message
73
- return "" if @prop_syntax == :new || !value.is_a?(Sass::Script::String) || !value.value.empty?
74
- "\nIf #{declaration.dump} should be a selector, use \"\\#{declaration}\" instead."
75
- end
76
-
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
- to_return = ' ' * (tabs - 1 + self.tabs) + resolved_name + ":" +
92
- (style == :compressed ? '' : ' ') + resolved_value + (style == :compressed ? "" : ";")
93
- end
94
-
95
- # Converts nested properties into flat properties.
96
- #
97
- # @param extends [Haml::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
98
- # The extensions defined for this tree
99
- # @param parent [PropNode, nil] The parent node of this node,
100
- # or nil if the parent isn't a {PropNode}
101
- # @raise [Sass::SyntaxError] if the property uses invalid syntax
102
- def _cssize(extends, parent)
103
- node = super
104
- result = node.children.dup
105
- if !node.resolved_value.empty? || node.children.empty?
106
- node.send(:check!)
107
- result.unshift(node)
108
- end
109
- result
110
- end
111
-
112
- # Updates the name and indentation of this node based on the parent name
113
- # and nesting level.
114
- #
115
- # @param extends [Haml::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
116
- # The extensions defined for this tree
117
- # @param parent [PropNode, nil] The parent node of this node,
118
- # or nil if the parent isn't a {PropNode}
119
- def cssize!(extends, parent)
120
- self.resolved_name = "#{parent.resolved_name}-#{resolved_name}" if parent
121
- self.tabs = parent.tabs + (parent.resolved_value.empty? ? 0 : 1) if parent && style == :nested
122
- super
123
- end
124
-
125
- # Runs any SassScript that may be embedded in the property,
126
- # and invludes the parent property, if any.
127
- #
128
- # @param environment [Sass::Environment] The lexical environment containing
129
- # variable and mixin values
130
- def perform!(environment)
131
- @resolved_name = run_interp(@name, environment)
132
- val = @value.perform(environment)
133
- @resolved_value =
134
- if @value.context == :equals && val.is_a?(Sass::Script::String)
135
- val.value
136
- else
137
- val.to_s
138
- end
139
- super
140
- end
141
-
142
- # Returns an error message if the given child node is invalid,
143
- # and false otherwise.
144
- #
145
- # {PropNode} only allows other {PropNode}s and {CommentNode}s as children.
146
- # @param child [Tree::Node] A potential child node
147
- # @return [String] An error message if the child is invalid, or nil otherwise
148
- def invalid_child?(child)
149
- if !child.is_a?(PropNode) && !child.is_a?(CommentNode)
150
- "Illegal nesting: Only properties may be nested beneath properties."
151
- end
152
- end
153
-
154
- private
155
-
156
- def check!
157
- if @options[:property_syntax] == :old && @prop_syntax == :new
158
- raise Sass::SyntaxError.new("Illegal property syntax: can't use new syntax when :property_syntax => :old is set.")
159
- elsif @options[:property_syntax] == :new && @prop_syntax == :old
160
- raise Sass::SyntaxError.new("Illegal property syntax: can't use old syntax when :property_syntax => :new is set.")
161
- elsif resolved_value.empty?
162
- raise Sass::SyntaxError.new("Invalid property: #{declaration.dump} (no value)." +
163
- pseudo_class_selector_message)
164
- end
165
- end
166
-
167
- def declaration(tabs = 0, opts = {:old => @prop_syntax == :old}, fmt = :sass)
168
- name = self.name.map {|n| n.is_a?(String) ? n : "\#{#{n.to_sass(opts)}}"}.join
169
- if name[0] == ?:
170
- raise Sass::SyntaxError.new("The \"#{name}: #{self.class.val_to_sass(value, opts)}\" hack is not allowed in the Sass indented syntax")
171
- end
172
-
173
- old = opts[:old] && fmt == :sass
174
- initial = old ? ':' : ''
175
- mid = old ? '' : ':'
176
- "#{' ' * tabs}#{initial}#{name}#{mid} #{self.class.val_to_sass(value, opts)}".rstrip
177
- end
178
-
179
- class << self
180
- # @private
181
- def val_to_sass(value, opts)
182
- val_to_sass_comma(value, opts).to_sass(opts)
183
- end
184
-
185
- private
186
-
187
- def val_to_sass_comma(node, opts)
188
- return node unless node.is_a?(Sass::Script::Operation)
189
- return val_to_sass_concat(node, opts) unless node.operator == :comma
190
-
191
- Sass::Script::Operation.new(
192
- val_to_sass_concat(node.operand1, opts),
193
- val_to_sass_comma(node.operand2, opts),
194
- node.operator)
195
- end
196
-
197
- def val_to_sass_concat(node, opts)
198
- return node unless node.is_a?(Sass::Script::Operation)
199
- return val_to_sass_div(node, opts) unless node.operator == :concat
200
-
201
- Sass::Script::Operation.new(
202
- val_to_sass_div(node.operand1, opts),
203
- val_to_sass_concat(node.operand2, opts),
204
- node.operator)
205
- end
206
-
207
- def val_to_sass_div(node, opts)
208
- unless node.is_a?(Sass::Script::Operation) && node.operator == :div &&
209
- node.operand1.is_a?(Sass::Script::Number) &&
210
- node.operand2.is_a?(Sass::Script::Number) &&
211
- (node.context == :equals || !node.operand1.original || !node.operand2.original)
212
- return node
213
- end
214
-
215
- Sass::Script::String.new("(#{node.to_sass(opts)})")
216
- end
217
-
218
- end
219
- end
220
- end
@@ -1,163 +0,0 @@
1
- module Sass
2
- module Tree
3
- # A static node that is the root node of the Sass document.
4
- class RootNode < Node
5
- # The Sass template from which this node was created
6
- #
7
- # @param template [String]
8
- attr_reader :template
9
-
10
- # @param template [String] The Sass template from which this node was created
11
- def initialize(template)
12
- super()
13
- @template = template
14
- end
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
- # Runs the dynamic Sass code *and* computes the CSS for the tree.
25
- #
26
- # @see #perform
27
- # @see #to_s
28
- def render
29
- result, extends = perform(Environment.new).cssize
30
- result = result.do_extend(extends) unless extends.empty?
31
- result.to_s
32
- 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, Haml::Util::SubsetMap)] The resulting tree of static nodes
48
- # *and* the extensions defined for this tree
49
- def cssize(extends = Haml::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
- Haml::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 Haml::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 Haml::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
- case child
152
- when Tree::ExtendNode
153
- "Extend directives may only be used within rules."
154
- when Tree::PropNode
155
- "Properties aren't allowed at the root of a document." +
156
- child.pseudo_class_selector_message
157
- else
158
- return
159
- end
160
- end
161
- end
162
- end
163
- end
@@ -1,261 +0,0 @@
1
- require 'pathname'
2
- require 'uri'
3
-
4
- module Sass::Tree
5
- # A static node reprenting a CSS rule.
6
- #
7
- # @see Sass::Tree
8
- class RuleNode < Node
9
- # The character used to include the parent selector
10
- PARENT = '&'
11
-
12
- # The CSS selector for this rule,
13
- # interspersed with {Sass::Script::Node}s
14
- # representing `#{}`-interpolation.
15
- # Any adjacent strings will be merged together.
16
- #
17
- # @return [Array<String, Sass::Script::Node>]
18
- attr_accessor :rule
19
-
20
- # The CSS selector for this rule,
21
- # without any unresolved interpolation
22
- # but with parent references still intact.
23
- # It's only set once {Tree::Node#perform} has been called.
24
- #
25
- # @return [Selector::CommaSequence]
26
- attr_accessor :parsed_rules
27
-
28
- # The CSS selector for this rule,
29
- # without any unresolved interpolation or parent references.
30
- # It's only set once {Tree::Node#cssize} has been called.
31
- #
32
- # @return [Selector::CommaSequence]
33
- attr_accessor :resolved_rules
34
-
35
- # How deep this rule is indented
36
- # relative to a base-level rule.
37
- # This is only greater than 0 in the case that:
38
- #
39
- # * This node is in a CSS tree
40
- # * The style is :nested
41
- # * This is a child rule of another rule
42
- # * The parent rule has properties, and thus will be rendered
43
- #
44
- # @return [Fixnum]
45
- attr_accessor :tabs
46
-
47
- # Whether or not this rule is the last rule in a nested group.
48
- # This is only set in a CSS tree.
49
- #
50
- # @return [Boolean]
51
- attr_accessor :group_end
52
-
53
- # @param rule [Array<String, Sass::Script::Node>]
54
- # The CSS rule. See \{#rule}
55
- def initialize(rule)
56
- #p rule
57
- merged = Haml::Util.merge_adjacent_strings(rule)
58
- #p merged
59
- @rule = Haml::Util.strip_string_array(merged)
60
- #p @rule
61
- @tabs = 0
62
- super()
63
- end
64
-
65
- # Compares the contents of two rules.
66
- #
67
- # @param other [Object] The object to compare with
68
- # @return [Boolean] Whether or not this node and the other object
69
- # are the same
70
- def ==(other)
71
- self.class == other.class && rule == other.rule && super
72
- end
73
-
74
- # Adds another {RuleNode}'s rules to this one's.
75
- #
76
- # @param node [RuleNode] The other node
77
- def add_rules(node)
78
- @rule = Haml::Util.strip_string_array(
79
- Haml::Util.merge_adjacent_strings(@rule + ["\n"] + node.rule))
80
- end
81
-
82
- # @return [Boolean] Whether or not this rule is continued on the next line
83
- def continued?
84
- last = @rule.last
85
- last.is_a?(String) && last[-1] == ?,
86
- end
87
-
88
- # @see Node#to_sass
89
- def to_sass(tabs, opts = {})
90
- name = selector_to_sass(rule, opts)
91
- name = "\\" + name if name[0] == ?:
92
- name.gsub(/^/, ' ' * tabs) + children_to_src(tabs, opts, :sass)
93
- end
94
-
95
- # @see Node#to_scss
96
- def to_scss(tabs, opts = {})
97
- name = selector_to_scss(rule, tabs, opts)
98
- res = name + children_to_src(tabs, opts, :scss)
99
-
100
- if children.last.is_a?(CommentNode) && children.last.silent
101
- res.slice!(-3..-1)
102
- res << "\n" << (' ' * tabs) << "}\n"
103
- end
104
-
105
- res
106
- end
107
-
108
- # Extends this Rule's selector with the given `extends`.
109
- #
110
- # @see Node#do_extend
111
- def do_extend(extends)
112
- node = dup
113
- node.resolved_rules = resolved_rules.do_extend(extends)
114
- node
115
- end
116
-
117
- protected
118
-
119
- # Computes the CSS for the rule.
120
- #
121
- # @param tabs [Fixnum] The level of indentation for the CSS
122
- # @return [String] The resulting CSS
123
- def _to_s(tabs)
124
- tabs = tabs + self.tabs
125
-
126
- rule_separator = style == :compressed ? ',' : ', '
127
- line_separator =
128
- case style
129
- when :nested, :expanded; "\n"
130
- when :compressed; ""
131
- else; " "
132
- end
133
- rule_indent = ' ' * (tabs - 1)
134
- per_rule_indent, total_indent = [:nested, :expanded].include?(style) ? [rule_indent, ''] : ['', rule_indent]
135
-
136
- total_rule = total_indent + resolved_rules.members.
137
- map {|seq| seq.to_a.join.gsub(/([^,])\n/m, style == :compressed ? '\1 ' : "\\1\n")}.
138
- join(rule_separator).split("\n").map do |line|
139
- per_rule_indent + line.strip
140
- end.join(line_separator)
141
-
142
- to_return = ''
143
- old_spaces = ' ' * (tabs - 1)
144
- spaces = ' ' * tabs
145
- if style != :compressed
146
- if @options[:debug_info]
147
- to_return << debug_info_rule.to_s(tabs) << "\n"
148
- elsif @options[:line_comments]
149
- to_return << "#{old_spaces}/* line #{line}"
150
-
151
- if filename
152
- relative_filename = if @options[:css_filename]
153
- begin
154
- Pathname.new(filename).relative_path_from(
155
- Pathname.new(File.dirname(@options[:css_filename]))).to_s
156
- rescue ArgumentError
157
- nil
158
- end
159
- end
160
- relative_filename ||= filename
161
- to_return << ", #{relative_filename}"
162
- end
163
-
164
- to_return << " */\n"
165
- end
166
- end
167
-
168
- if style == :compact
169
- properties = children.map { |a| a.to_s(1) }.join(' ')
170
- to_return << "#{total_rule} { #{properties} }#{"\n" if group_end}"
171
- elsif style == :compressed
172
- properties = children.map { |a| a.to_s(1) }.join(';')
173
- to_return << "#{total_rule}{#{properties}}"
174
- else
175
- properties = children.map { |a| a.to_s(tabs + 1) }.join("\n")
176
- end_props = (style == :expanded ? "\n" + old_spaces : ' ')
177
- to_return << "#{total_rule} {\n#{properties}#{end_props}}#{"\n" if group_end}"
178
- end
179
-
180
- to_return
181
- end
182
-
183
- # Runs SassScript interpolation in the selector,
184
- # and then parses the result into a {Sass::Selector::CommaSequence}.
185
- #
186
- # @param environment [Sass::Environment] The lexical environment containing
187
- # variable and mixin values
188
- def perform!(environment)
189
- @parsed_rules = Sass::SCSS::StaticParser.new(run_interp(@rule, environment), self.line).
190
- parse_selector(self.filename)
191
- super
192
- end
193
-
194
- # Converts nested rules into a flat list of rules.
195
- #
196
- # @param extends [Haml::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
197
- # The extensions defined for this tree
198
- # @param parent [RuleNode, nil] The parent node of this node,
199
- # or nil if the parent isn't a {RuleNode}
200
- def _cssize(extends, parent)
201
- node = super
202
- rules = node.children.select {|c| c.is_a?(RuleNode)}
203
- props = node.children.reject {|c| c.is_a?(RuleNode) || c.invisible?}
204
-
205
- unless props.empty?
206
- node.children = props
207
- rules.each {|r| r.tabs += 1} if style == :nested
208
- rules.unshift(node)
209
- end
210
-
211
- rules.last.group_end = true unless parent || rules.empty?
212
-
213
- rules
214
- end
215
-
216
- # Resolves parent references and nested selectors,
217
- # and updates the indentation based on the parent's indentation.
218
- #
219
- # @param extends [Haml::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
220
- # The extensions defined for this tree
221
- # @param parent [RuleNode, nil] The parent node of this node,
222
- # or nil if the parent isn't a {RuleNode}
223
- # @raise [Sass::SyntaxError] if the rule has no parents but uses `&`
224
- def cssize!(extends, parent)
225
- self.resolved_rules = @parsed_rules.resolve_parent_refs(parent && parent.resolved_rules)
226
- super
227
- end
228
-
229
- # A hash that will be associated with this rule in the CSS document
230
- # if the {file:SASS_REFERENCE.md#debug_info-option `:debug_info` option} is enabled.
231
- # This data is used by e.g. [the FireSass Firebug extension](https://addons.mozilla.org/en-US/firefox/addon/103988).
232
- #
233
- # @return [{#to_s => #to_s}]
234
- def debug_info
235
- {:filename => filename && ("file://" + URI.escape(File.expand_path(filename))),
236
- :line => self.line}
237
- end
238
-
239
- private
240
-
241
- def debug_info_rule
242
- node = DirectiveNode.new("@media -sass-debug-info")
243
- debug_info.map {|k, v| [k.to_s, v.to_s]}.sort.each do |k, v|
244
- rule = RuleNode.new([""])
245
- rule.resolved_rules = Sass::Selector::CommaSequence.new(
246
- [Sass::Selector::Sequence.new(
247
- [Sass::Selector::SimpleSequence.new(
248
- [Sass::Selector::Element.new(k.to_s.gsub(/[^\w-]/, "\\\\\\0"), nil)])
249
- ])
250
- ])
251
- prop = PropNode.new([""], "", :new)
252
- prop.resolved_name = "font-family"
253
- prop.resolved_value = Sass::SCSS::RX.escape_ident(v.to_s)
254
- rule << prop
255
- node << rule
256
- end
257
- node.options = @options.merge(:debug_info => false, :line_comments => false, :style => :compressed)
258
- node
259
- end
260
- end
261
- end