xass 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (252) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/Gemfile +9 -0
  4. data/Gemfile.lock +39 -0
  5. data/README.md +131 -193
  6. data/lib/initialize.rb +8 -0
  7. data/lib/xass.rb +67 -0
  8. data/spec/secrets.yml +4 -0
  9. data/spec/spec_helper.rb +8 -0
  10. data/spec/test_spec.rb +5 -0
  11. data/template/secrets.yml +2 -0
  12. data/xass.gemspec +15 -0
  13. metadata +53 -294
  14. data/.yardopts +0 -11
  15. data/CONTRIBUTING +0 -3
  16. data/MIT-LICENSE +0 -20
  17. data/Rakefile +0 -349
  18. data/VERSION +0 -1
  19. data/VERSION_NAME +0 -1
  20. data/bin/push +0 -13
  21. data/bin/sass +0 -13
  22. data/bin/sass-convert +0 -12
  23. data/bin/scss +0 -13
  24. data/extra/update_watch.rb +0 -13
  25. data/init.rb +0 -18
  26. data/lib/sass/cache_stores/base.rb +0 -88
  27. data/lib/sass/cache_stores/chain.rb +0 -33
  28. data/lib/sass/cache_stores/filesystem.rb +0 -64
  29. data/lib/sass/cache_stores/memory.rb +0 -47
  30. data/lib/sass/cache_stores/null.rb +0 -25
  31. data/lib/sass/cache_stores.rb +0 -15
  32. data/lib/sass/callbacks.rb +0 -66
  33. data/lib/sass/css.rb +0 -409
  34. data/lib/sass/engine.rb +0 -930
  35. data/lib/sass/environment.rb +0 -101
  36. data/lib/sass/error.rb +0 -201
  37. data/lib/sass/exec.rb +0 -707
  38. data/lib/sass/importers/base.rb +0 -139
  39. data/lib/sass/importers/filesystem.rb +0 -186
  40. data/lib/sass/importers.rb +0 -22
  41. data/lib/sass/logger/base.rb +0 -32
  42. data/lib/sass/logger/log_level.rb +0 -49
  43. data/lib/sass/logger.rb +0 -15
  44. data/lib/sass/media.rb +0 -213
  45. data/lib/sass/plugin/compiler.rb +0 -406
  46. data/lib/sass/plugin/configuration.rb +0 -123
  47. data/lib/sass/plugin/generic.rb +0 -15
  48. data/lib/sass/plugin/merb.rb +0 -48
  49. data/lib/sass/plugin/rack.rb +0 -60
  50. data/lib/sass/plugin/rails.rb +0 -47
  51. data/lib/sass/plugin/staleness_checker.rb +0 -199
  52. data/lib/sass/plugin.rb +0 -133
  53. data/lib/sass/railtie.rb +0 -10
  54. data/lib/sass/repl.rb +0 -57
  55. data/lib/sass/root.rb +0 -7
  56. data/lib/sass/script/arg_list.rb +0 -52
  57. data/lib/sass/script/bool.rb +0 -18
  58. data/lib/sass/script/color.rb +0 -606
  59. data/lib/sass/script/css_lexer.rb +0 -29
  60. data/lib/sass/script/css_parser.rb +0 -31
  61. data/lib/sass/script/funcall.rb +0 -245
  62. data/lib/sass/script/functions.rb +0 -1543
  63. data/lib/sass/script/interpolation.rb +0 -79
  64. data/lib/sass/script/lexer.rb +0 -345
  65. data/lib/sass/script/list.rb +0 -85
  66. data/lib/sass/script/literal.rb +0 -221
  67. data/lib/sass/script/node.rb +0 -99
  68. data/lib/sass/script/null.rb +0 -37
  69. data/lib/sass/script/number.rb +0 -453
  70. data/lib/sass/script/operation.rb +0 -110
  71. data/lib/sass/script/parser.rb +0 -502
  72. data/lib/sass/script/string.rb +0 -51
  73. data/lib/sass/script/string_interpolation.rb +0 -103
  74. data/lib/sass/script/unary_operation.rb +0 -69
  75. data/lib/sass/script/variable.rb +0 -58
  76. data/lib/sass/script.rb +0 -39
  77. data/lib/sass/scss/css_parser.rb +0 -36
  78. data/lib/sass/scss/parser.rb +0 -1180
  79. data/lib/sass/scss/rx.rb +0 -133
  80. data/lib/sass/scss/script_lexer.rb +0 -15
  81. data/lib/sass/scss/script_parser.rb +0 -25
  82. data/lib/sass/scss/static_parser.rb +0 -54
  83. data/lib/sass/scss.rb +0 -16
  84. data/lib/sass/selector/abstract_sequence.rb +0 -94
  85. data/lib/sass/selector/comma_sequence.rb +0 -92
  86. data/lib/sass/selector/sequence.rb +0 -507
  87. data/lib/sass/selector/simple.rb +0 -119
  88. data/lib/sass/selector/simple_sequence.rb +0 -215
  89. data/lib/sass/selector.rb +0 -452
  90. data/lib/sass/shared.rb +0 -76
  91. data/lib/sass/supports.rb +0 -229
  92. data/lib/sass/tree/charset_node.rb +0 -22
  93. data/lib/sass/tree/comment_node.rb +0 -82
  94. data/lib/sass/tree/content_node.rb +0 -9
  95. data/lib/sass/tree/css_import_node.rb +0 -60
  96. data/lib/sass/tree/debug_node.rb +0 -18
  97. data/lib/sass/tree/directive_node.rb +0 -42
  98. data/lib/sass/tree/each_node.rb +0 -24
  99. data/lib/sass/tree/extend_node.rb +0 -36
  100. data/lib/sass/tree/for_node.rb +0 -36
  101. data/lib/sass/tree/function_node.rb +0 -34
  102. data/lib/sass/tree/if_node.rb +0 -52
  103. data/lib/sass/tree/import_node.rb +0 -75
  104. data/lib/sass/tree/media_node.rb +0 -58
  105. data/lib/sass/tree/mixin_def_node.rb +0 -38
  106. data/lib/sass/tree/mixin_node.rb +0 -39
  107. data/lib/sass/tree/node.rb +0 -196
  108. data/lib/sass/tree/prop_node.rb +0 -152
  109. data/lib/sass/tree/return_node.rb +0 -18
  110. data/lib/sass/tree/root_node.rb +0 -78
  111. data/lib/sass/tree/rule_node.rb +0 -132
  112. data/lib/sass/tree/supports_node.rb +0 -51
  113. data/lib/sass/tree/trace_node.rb +0 -32
  114. data/lib/sass/tree/variable_node.rb +0 -30
  115. data/lib/sass/tree/visitors/base.rb +0 -75
  116. data/lib/sass/tree/visitors/check_nesting.rb +0 -147
  117. data/lib/sass/tree/visitors/convert.rb +0 -316
  118. data/lib/sass/tree/visitors/cssize.rb +0 -241
  119. data/lib/sass/tree/visitors/deep_copy.rb +0 -102
  120. data/lib/sass/tree/visitors/extend.rb +0 -68
  121. data/lib/sass/tree/visitors/perform.rb +0 -446
  122. data/lib/sass/tree/visitors/set_options.rb +0 -125
  123. data/lib/sass/tree/visitors/to_css.rb +0 -228
  124. data/lib/sass/tree/warn_node.rb +0 -18
  125. data/lib/sass/tree/while_node.rb +0 -18
  126. data/lib/sass/util/multibyte_string_scanner.rb +0 -155
  127. data/lib/sass/util/subset_map.rb +0 -109
  128. data/lib/sass/util/test.rb +0 -10
  129. data/lib/sass/util.rb +0 -948
  130. data/lib/sass/version.rb +0 -126
  131. data/lib/sass.rb +0 -95
  132. data/rails/init.rb +0 -1
  133. data/test/Gemfile +0 -3
  134. data/test/Gemfile.lock +0 -10
  135. data/test/sass/cache_test.rb +0 -89
  136. data/test/sass/callbacks_test.rb +0 -61
  137. data/test/sass/conversion_test.rb +0 -1760
  138. data/test/sass/css2sass_test.rb +0 -458
  139. data/test/sass/data/hsl-rgb.txt +0 -319
  140. data/test/sass/engine_test.rb +0 -3244
  141. data/test/sass/exec_test.rb +0 -86
  142. data/test/sass/extend_test.rb +0 -1482
  143. data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
  144. data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
  145. data/test/sass/functions_test.rb +0 -1139
  146. data/test/sass/importer_test.rb +0 -192
  147. data/test/sass/logger_test.rb +0 -58
  148. data/test/sass/mock_importer.rb +0 -49
  149. data/test/sass/more_results/more1.css +0 -9
  150. data/test/sass/more_results/more1_with_line_comments.css +0 -26
  151. data/test/sass/more_results/more_import.css +0 -29
  152. data/test/sass/more_templates/_more_partial.sass +0 -2
  153. data/test/sass/more_templates/more1.sass +0 -23
  154. data/test/sass/more_templates/more_import.sass +0 -11
  155. data/test/sass/plugin_test.rb +0 -564
  156. data/test/sass/results/alt.css +0 -4
  157. data/test/sass/results/basic.css +0 -9
  158. data/test/sass/results/cached_import_option.css +0 -3
  159. data/test/sass/results/compact.css +0 -5
  160. data/test/sass/results/complex.css +0 -86
  161. data/test/sass/results/compressed.css +0 -1
  162. data/test/sass/results/expanded.css +0 -19
  163. data/test/sass/results/filename_fn.css +0 -3
  164. data/test/sass/results/if.css +0 -3
  165. data/test/sass/results/import.css +0 -31
  166. data/test/sass/results/import_charset.css +0 -5
  167. data/test/sass/results/import_charset_1_8.css +0 -5
  168. data/test/sass/results/import_charset_ibm866.css +0 -5
  169. data/test/sass/results/import_content.css +0 -1
  170. data/test/sass/results/line_numbers.css +0 -49
  171. data/test/sass/results/mixins.css +0 -95
  172. data/test/sass/results/multiline.css +0 -24
  173. data/test/sass/results/nested.css +0 -22
  174. data/test/sass/results/options.css +0 -1
  175. data/test/sass/results/parent_ref.css +0 -13
  176. data/test/sass/results/script.css +0 -16
  177. data/test/sass/results/scss_import.css +0 -31
  178. data/test/sass/results/scss_importee.css +0 -2
  179. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +0 -1
  180. data/test/sass/results/subdir/subdir.css +0 -3
  181. data/test/sass/results/units.css +0 -11
  182. data/test/sass/results/warn_imported.css +0 -0
  183. data/test/sass/script_conversion_test.rb +0 -299
  184. data/test/sass/script_test.rb +0 -622
  185. data/test/sass/scss/css_test.rb +0 -1100
  186. data/test/sass/scss/rx_test.rb +0 -156
  187. data/test/sass/scss/scss_test.rb +0 -2106
  188. data/test/sass/scss/test_helper.rb +0 -37
  189. data/test/sass/templates/_cached_import_option_partial.scss +0 -1
  190. data/test/sass/templates/_double_import_loop2.sass +0 -1
  191. data/test/sass/templates/_filename_fn_import.scss +0 -11
  192. data/test/sass/templates/_imported_charset_ibm866.sass +0 -4
  193. data/test/sass/templates/_imported_charset_utf8.sass +0 -4
  194. data/test/sass/templates/_imported_content.sass +0 -3
  195. data/test/sass/templates/_partial.sass +0 -2
  196. data/test/sass/templates/_same_name_different_partiality.scss +0 -1
  197. data/test/sass/templates/alt.sass +0 -16
  198. data/test/sass/templates/basic.sass +0 -23
  199. data/test/sass/templates/bork1.sass +0 -2
  200. data/test/sass/templates/bork2.sass +0 -2
  201. data/test/sass/templates/bork3.sass +0 -2
  202. data/test/sass/templates/bork4.sass +0 -2
  203. data/test/sass/templates/bork5.sass +0 -3
  204. data/test/sass/templates/cached_import_option.scss +0 -3
  205. data/test/sass/templates/compact.sass +0 -17
  206. data/test/sass/templates/complex.sass +0 -305
  207. data/test/sass/templates/compressed.sass +0 -15
  208. data/test/sass/templates/double_import_loop1.sass +0 -1
  209. data/test/sass/templates/expanded.sass +0 -17
  210. data/test/sass/templates/filename_fn.scss +0 -18
  211. data/test/sass/templates/if.sass +0 -11
  212. data/test/sass/templates/import.sass +0 -12
  213. data/test/sass/templates/import_charset.sass +0 -9
  214. data/test/sass/templates/import_charset_1_8.sass +0 -6
  215. data/test/sass/templates/import_charset_ibm866.sass +0 -11
  216. data/test/sass/templates/import_content.sass +0 -4
  217. data/test/sass/templates/importee.less +0 -2
  218. data/test/sass/templates/importee.sass +0 -19
  219. data/test/sass/templates/line_numbers.sass +0 -13
  220. data/test/sass/templates/mixin_bork.sass +0 -5
  221. data/test/sass/templates/mixins.sass +0 -76
  222. data/test/sass/templates/multiline.sass +0 -20
  223. data/test/sass/templates/nested.sass +0 -25
  224. data/test/sass/templates/nested_bork1.sass +0 -2
  225. data/test/sass/templates/nested_bork2.sass +0 -2
  226. data/test/sass/templates/nested_bork3.sass +0 -2
  227. data/test/sass/templates/nested_bork4.sass +0 -2
  228. data/test/sass/templates/nested_import.sass +0 -2
  229. data/test/sass/templates/nested_mixin_bork.sass +0 -6
  230. data/test/sass/templates/options.sass +0 -2
  231. data/test/sass/templates/parent_ref.sass +0 -25
  232. data/test/sass/templates/same_name_different_ext.sass +0 -2
  233. data/test/sass/templates/same_name_different_ext.scss +0 -1
  234. data/test/sass/templates/same_name_different_partiality.scss +0 -1
  235. data/test/sass/templates/script.sass +0 -101
  236. data/test/sass/templates/scss_import.scss +0 -11
  237. data/test/sass/templates/scss_importee.scss +0 -1
  238. data/test/sass/templates/single_import_loop.sass +0 -1
  239. data/test/sass/templates/subdir/import_up1.scss +0 -1
  240. data/test/sass/templates/subdir/import_up2.scss +0 -1
  241. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +0 -2
  242. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +0 -3
  243. data/test/sass/templates/subdir/subdir.sass +0 -6
  244. data/test/sass/templates/units.sass +0 -11
  245. data/test/sass/templates/warn.sass +0 -3
  246. data/test/sass/templates/warn_imported.sass +0 -4
  247. data/test/sass/test_helper.rb +0 -8
  248. data/test/sass/util/multibyte_string_scanner_test.rb +0 -147
  249. data/test/sass/util/subset_map_test.rb +0 -91
  250. data/test/sass/util_test.rb +0 -382
  251. data/test/test_helper.rb +0 -80
  252. /data/{test/sass/results/warn.css → template/files/.gitkeep} +0 -0
