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,55 +0,0 @@
1
- require 'sass/tree/node'
2
-
3
- module Sass::Tree
4
- # A dynamic node representing a Sass `@for` loop.
5
- #
6
- # @see Sass::Tree
7
- class ForNode < Node
8
- # @param var [String] The name of the loop variable
9
- # @param from [Script::Node] The parse tree for the initial expression
10
- # @param to [Script::Node] The parse tree for the final expression
11
- # @param exclusive [Boolean] Whether to include `to` in the loop
12
- # or stop just before
13
- def initialize(var, from, to, exclusive)
14
- @var = var
15
- @from = from
16
- @to = to
17
- @exclusive = exclusive
18
- super()
19
- end
20
-
21
- protected
22
-
23
- # @see Node#to_src
24
- def to_src(tabs, opts, fmt)
25
- to = @exclusive ? "to" : "through"
26
- "#{' ' * tabs}@for $#{dasherize(@var, opts)} from #{@from.to_sass(opts)} #{to} #{@to.to_sass(opts)}" +
27
- children_to_src(tabs, opts, fmt)
28
- end
29
-
30
- # Runs the child nodes once for each time through the loop,
31
- # varying the variable each time.
32
- #
33
- # @param environment [Sass::Environment] The lexical environment containing
34
- # variable and mixin values
35
- # @return [Array<Tree::Node>] The resulting static nodes
36
- # @see Sass::Tree
37
- def _perform(environment)
38
- from = @from.perform(environment)
39
- to = @to.perform(environment)
40
- from.assert_int!
41
- to.assert_int!
42
-
43
- to = to.coerce(from.numerator_units, from.denominator_units)
44
- range = Range.new(from.to_i, to.to_i, @exclusive)
45
-
46
- children = []
47
- environment = Sass::Environment.new(environment)
48
- range.each do |i|
49
- environment.set_local_var(@var, Sass::Script::Number.new(i, from.numerator_units, from.denominator_units))
50
- children += perform_children(environment)
51
- end
52
- children
53
- end
54
- end
55
- end
@@ -1,69 +0,0 @@
1
- require 'sass/tree/node'
2
-
3
- module Sass::Tree
4
- # A dynamic node representing a Sass `@if` statement.
5
- #
6
- # {IfNode}s are a little odd, in that they also represent `@else` and `@else if`s.
7
- # This is done as a linked list:
8
- # each {IfNode} has a link (\{#else}) to the next {IfNode}.
9
- #
10
- # @see Sass::Tree
11
- class IfNode < Node
12
- # The next {IfNode} in the if-else list, or `nil`.
13
- #
14
- # @return [IfNode]
15
- attr_accessor :else
16
-
17
- # @param expr [Script::Expr] The conditional expression.
18
- # If this is nil, this is an `@else` node, not an `@else if`
19
- def initialize(expr)
20
- @expr = expr
21
- @last_else = self
22
- super()
23
- end
24
-
25
- # Append an `@else` node to the end of the list.
26
- #
27
- # @param node [IfNode] The `@else` node to append
28
- def add_else(node)
29
- @last_else.else = node
30
- @last_else = node
31
- end
32
-
33
- # @see Node#options=
34
- def options=(options)
35
- super
36
- self.else.options = options if self.else
37
- end
38
-
39
- protected
40
-
41
- # @see Node#to_src
42
- def to_src(tabs, opts, fmt, is_else = false)
43
- name =
44
- if !is_else; "if"
45
- elsif @expr; "else if"
46
- else; "else"
47
- end
48
- str = "#{' ' * tabs}@#{name}"
49
- str << " #{@expr.to_sass(opts)}" if @expr
50
- str << children_to_src(tabs, opts, fmt)
51
- str << @else.send(:to_src, tabs, opts, fmt, true) if @else
52
- str
53
- end
54
-
55
- # Runs the child nodes if the conditional expression is true;
56
- # otherwise, tries the \{#else} nodes.
57
- #
58
- # @param environment [Sass::Environment] The lexical environment containing
59
- # variable and mixin values
60
- # @return [Array<Tree::Node>] The resulting static nodes
61
- # @see Sass::Tree
62
- def _perform(environment)
63
- environment = Sass::Environment.new(environment)
64
- return perform_children(environment) if @expr.nil? || @expr.perform(environment).to_bool
65
- return @else.perform(environment) if @else
66
- []
67
- end
68
- end
69
- end
@@ -1,102 +0,0 @@
1
- module Sass
2
- module Tree
3
- # A static node that wraps the {Sass::Tree} for an `@import`ed file.
4
- # It doesn't have a functional purpose other than to add the `@import`ed file
5
- # to the backtrace if an error occurs.
6
- class ImportNode < RootNode
7
- # The name of the imported file as it appears in the Sass document.
8
- #
9
- # @return [String]
10
- attr_reader :imported_filename
11
-
12
- # @param imported_filename [String] The name of the imported file
13
- def initialize(imported_filename)
14
- @imported_filename = imported_filename
15
- super(nil)
16
- end
17
-
18
- def invisible?; to_s.empty?; end
19
-
20
- # Returns the resolved name of the imported file,
21
- # as returned by \{Sass::Files#find\_file\_to\_import}.
22
- #
23
- # @return [String] The filename of the imported file.
24
- # This is an absolute path if the file is a `".sass"` or `".scss"` file.
25
- # @raise [Sass::SyntaxError] if `filename` ends in `".sass"` or `".scss"`
26
- # and no corresponding Sass file could be found.
27
- def full_filename
28
- @full_filename ||= import
29
- end
30
-
31
- # @see Node#to_sass
32
- def to_sass(tabs = 0, opts = {})
33
- "#{' ' * tabs}@import #{@imported_filename}\n"
34
- end
35
-
36
- # @see Node#to_scss
37
- def to_scss(tabs = 0, opts = {})
38
- "#{' ' * tabs}@import \"#{@imported_filename}\";\n"
39
- end
40
-
41
- # @see Node#cssize
42
- def cssize(*args)
43
- super.first
44
- end
45
-
46
- protected
47
-
48
- # @see Node#_cssize
49
- def _cssize(*args)
50
- super.children
51
- rescue Sass::SyntaxError => e
52
- e.modify_backtrace(:filename => children.first.filename)
53
- e.add_backtrace(:filename => @filename, :line => @line)
54
- raise e
55
- end
56
-
57
- # Returns a static DirectiveNode if this is importing a CSS file,
58
- # or parses and includes the imported Sass file.
59
- #
60
- # @param environment [Sass::Environment] The lexical environment containing
61
- # variable and mixin values
62
- def _perform(environment)
63
- return DirectiveNode.new("@import url(#{full_filename})") if full_filename =~ /\.css$/
64
- super
65
- end
66
-
67
- # Parses the imported file and runs the dynamic Sass for it.
68
- #
69
- # @param environment [Sass::Environment] The lexical environment containing
70
- # variable and mixin values
71
- def perform!(environment)
72
- environment.push_frame(:filename => @filename, :line => @line)
73
- options = @options.dup
74
- options.delete(:syntax)
75
- root = Sass::Files.tree_for(full_filename, options)
76
- @template = root.template
77
- self.children = root.children
78
- self.children = perform_children(environment)
79
- rescue Sass::SyntaxError => e
80
- e.modify_backtrace(:filename => full_filename)
81
- e.add_backtrace(:filename => @filename, :line => @line)
82
- raise e
83
- ensure
84
- environment.pop_frame
85
- end
86
-
87
- private
88
-
89
- def import_paths
90
- paths = (@options[:load_paths] || []).dup
91
- paths.unshift(File.dirname(@options[:filename])) if @options[:filename]
92
- paths
93
- end
94
-
95
- def import
96
- Sass::Files.find_file_to_import(@imported_filename, import_paths)
97
- rescue Exception => e
98
- raise SyntaxError.new(e.message, :line => self.line, :filename => @filename)
99
- end
100
- end
101
- end
102
- end
@@ -1,48 +0,0 @@
1
- module Sass
2
- module Tree
3
- # A dynamic node representing a mixin definition.
4
- #
5
- # @see Sass::Tree
6
- class MixinDefNode < Node
7
- # @param name [String] The mixin name
8
- # @param args [Array<(Script::Node, Script::Node)>] The arguments for the mixin.
9
- # Each element is a tuple containing the variable for argument
10
- # and the parse tree for the default value of the argument
11
- def initialize(name, args)
12
- @name = name
13
- @args = args
14
- super()
15
- end
16
-
17
- protected
18
-
19
- # @see Node#to_src
20
- def to_src(tabs, opts, fmt)
21
- args =
22
- if @args.empty?
23
- ""
24
- else
25
- '(' + @args.map do |v, d|
26
- if d
27
- "#{v.to_sass(opts)}: #{d.to_sass(opts)}"
28
- else
29
- v.to_sass(opts)
30
- end
31
- end.join(", ") + ')'
32
- end
33
-
34
- "#{' ' * tabs}#{fmt == :sass ? '=' : '@mixin '}#{dasherize(@name, opts)}#{args}" +
35
- children_to_src(tabs, opts, fmt)
36
- end
37
-
38
- # Loads the mixin into the environment.
39
- #
40
- # @param environment [Sass::Environment] The lexical environment containing
41
- # variable and mixin values
42
- def _perform(environment)
43
- environment.set_mixin(@name, Sass::Mixin.new(@name, @args, environment, children))
44
- []
45
- end
46
- end
47
- end
48
- end
@@ -1,111 +0,0 @@
1
- require 'sass/tree/node'
2
-
3
- module Sass::Tree
4
- # A static node representing a mixin include.
5
- # When in a static tree, the sole purpose is to wrap exceptions
6
- # to add the mixin to the backtrace.
7
- #
8
- # @see Sass::Tree
9
- class MixinNode < Node
10
- # @see Node#options=
11
- def options=(opts)
12
- super
13
- @args.each {|a| a.context = :equals} if opts[:sass2]
14
- end
15
-
16
- # @param name [String] The name of the mixin
17
- # @param args [Array<Script::Node>] The arguments to the mixin
18
- def initialize(name, args)
19
- @name = name
20
- @args = args
21
- super()
22
- end
23
-
24
- # @see Node#cssize
25
- def cssize(extends, parent = nil)
26
- _cssize(extends, parent) # Pass on the parent even if it's not a MixinNode
27
- end
28
-
29
- protected
30
-
31
- # @see Node#to_src
32
- def to_src(tabs, opts, fmt)
33
- args = '(' + @args.map {|a| a.to_sass(opts)}.join(", ") + ')' unless @args.empty?
34
- "#{' ' * tabs}#{fmt == :sass ? '+' : '@include '}#{dasherize(@name, opts)}#{args}#{semi fmt}\n"
35
- end
36
-
37
- # @see Node#_cssize
38
- def _cssize(extends, parent)
39
- children.map do |c|
40
- parent.check_child! c
41
- c.cssize(extends, parent)
42
- end.flatten
43
- rescue Sass::SyntaxError => e
44
- e.modify_backtrace(:mixin => @name, :filename => filename, :line => line)
45
- e.add_backtrace(:filename => filename, :line => line)
46
- raise e
47
- end
48
-
49
- # Runs the mixin.
50
- #
51
- # @param environment [Sass::Environment] The lexical environment containing
52
- # variable and mixin values
53
- # @raise [Sass::SyntaxError] if there is no mixin with the given name
54
- # @raise [Sass::SyntaxError] if an incorrect number of arguments was passed
55
- # @see Sass::Tree
56
- def perform!(environment)
57
- handle_include_loop!(environment) if environment.mixins_in_use.include?(@name)
58
-
59
- original_env = environment
60
- original_env.push_frame(:filename => filename, :line => line)
61
- original_env.prepare_frame(:mixin => @name)
62
- raise Sass::SyntaxError.new("Undefined mixin '#{@name}'.") unless mixin = environment.mixin(@name)
63
-
64
- raise Sass::SyntaxError.new(<<END.gsub("\n", "")) if mixin.args.size < @args.size
65
- Mixin #{@name} takes #{mixin.args.size} argument#{'s' if mixin.args.size != 1}
66
- but #{@args.size} #{@args.size == 1 ? 'was' : 'were'} passed.
67
- END
68
- environment = mixin.args.zip(@args).
69
- inject(Sass::Environment.new(mixin.environment)) do |env, ((var, default), value)|
70
- env.set_local_var(var.name,
71
- if value
72
- value.perform(environment)
73
- elsif default
74
- val = default.perform(env)
75
- if default.context == :equals && val.is_a?(Sass::Script::String)
76
- val = Sass::Script::String.new(val.value)
77
- end
78
- val
79
- end)
80
- raise Sass::SyntaxError.new("Mixin #{@name} is missing parameter #{var.inspect}.") unless env.var(var.name)
81
- env
82
- end
83
-
84
- self.children = mixin.tree.map {|c| c.perform(environment)}.flatten
85
- rescue Sass::SyntaxError => e
86
- if original_env # Don't add backtrace info if this is an @include loop
87
- e.modify_backtrace(:mixin => @name, :line => @line)
88
- e.add_backtrace(:line => @line)
89
- end
90
- raise e
91
- ensure
92
- original_env.pop_frame if original_env
93
- end
94
-
95
- private
96
-
97
- def handle_include_loop!(environment)
98
- msg = "An @include loop has been found:"
99
- mixins = environment.stack.map {|s| s[:mixin]}.compact
100
- if mixins.size == 2 && mixins[0] == mixins[1]
101
- raise Sass::SyntaxError.new("#{msg} #{@name} includes itself")
102
- end
103
-
104
- mixins << @name
105
- msg << "\n" << Haml::Util.enum_cons(mixins, 2).map do |m1, m2|
106
- " #{m1} includes #{m2}"
107
- end.join("\n")
108
- raise Sass::SyntaxError.new(msg)
109
- end
110
- end
111
- end
@@ -1,464 +0,0 @@
1
- module Sass
2
- # A namespace for nodes in the Sass parse tree.
3
- #
4
- # The Sass parse tree has three states: dynamic, static Sass, and static CSS.
5
- #
6
- # When it's first parsed, a Sass document is in the dynamic state.
7
- # It has nodes for mixin definitions and `@for` loops and so forth,
8
- # in addition to nodes for CSS rules and properties.
9
- # Nodes that only appear in this state are called **dynamic nodes**.
10
- #
11
- # {Tree::Node#perform} returns a static Sass tree, which is different.
12
- # It still has nodes for CSS rules and properties
13
- # but it doesn't have any dynamic-generation-related nodes.
14
- # The nodes in this state are in the same structure as the Sass document:
15
- # rules and properties are nested beneath one another.
16
- # Nodes that can be in this state or in the dynamic state
17
- # are called **static nodes**.
18
- #
19
- # {Tree::Node#cssize} then returns a static CSS tree.
20
- # This is like a static Sass tree,
21
- # but the structure exactly mirrors that of the generated CSS.
22
- # Rules and properties can't be nested beneath one another in this state.
23
- #
24
- # Finally, {Tree::Node#to_s} can be called on a static CSS tree
25
- # to get the actual CSS code as a string.
26
- module Tree
27
- # The abstract superclass of all parse-tree nodes.
28
- class Node
29
- include Enumerable
30
-
31
- # The child nodes of this node.
32
- #
33
- # @return [Array<Tree::Node>]
34
- attr_accessor :children
35
-
36
- # Whether or not this node has child nodes.
37
- # This may be true even when \{#children} is empty,
38
- # in which case this node has an empty block (e.g. `{}`).
39
- #
40
- # @return [Boolean]
41
- attr_accessor :has_children
42
-
43
- # The line of the document on which this node appeared.
44
- #
45
- # @return [Fixnum]
46
- attr_accessor :line
47
-
48
- # The name of the document on which this node appeared.
49
- #
50
- # @return [String]
51
- attr_writer :filename
52
-
53
- # The options hash for the node.
54
- # See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
55
- #
56
- # @return [{Symbol => Object}]
57
- attr_reader :options
58
-
59
- def initialize
60
- @children = []
61
- end
62
-
63
- # Sets the options hash for the node and all its children.
64
- #
65
- # @param options [{Symbol => Object}] The options
66
- # @see #options
67
- def options=(options)
68
- children.each {|c| c.options = options}
69
- @options = options
70
- end
71
-
72
- # @private
73
- def children=(children)
74
- self.has_children ||= !children.empty?
75
- @children = children
76
- end
77
-
78
- # The name of the document on which this node appeared.
79
- #
80
- # @return [String]
81
- def filename
82
- @filename || (@options && @options[:filename])
83
- end
84
-
85
- # Appends a child to the node.
86
- #
87
- # @param child [Tree::Node, Array<Tree::Node>] The child node or nodes
88
- # @raise [Sass::SyntaxError] if `child` is invalid
89
- # @see #invalid_child?
90
- def <<(child)
91
- return if child.nil?
92
- if child.is_a?(Array)
93
- child.each {|c| self << c}
94
- else
95
- check_child! child
96
- self.has_children = true
97
- @children << child
98
- end
99
- end
100
-
101
- # Raises an error if the given child node is invalid.
102
- #
103
- # @param child [Tree::Node] The child node
104
- # @raise [Sass::SyntaxError] if `child` is invalid
105
- # @see #invalid_child?
106
- def check_child!(child)
107
- if msg = invalid_child?(child)
108
- raise Sass::SyntaxError.new(msg, :line => child.line)
109
- end
110
- end
111
-
112
- # Compares this node and another object (only other {Tree::Node}s will be equal).
113
- # This does a structural comparison;
114
- # if the contents of the nodes and all the child nodes are equivalent,
115
- # then the nodes are as well.
116
- #
117
- # Only static nodes need to override this.
118
- #
119
- # @param other [Object] The object to compare with
120
- # @return [Boolean] Whether or not this node and the other object
121
- # are the same
122
- # @see Sass::Tree
123
- def ==(other)
124
- self.class == other.class && other.children == children
125
- end
126
-
127
- # True if \{#to\_s} will return `nil`;
128
- # that is, if the node shouldn't be rendered.
129
- # Should only be called in a static tree.
130
- #
131
- # @return [Boolean]
132
- def invisible?; false; end
133
-
134
- # The output style. See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
135
- #
136
- # @return [Symbol]
137
- def style
138
- @options[:style]
139
- end
140
-
141
- # Computes the CSS corresponding to this static CSS tree.
142
- #
143
- # \{#to_s} shouldn't be overridden directly; instead, override \{#\_to\_s}.
144
- # Only static-node subclasses need to implement \{#to\_s}.
145
- #
146
- # This may return `nil`, but it will only do so if \{#invisible?} is true.
147
- #
148
- # @param args [Array] Passed on to \{#\_to\_s}
149
- # @return [String, nil] The resulting CSS
150
- # @see Sass::Tree
151
- def to_s(*args)
152
- _to_s(*args)
153
- rescue Sass::SyntaxError => e
154
- e.modify_backtrace(:filename => filename, :line => line)
155
- raise e
156
- end
157
-
158
- # Converts a static CSS tree (e.g. the output of \{#cssize})
159
- # into another static CSS tree,
160
- # with the given extensions applied to all relevant {RuleNode}s.
161
- #
162
- # @todo Link this to the reference documentation on `@extend`
163
- # when such a thing exists.
164
- #
165
- # @param extends [Haml::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
166
- # The extensions to perform on this tree
167
- # @return [Tree::Node] The resulting tree of static CSS nodes.
168
- # @raise [Sass::SyntaxError] Only if there's a programmer error
169
- # and this is not a static CSS tree
170
- def do_extend(extends)
171
- node = dup
172
- node.children = children.map {|c| c.do_extend(extends)}
173
- node
174
- rescue Sass::SyntaxError => e
175
- e.modify_backtrace(:filename => filename, :line => line)
176
- raise e
177
- end
178
-
179
- # Converts a static Sass tree (e.g. the output of \{#perform})
180
- # into a static CSS tree.
181
- #
182
- # \{#cssize} shouldn't be overridden directly;
183
- # instead, override \{#\_cssize} or \{#cssize!}.
184
- #
185
- # @param extends [Haml::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
186
- # The extensions defined for this tree
187
- # @param parent [Node, nil] The parent node of this node.
188
- # This should only be non-nil if the parent is the same class as this node
189
- # @return [Tree::Node] The resulting tree of static nodes
190
- # @raise [Sass::SyntaxError] if some element of the tree is invalid
191
- # @see Sass::Tree
192
- def cssize(extends, parent = nil)
193
- _cssize(extends, (parent if parent.class == self.class))
194
- rescue Sass::SyntaxError => e
195
- e.modify_backtrace(:filename => filename, :line => line)
196
- raise e
197
- end
198
-
199
- # Converts a dynamic tree into a static Sass tree.
200
- # That is, runs the dynamic Sass code:
201
- # mixins, variables, control directives, and so forth.
202
- # This doesn't modify this node or any of its children.
203
- #
204
- # \{#perform} shouldn't be overridden directly;
205
- # instead, override \{#\_perform} or \{#perform!}.
206
- #
207
- # @param environment [Sass::Environment] The lexical environment containing
208
- # variable and mixin values
209
- # @return [Tree::Node] The resulting tree of static nodes
210
- # @raise [Sass::SyntaxError] if some element of the tree is invalid
211
- # @see Sass::Tree
212
- def perform(environment)
213
- _perform(environment)
214
- rescue Sass::SyntaxError => e
215
- e.modify_backtrace(:filename => filename, :line => line)
216
- raise e
217
- end
218
-
219
- # Iterates through each node in the tree rooted at this node
220
- # in a pre-order walk.
221
- #
222
- # @yield node
223
- # @yieldparam node [Node] a node in the tree
224
- def each(&block)
225
- yield self
226
- children.each {|c| c.each(&block)}
227
- end
228
-
229
- # Converts a node to Sass code that will generate it.
230
- #
231
- # @param tabs [Fixnum] The amount of tabulation to use for the Sass code
232
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
233
- # @return [String] The Sass code corresponding to the node
234
- def to_sass(tabs = 0, opts = {})
235
- to_src(tabs, opts, :sass)
236
- end
237
-
238
- # Converts a node to SCSS code that will generate it.
239
- #
240
- # @param tabs [Fixnum] The amount of tabulation to use for the SCSS code
241
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
242
- # @return [String] The Sass code corresponding to the node
243
- def to_scss(tabs = 0, opts = {})
244
- to_src(tabs, opts, :scss)
245
- end
246
-
247
- protected
248
-
249
- # Computes the CSS corresponding to this particular Sass node.
250
- #
251
- # This method should never raise {Sass::SyntaxError}s.
252
- # Such errors will not be properly annotated with Sass backtrace information.
253
- # All error conditions should be checked in earlier transformations,
254
- # such as \{#cssize} and \{#perform}.
255
- #
256
- # @param args [Array] ignored
257
- # @return [String, nil] The resulting CSS
258
- # @see #to_s
259
- # @see Sass::Tree
260
- def _to_s
261
- raise NotImplementedError.new("All static-node subclasses of Sass::Tree::Node must override #_to_s or #to_s.")
262
- end
263
-
264
- # Converts this static Sass node into a static CSS node,
265
- # returning the new node.
266
- # This doesn't modify this node or any of its children.
267
- #
268
- # @param extends [Haml::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
269
- # The extensions defined for this tree
270
- # @param parent [Node, nil] The parent node of this node.
271
- # This should only be non-nil if the parent is the same class as this node
272
- # @return [Tree::Node, Array<Tree::Node>] The resulting static CSS nodes
273
- # @raise [Sass::SyntaxError] if some element of the tree is invalid
274
- # @see #cssize
275
- # @see Sass::Tree
276
- def _cssize(extends, parent)
277
- node = dup
278
- node.cssize!(extends, parent)
279
- node
280
- end
281
-
282
- # Destructively converts this static Sass node into a static CSS node.
283
- # This *does* modify this node,
284
- # but will be run non-destructively by \{#\_cssize\}.
285
- #
286
- # @param extends [Haml::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
287
- # The extensions defined for this tree
288
- # @param parent [Node, nil] The parent node of this node.
289
- # This should only be non-nil if the parent is the same class as this node
290
- # @see #cssize
291
- def cssize!(extends, parent)
292
- self.children = children.map {|c| c.cssize(extends, self)}.flatten
293
- end
294
-
295
- # Runs any dynamic Sass code in this particular node.
296
- # This doesn't modify this node or any of its children.
297
- #
298
- # @param environment [Sass::Environment] The lexical environment containing
299
- # variable and mixin values
300
- # @return [Tree::Node, Array<Tree::Node>] The resulting static nodes
301
- # @see #perform
302
- # @see Sass::Tree
303
- def _perform(environment)
304
- node = dup
305
- node.perform!(environment)
306
- node
307
- end
308
-
309
- # Destructively runs dynamic Sass code in this particular node.
310
- # This *does* modify this node,
311
- # but will be run non-destructively by \{#\_perform\}.
312
- #
313
- # @param environment [Sass::Environment] The lexical environment containing
314
- # variable and mixin values
315
- # @see #perform
316
- def perform!(environment)
317
- self.children = perform_children(Environment.new(environment))
318
- self.children.each {|c| check_child! c}
319
- end
320
-
321
- # Non-destructively runs \{#perform} on all children of the current node.
322
- #
323
- # @param environment [Sass::Environment] The lexical environment containing
324
- # variable and mixin values
325
- # @return [Array<Tree::Node>] The resulting static nodes
326
- def perform_children(environment)
327
- children.map {|c| c.perform(environment)}.flatten
328
- end
329
-
330
- # Replaces SassScript in a chunk of text
331
- # with the resulting value.
332
- #
333
- # @param text [Array<String, Sass::Script::Node>] The text to interpolate
334
- # @param environment [Sass::Environment] The lexical environment containing
335
- # variable and mixin values
336
- # @return [String] The interpolated text
337
- def run_interp(text, environment)
338
- text.map do |r|
339
- next r if r.is_a?(String)
340
- val = r.perform(environment)
341
- # Interpolated strings should never render with quotes
342
- next val.value if val.is_a?(Sass::Script::String)
343
- val.to_s
344
- end.join.strip
345
- end
346
-
347
- # @see Haml::Shared.balance
348
- # @raise [Sass::SyntaxError] if the brackets aren't balanced
349
- def balance(*args)
350
- res = Haml::Shared.balance(*args)
351
- return res if res
352
- raise Sass::SyntaxError.new("Unbalanced brackets.", :line => line)
353
- end
354
-
355
- # Returns an error message if the given child node is invalid,
356
- # and false otherwise.
357
- #
358
- # By default, all child nodes except those only allowed under specific nodes
359
- # ({Tree::MixinDefNode}, {Tree::ImportNode}, {Tree::ExtendNode}) are valid.
360
- # This is expected to be overriden by subclasses
361
- # for which some children are invalid.
362
- #
363
- # @param child [Tree::Node] A potential child node
364
- # @return [Boolean, String] Whether or not the child node is valid,
365
- # as well as the error message to display if it is invalid
366
- def invalid_child?(child)
367
- case child
368
- when Tree::MixinDefNode
369
- "Mixins may only be defined at the root of a document."
370
- when Tree::ImportNode
371
- "Import directives may only be used at the root of a document."
372
- end
373
- end
374
-
375
- # Converts a node to Sass or SCSS code that will generate it.
376
- #
377
- # This method is called by the default \{#to\_sass} and \{#to\_scss} methods,
378
- # so that the same code can be used for both with minor variations.
379
- #
380
- # @param tabs [Fixnum] The amount of tabulation to use for the SCSS code
381
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
382
- # @param fmt [Symbol] `:sass` or `:scss`
383
- # @return [String] The Sass or SCSS code corresponding to the node
384
- def to_src(tabs, opts, fmt)
385
- raise NotImplementedError.new("All static-node subclasses of Sass::Tree::Node must override #to_#{fmt}.")
386
- end
387
-
388
- # Converts the children of this node to a Sass or SCSS string.
389
- # This will return the trailing newline for the previous line,
390
- # including brackets if this is SCSS.
391
- #
392
- # @param tabs [Fixnum] The amount of tabulation to use for the Sass code
393
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
394
- # @param fmt [Symbol] `:sass` or `:scss`
395
- # @return [String] The Sass or SCSS code corresponding to the children
396
- def children_to_src(tabs, opts, fmt)
397
- return fmt == :sass ? "\n" : " {}\n" if children.empty?
398
-
399
- (fmt == :sass ? "\n" : " {\n") +
400
- children.map {|c| c.send("to_#{fmt}", tabs + 1, opts)}.join.rstrip +
401
- (fmt == :sass ? "\n" : " }\n")
402
- end
403
-
404
- # Converts a selector to a Sass or SCSS string.
405
- #
406
- # @param sel [Array<String, Sass::Script::Node>] The selector to convert
407
- # @param tabs [Fixnum] The indentation of the selector
408
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
409
- # @param fmt [Symbol] `:sass` or `:scss`
410
- # @return [String] The Sass or SCSS code corresponding to the selector
411
- def selector_to_src(sel, tabs, opts, fmt)
412
- fmt == :sass ? selector_to_sass(sel, opts) : selector_to_scss(sel, tabs, opts)
413
- end
414
-
415
- # Converts a selector to a Sass string.
416
- #
417
- # @param sel [Array<String, Sass::Script::Node>] The selector to convert
418
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
419
- # @return [String] The Sass code corresponding to the selector
420
- def selector_to_sass(sel, opts)
421
- sel.map do |r|
422
- if r.is_a?(String)
423
- r.gsub(/(,[ \t]*)?\n\s*/) {$1 ? $1 + "\n" : " "}
424
- else
425
- "\#{#{r.to_sass(opts)}}"
426
- end
427
- end.join
428
- end
429
-
430
- # Converts a selector to a SCSS string.
431
- #
432
- # @param sel [Array<String, Sass::Script::Node>] The selector to convert
433
- # @param tabs [Fixnum] The indentation of the selector
434
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
435
- # @return [String] The SCSS code corresponding to the selector
436
- def selector_to_scss(sel, tabs, opts)
437
- sel.map {|r| r.is_a?(String) ? r : "\#{#{r.to_sass(opts)}}"}.
438
- join.gsub(/^[ \t]*/, ' ' * tabs)
439
- end
440
-
441
- # Convert any underscores in a string into hyphens,
442
- # but only if the `:dasherize` option is set.
443
- #
444
- # @param s [String] The string to convert
445
- # @param opts [{Symbol => Object}] The options hash
446
- # @return [String] The converted string
447
- def dasherize(s, opts)
448
- if opts[:dasherize]
449
- s.gsub('_', '-')
450
- else
451
- s
452
- end
453
- end
454
-
455
- # Returns a semicolon if this is SCSS, or an empty string if this is Sass.
456
- #
457
- # @param fmt [Symbol] `:sass` or `:scss`
458
- # @return [String] A semicolon or the empty string
459
- def semi(fmt)
460
- fmt == :sass ? "" : ";"
461
- end
462
- end
463
- end
464
- end