@@ -1,68 +0,0 @@
1
- # A visitor for performing selector inheritance on a static CSS tree.
2
- #
3
- # Destructively modifies the tree.
4
- class Sass::Tree::Visitors::Extend < Sass::Tree::Visitors::Base
5
- # Performs the given extensions on the static CSS tree based in `root`, then
6
- # validates that all extends matched some selector.
7
- #
8
- # @param root [Tree::Node] The root node of the tree to visit.
9
- # @param extends [Sass::Util::SubsetMap{Selector::Simple =>
10
- # Sass::Tree::Visitors::Cssize::Extend}]
11
- # The extensions to perform on this tree.
12
- # @return [Object] The return value of \{#visit} for the root node.
13
- def self.visit(root, extends)
14
- return if extends.empty?
15
- new(extends).send(:visit, root)
16
- check_extends_fired! extends
17
- end
18
-
19
- protected
20
-
21
- def initialize(extends)
22
- @parent_directives = []
23
- @extends = extends
24
- end
25
-
26
- # If an exception is raised, this adds proper metadata to the backtrace.
27
- def visit(node)
28
- super(node)
29
- rescue Sass::SyntaxError => e
30
- e.modify_backtrace(:filename => node.filename, :line => node.line)
31
- raise e
32
- end
33
-
34
- # Keeps track of the current parent directives.
35
- def visit_children(parent)
36
- @parent_directives.push parent if parent.is_a?(Sass::Tree::DirectiveNode)
37
- super
38
- ensure
39
- @parent_directives.pop if parent.is_a?(Sass::Tree::DirectiveNode)
40
- end
41
-
42
- # Applies the extend to a single rule's selector.
43
- def visit_rule(node)
44
- node.resolved_rules = node.resolved_rules.do_extend(@extends, @parent_directives)
45
- end
46
-
47
- private
48
-
49
- def self.check_extends_fired!(extends)
50
- extends.each_value do |ex|
51
- next if ex.result == :succeeded || ex.node.optional?
52
- warn = "\"#{ex.extender}\" failed to @extend \"#{ex.target.join}\"."
53
- reason =
54
- if ex.result == :not_found
55
- "The selector \"#{ex.target.join}\" was not found."
56
- else
57
- "No selectors matching \"#{ex.target.join}\" could be unified with \"#{ex.extender}\"."
58
- end
59
-
60
- Sass::Util.sass_warn <<WARN
61
- WARNING on line #{ex.node.line}#{" of #{ex.node.filename}" if ex.node.filename}: #{warn}
62
- #{reason}
63
- This will be an error in future releases of Sass.
64
- Use "@extend #{ex.target.join} !optional" if the extend should be able to fail.
65
- WARN
66
- end
67
- end
68
- end
@@ -1,446 +0,0 @@
1
- # A visitor for converting a dynamic Sass tree into a static Sass tree.
2
- class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
3
- # @param root [Tree::Node] The root node of the tree to visit.
4
- # @param environment [Sass::Environment] The lexical environment.
5
- # @return [Tree::Node] The resulting tree of static nodes.
6
- def self.visit(root, environment = Sass::Environment.new)
7
- new(environment).send(:visit, root)
8
- end
9
-
10
- # @api private
11
- def self.perform_arguments(callable, args, keywords, splat)
12
- desc = "#{callable.type.capitalize} #{callable.name}"
13
- downcase_desc = "#{callable.type} #{callable.name}"
14
-
15
- begin
16
- unless keywords.empty?
17
- unknown_args = Sass::Util.array_minus(keywords.keys,
18
- callable.args.map {|var| var.first.underscored_name})
19
- if callable.splat && unknown_args.include?(callable.splat.underscored_name)
20
- raise Sass::SyntaxError.new("Argument $#{callable.splat.name} of #{downcase_desc} cannot be used as a named argument.")
21
- elsif unknown_args.any?
22
- description = unknown_args.length > 1 ? 'the following arguments:' : 'an argument named'
23
- raise Sass::SyntaxError.new("#{desc} doesn't have #{description} #{unknown_args.map {|name| "$#{name}"}.join ', '}.")
24
- end
25
- end
26
- rescue Sass::SyntaxError => keyword_exception
27
- end
28
-
29
- # If there's no splat, raise the keyword exception immediately. The actual
30
- # raising happens in the ensure clause at the end of this function.
31
- return if keyword_exception && !callable.splat
32
-
33
- if args.size > callable.args.size && !callable.splat
34
- takes = callable.args.size
35
- passed = args.size
36
- raise Sass::SyntaxError.new(
37
- "#{desc} takes #{takes} argument#{'s' unless takes == 1} " +
38
- "but #{passed} #{passed == 1 ? 'was' : 'were'} passed.")
39
- end
40
-
41
- splat_sep = :comma
42
- if splat
43
- args += splat.to_a
44
- splat_sep = splat.separator if splat.is_a?(Sass::Script::List)
45
- # If the splat argument exists, there won't be any keywords passed in
46
- # manually, so we can safely overwrite rather than merge here.
47
- keywords = splat.keywords if splat.is_a?(Sass::Script::ArgList)
48
- end
49
-
50
- keywords = keywords.dup
51
- env = Sass::Environment.new(callable.environment)
52
- callable.args.zip(args[0...callable.args.length]) do |(var, default), value|
53
- if value && keywords.include?(var.underscored_name)
54
- raise Sass::SyntaxError.new("#{desc} was passed argument $#{var.name} both by position and by name.")
55
- end
56
-
57
- value ||= keywords.delete(var.underscored_name)
58
- value ||= default && default.perform(env)
59
- raise Sass::SyntaxError.new("#{desc} is missing argument #{var.inspect}.") unless value
60
- env.set_local_var(var.name, value)
61
- end
62
-
63
- if callable.splat
64
- rest = args[callable.args.length..-1]
65
- arg_list = Sass::Script::ArgList.new(rest, keywords.dup, splat_sep)
66
- arg_list.options = env.options
67
- env.set_local_var(callable.splat.name, arg_list)
68
- end
69
-
70
- yield env
71
- rescue Exception => e
72
- ensure
73
- # If there's a keyword exception, we don't want to throw it immediately,
74
- # because the invalid keywords may be part of a glob argument that should be
75
- # passed on to another function. So we only raise it if we reach the end of
76
- # this function *and* the keywords attached to the argument list glob object
77
- # haven't been accessed.
78
- #
79
- # The keyword exception takes precedence over any Sass errors, but not over
80
- # non-Sass exceptions.
81
- if keyword_exception &&
82
- !(arg_list && arg_list.keywords_accessed) &&
83
- (e.nil? || e.is_a?(Sass::SyntaxError))
84
- raise keyword_exception
85
- elsif e
86
- raise e
87
- end
88
- end
89
-
90
- protected
91
-
92
- def initialize(env)
93
- @environment = env
94
- # Stack trace information, including mixin includes and imports.
95
- @stack = []
96
- end
97
-
98
- # If an exception is raised, this adds proper metadata to the backtrace.
99
- def visit(node)
100
- super(node.dup)
101
- rescue Sass::SyntaxError => e
102
- e.modify_backtrace(:filename => node.filename, :line => node.line)
103
- raise e
104
- end
105
-
106
- # Keeps track of the current environment.
107
- def visit_children(parent)
108
- with_environment Sass::Environment.new(@environment, parent.options) do
109
- parent.children = super.flatten
110
- parent
111
- end
112
- end
113
-
114
- # Runs a block of code with the current environment replaced with the given one.
115
- #
116
- # @param env [Sass::Environment] The new environment for the duration of the block.
117
- # @yield A block in which the environment is set to `env`.
118
- # @return [Object] The return value of the block.
119
- def with_environment(env)
120
- old_env, @environment = @environment, env
121
- yield
122
- ensure
123
- @environment = old_env
124
- end
125
-
126
- # Sets the options on the environment if this is the top-level root.
127
- def visit_root(node)
128
- yield
129
- rescue Sass::SyntaxError => e
130
- e.sass_template ||= node.template
131
- raise e
132
- end
133
-
134
- # Removes this node from the tree if it's a silent comment.
135
- def visit_comment(node)
136
- return [] if node.invisible?
137
- node.resolved_value = run_interp_no_strip(node.value)
138
- node.resolved_value.gsub!(/\\([\\#])/, '\1')
139
- node
140
- end
141
-
142
- # Prints the expression to STDERR.
143
- def visit_debug(node)
144
- res = node.expr.perform(@environment)
145
- res = res.value if res.is_a?(Sass::Script::String)
146
- if node.filename
147
- Sass::Util.sass_warn "#{node.filename}:#{node.line} DEBUG: #{res}"
148
- else
149
- Sass::Util.sass_warn "Line #{node.line} DEBUG: #{res}"
150
- end
151
- []
152
- end
153
-
154
- # Runs the child nodes once for each value in the list.
155
- def visit_each(node)
156
- list = node.list.perform(@environment)
157
-
158
- with_environment Sass::Environment.new(@environment) do
159
- list.to_a.map do |v|
160
- @environment.set_local_var(node.var, v)
161
- node.children.map {|c| visit(c)}
162
- end.flatten
163
- end
164
- end
165
-
166
- # Runs SassScript interpolation in the selector,
167
- # and then parses the result into a {Sass::Selector::CommaSequence}.
168
- def visit_extend(node)
169
- parser = Sass::SCSS::StaticParser.new(run_interp(node.selector), node.filename, node.line)
170
- node.resolved_selector = parser.parse_selector
171
- node
172
- end
173
-
174
- # Runs the child nodes once for each time through the loop, varying the variable each time.
175
- def visit_for(node)
176
- from = node.from.perform(@environment)
177
- to = node.to.perform(@environment)
178
- from.assert_int!
179
- to.assert_int!
180
-
181
- to = to.coerce(from.numerator_units, from.denominator_units)
182
- range = Range.new(from.to_i, to.to_i, node.exclusive)
183
-
184
- with_environment Sass::Environment.new(@environment) do
185
- range.map do |i|
186
- @environment.set_local_var(node.var,
187
- Sass::Script::Number.new(i, from.numerator_units, from.denominator_units))
188
- node.children.map {|c| visit(c)}
189
- end.flatten
190
- end
191
- end
192
-
193
- # Loads the function into the environment.
194
- def visit_function(node)
195
- env = Sass::Environment.new(@environment, node.options)
196
- @environment.set_local_function(node.name,
197
- Sass::Callable.new(node.name, node.args, node.splat, env, node.children, !:has_content, "function"))
198
- []
199
- end
200
-
201
- # Runs the child nodes if the conditional expression is true;
202
- # otherwise, tries the else nodes.
203
- def visit_if(node)
204
- if node.expr.nil? || node.expr.perform(@environment).to_bool
205
- yield
206
- node.children
207
- elsif node.else
208
- visit(node.else)
209
- else
210
- []
211
- end
212
- end
213
-
214
- # Returns a static DirectiveNode if this is importing a CSS file,
215
- # or parses and includes the imported Sass file.
216
- def visit_import(node)
217
- if path = node.css_import?
218
- return Sass::Tree::CssImportNode.resolved("url(#{path})")
219
- end
220
- file = node.imported_file
221
- handle_import_loop!(node) if @stack.any? {|e| e[:filename] == file.options[:filename]}
222
-
223
- begin
224
- @stack.push(:filename => node.filename, :line => node.line)
225
- root = file.to_tree
226
- Sass::Tree::Visitors::CheckNesting.visit(root)
227
- node.children = root.children.map {|c| visit(c)}.flatten
228
- node
229
- rescue Sass::SyntaxError => e
230
- e.modify_backtrace(:filename => node.imported_file.options[:filename])
231
- e.add_backtrace(:filename => node.filename, :line => node.line)
232
- raise e
233
- end
234
- ensure
235
- @stack.pop unless path
236
- end
237
-
238
- # Loads a mixin into the environment.
239
- def visit_mixindef(node)
240
- env = Sass::Environment.new(@environment, node.options)
241
- @environment.set_local_mixin(node.name,
242
- Sass::Callable.new(node.name, node.args, node.splat, env, node.children, node.has_content, "mixin"))
243
- []
244
- end
245
-
246
- # Runs a mixin.
247
- def visit_mixin(node)
248
- include_loop = true
249
- handle_include_loop!(node) if @stack.any? {|e| e[:name] == node.name}
250
- include_loop = false
251
-
252
- @stack.push(:filename => node.filename, :line => node.line, :name => node.name)
253
- raise Sass::SyntaxError.new("Undefined mixin '#{node.name}'.") unless mixin = @environment.mixin(node.name)
254
-
255
- if node.children.any? && !mixin.has_content
256
- raise Sass::SyntaxError.new(%Q{Mixin "#{node.name}" does not accept a content block.})
257
- end
258
-
259
- args = node.args.map {|a| a.perform(@environment)}
260
- keywords = Sass::Util.map_hash(node.keywords) {|k, v| [k, v.perform(@environment)]}
261
- splat = node.splat.perform(@environment) if node.splat
262
-
263
- self.class.perform_arguments(mixin, args, keywords, splat) do |env|
264
- env.caller = Sass::Environment.new(@environment)
265
- env.content = node.children if node.has_children
266
-
267
- trace_node = Sass::Tree::TraceNode.from_node(node.name, node)
268
- with_environment(env) {trace_node.children = mixin.tree.map {|c| visit(c)}.flatten}
269
- trace_node
270
- end
271
- rescue Sass::SyntaxError => e
272
- unless include_loop
273
- e.modify_backtrace(:mixin => node.name, :line => node.line)
274
- e.add_backtrace(:line => node.line)
275
- end
276
- raise e
277
- ensure
278
- @stack.pop unless include_loop
279
- end
280
-
281
- def visit_content(node)
282
- return [] unless content = @environment.content
283
- @stack.push(:filename => node.filename, :line => node.line, :name => '@content')
284
- trace_node = Sass::Tree::TraceNode.from_node('@content', node)
285
- with_environment(@environment.caller) {trace_node.children = content.map {|c| visit(c.dup)}.flatten}
286
- trace_node
287
- rescue Sass::SyntaxError => e
288
- e.modify_backtrace(:mixin => '@content', :line => node.line)
289
- e.add_backtrace(:line => node.line)
290
- raise e
291
- ensure
292
- @stack.pop if content
293
- end
294
-
295
- # Runs any SassScript that may be embedded in a property.
296
- def visit_prop(node)
297
- node.resolved_name = run_interp(node.name)
298
- val = node.value.perform(@environment)
299
- node.resolved_value = val.to_s
300
- yield
301
- end
302
-
303
- # Returns the value of the expression.
304
- def visit_return(node)
305
- throw :_sass_return, node.expr.perform(@environment)
306
- end
307
-
308
- # Runs SassScript interpolation in the selector,
309
- # and then parses the result into a {Sass::Selector::CommaSequence}.
310
- def visit_rule(node)
311
- rule = node.rule
312
- rule = rule.map {|e| e.is_a?(String) && e != ' ' ? e.strip : e} if node.style == :compressed
313
- parser = Sass::SCSS::StaticParser.new(run_interp(node.rule), node.filename, node.line)
314
- node.parsed_rules ||= parser.parse_selector
315
- if node.options[:trace_selectors]
316
- @stack.push(:filename => node.filename, :line => node.line)
317
- node.stack_trace = stack_trace
318
- @stack.pop
319
- end
320
- yield
321
- end
322
-
323
- # Loads the new variable value into the environment.
324
- def visit_variable(node)
325
- var = @environment.var(node.name)
326
- return [] if node.guarded && var && !var.null?
327
- val = node.expr.perform(@environment)
328
- @environment.set_var(node.name, val)
329
- []
330
- end
331
-
332
- # Prints the expression to STDERR with a stylesheet trace.
333
- def visit_warn(node)
334
- @stack.push(:filename => node.filename, :line => node.line)
335
- res = node.expr.perform(@environment)
336
- res = res.value if res.is_a?(Sass::Script::String)
337
- msg = "WARNING: #{res}\n "
338
- msg << stack_trace.join("\n ") << "\n"
339
- Sass::Util.sass_warn msg
340
- []
341
- ensure
342
- @stack.pop
343
- end
344
-
345
- # Runs the child nodes until the continuation expression becomes false.
346
- def visit_while(node)
347
- children = []
348
- with_environment Sass::Environment.new(@environment) do
349
- children += node.children.map {|c| visit(c)} while node.expr.perform(@environment).to_bool
350
- end
351
- children.flatten
352
- end
353
-
354
- def visit_directive(node)
355
- node.resolved_value = run_interp(node.value)
356
- yield
357
- end
358
-
359
- def visit_media(node)
360
- parser = Sass::SCSS::StaticParser.new(run_interp(node.query), node.filename, node.line)
361
- node.resolved_query ||= parser.parse_media_query_list
362
- yield
363
- end
364
-
365
- def visit_supports(node)
366
- node.condition = node.condition.deep_copy
367
- node.condition.perform(@environment)
368
- yield
369
- end
370
-
371
- def visit_cssimport(node)
372
- node.resolved_uri = run_interp([node.uri])
373
- if node.query
374
- parser = Sass::SCSS::StaticParser.new(run_interp(node.query), node.filename, node.line)
375
- node.resolved_query ||= parser.parse_media_query_list
376
- end
377
- yield
378
- end
379
-
380
- private
381
-
382
- def stack_trace
383
- trace = []
384
- stack = @stack.map {|e| e.dup}.reverse
385
- stack.each_cons(2) {|(e1, e2)| e1[:caller] = e2[:name]; [e1, e2]}
386
- stack.each_with_index do |entry, i|
387
- msg = "#{i == 0 ? "on" : "from"} line #{entry[:line]}"
388
- msg << " of #{entry[:filename] || "an unknown file"}"
389
- msg << ", in `#{entry[:caller]}'" if entry[:caller]
390
- trace << msg
391
- end
392
- trace
393
- end
394
-
395
- def run_interp_no_strip(text)
396
- text.map do |r|
397
- next r if r.is_a?(String)
398
- val = r.perform(@environment)
399
- # Interpolated strings should never render with quotes
400
- next val.value if val.is_a?(Sass::Script::String)
401
- val.to_s
402
- end.join
403
- end
404
-
405
- def run_interp(text)
406
- run_interp_no_strip(text).strip
407
- end
408
-
409
- def handle_include_loop!(node)
410
- msg = "An @include loop has been found:"
411
- content_count = 0
412
- mixins = @stack.reverse.map {|s| s[:name]}.compact.select do |s|
413
- if s == '@content'
414
- content_count += 1
415
- false
416
- elsif content_count > 0
417
- content_count -= 1
418
- false
419
- else
420
- true
421
- end
422
- end
423
-
424
- return unless mixins.include?(node.name)
425
- raise Sass::SyntaxError.new("#{msg} #{node.name} includes itself") if mixins.size == 1
426
-
427
- msg << "\n" << Sass::Util.enum_cons(mixins.reverse + [node.name], 2).map do |m1, m2|
428
- " #{m1} includes #{m2}"
429
- end.join("\n")
430
- raise Sass::SyntaxError.new(msg)
431
- end
432
-
433
- def handle_import_loop!(node)
434
- msg = "An @import loop has been found:"
435
- files = @stack.map {|s| s[:filename]}.compact
436
- if node.filename == node.imported_file.options[:filename]
437
- raise Sass::SyntaxError.new("#{msg} #{node.filename} imports itself")
438
- end
439
-
440
- files << node.filename << node.imported_file.options[:filename]
441
- msg << "\n" << Sass::Util.enum_cons(files, 2).map do |m1, m2|
442
- " #{m1} imports #{m2}"
443
- end.join("\n")
444
- raise Sass::SyntaxError.new(msg)
445
- end
446
- end
@@ -1,125 +0,0 @@
1
- # A visitor for setting options on the Sass tree
2
- class Sass::Tree::Visitors::SetOptions < Sass::Tree::Visitors::Base
3
- # @param root [Tree::Node] The root node of the tree to visit.
4
- # @param options [{Symbol => Object}] The options has to set.
5
- def self.visit(root, options); new(options).send(:visit, root); end
6
-
7
- protected
8
-
9
- def initialize(options)
10
- @options = options
11
- end
12
-
13
- def visit(node)
14
- node.instance_variable_set('@options', @options)
15
- super
16
- end
17
-
18
- def visit_debug(node)
19
- node.expr.options = @options
20
- yield
21
- end
22
-
23
- def visit_each(node)
24
- node.list.options = @options
25
- yield
26
- end
27
-
28
- def visit_extend(node)
29
- node.selector.each {|c| c.options = @options if c.is_a?(Sass::Script::Node)}
30
- yield
31
- end
32
-
33
- def visit_for(node)
34
- node.from.options = @options
35
- node.to.options = @options
36
- yield
37
- end
38
-
39
- def visit_function(node)
40
- node.args.each do |k, v|
41
- k.options = @options
42
- v.options = @options if v
43
- end
44
- yield
45
- end
46
-
47
- def visit_if(node)
48
- node.expr.options = @options if node.expr
49
- visit(node.else) if node.else
50
- yield
51
- end
52
-
53
- def visit_import(node)
54
- # We have no good way of propagating the new options through an Engine
55
- # instance, so we just null it out. This also lets us avoid caching an
56
- # imported Engine along with the importing source tree.
57
- node.imported_file = nil
58
- yield
59
- end
60
-
61
- def visit_mixindef(node)
62
- node.args.each do |k, v|
63
- k.options = @options
64
- v.options = @options if v
65
- end
66
- yield
67
- end
68
-
69
- def visit_mixin(node)
70
- node.args.each {|a| a.options = @options}
71
- node.keywords.each {|k, v| v.options = @options}
72
- yield
73
- end
74
-
75
- def visit_prop(node)
76
- node.name.each {|c| c.options = @options if c.is_a?(Sass::Script::Node)}
77
- node.value.options = @options
78
- yield
79
- end
80
-
81
- def visit_return(node)
82
- node.expr.options = @options
83
- yield
84
- end
85
-
86
- def visit_rule(node)
87
- node.rule.each {|c| c.options = @options if c.is_a?(Sass::Script::Node)}
88
- yield
89
- end
90
-
91
- def visit_variable(node)
92
- node.expr.options = @options
93
- yield
94
- end
95
-
96
- def visit_warn(node)
97
- node.expr.options = @options
98
- yield
99
- end
100
-
101
- def visit_while(node)
102
- node.expr.options = @options
103
- yield
104
- end
105
-
106
- def visit_directive(node)
107
- node.value.each {|c| c.options = @options if c.is_a?(Sass::Script::Node)}
108
- yield
109
- end
110
-
111
- def visit_media(node)
112
- node.query.each {|c| c.options = @options if c.is_a?(Sass::Script::Node)}
113
- yield
114
- end
115
-
116
- def visit_cssimport(node)
117
- node.query.each {|c| c.options = @options if c.is_a?(Sass::Script::Node)} if node.query
118
- yield
119
- end
120
-
121
- def visit_supports(node)
122
- node.condition.options = @options
123
- yield
124
- end
125
- end