haml 3.1.0.alpha.14 → 3.1.0.alpha.17

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 (222) hide show
  1. data/EDGE_GEM_VERSION +1 -1
  2. data/VERSION +1 -1
  3. data/lib/haml.rb +3 -2
  4. data/lib/haml/exec.rb +0 -226
  5. data/lib/sass.rb +8 -0
  6. data/lib/sass/plugin.rb +8 -0
  7. data/lib/sass/rails2_shim.rb +9 -0
  8. data/lib/sass/rails3_shim.rb +16 -0
  9. data/vendor/sass/CONTRIBUTING +3 -0
  10. data/vendor/sass/MIT-LICENSE +20 -0
  11. data/vendor/sass/README.md +201 -0
  12. data/vendor/sass/Rakefile +363 -0
  13. data/vendor/sass/TODO +39 -0
  14. data/vendor/sass/VERSION +1 -0
  15. data/vendor/sass/VERSION_NAME +1 -0
  16. data/vendor/sass/bin/css2sass +13 -0
  17. data/vendor/sass/bin/sass +8 -0
  18. data/vendor/sass/bin/sass-convert +7 -0
  19. data/vendor/sass/doc-src/FAQ.md +35 -0
  20. data/vendor/sass/doc-src/INDENTED_SYNTAX.md +210 -0
  21. data/vendor/sass/doc-src/SASS_CHANGELOG.md +1878 -0
  22. data/vendor/sass/doc-src/SASS_REFERENCE.md +1713 -0
  23. data/vendor/sass/doc-src/SCSS_FOR_SASS_USERS.md +155 -0
  24. data/vendor/sass/ext/extconf.rb +10 -0
  25. data/vendor/sass/extra/update_watch.rb +13 -0
  26. data/vendor/sass/init.rb +18 -0
  27. data/vendor/sass/lib/sass.rb +71 -0
  28. data/vendor/sass/lib/sass/cache_store.rb +208 -0
  29. data/vendor/sass/lib/sass/callbacks.rb +66 -0
  30. data/vendor/sass/lib/sass/css.rb +294 -0
  31. data/vendor/sass/lib/sass/engine.rb +792 -0
  32. data/vendor/sass/lib/sass/environment.rb +143 -0
  33. data/vendor/sass/lib/sass/error.rb +201 -0
  34. data/vendor/sass/lib/sass/exec.rb +619 -0
  35. data/vendor/sass/lib/sass/importers.rb +22 -0
  36. data/vendor/sass/lib/sass/importers/base.rb +138 -0
  37. data/vendor/sass/lib/sass/importers/filesystem.rb +121 -0
  38. data/vendor/sass/lib/sass/less.rb +363 -0
  39. data/vendor/sass/lib/sass/plugin.rb +126 -0
  40. data/vendor/sass/lib/sass/plugin/compiler.rb +346 -0
  41. data/vendor/sass/lib/sass/plugin/configuration.rb +123 -0
  42. data/vendor/sass/lib/sass/plugin/generic.rb +15 -0
  43. data/vendor/sass/lib/sass/plugin/merb.rb +48 -0
  44. data/vendor/sass/lib/sass/plugin/rack.rb +47 -0
  45. data/vendor/sass/lib/sass/plugin/rails.rb +41 -0
  46. data/vendor/sass/lib/sass/plugin/staleness_checker.rb +145 -0
  47. data/vendor/sass/lib/sass/railtie.rb +8 -0
  48. data/vendor/sass/lib/sass/repl.rb +58 -0
  49. data/vendor/sass/lib/sass/root.rb +7 -0
  50. data/vendor/sass/lib/sass/script.rb +63 -0
  51. data/vendor/sass/lib/sass/script/bool.rb +18 -0
  52. data/vendor/sass/lib/sass/script/color.rb +491 -0
  53. data/vendor/sass/lib/sass/script/css_lexer.rb +29 -0
  54. data/vendor/sass/lib/sass/script/css_parser.rb +31 -0
  55. data/vendor/sass/lib/sass/script/funcall.rb +76 -0
  56. data/vendor/sass/lib/sass/script/functions.rb +852 -0
  57. data/vendor/sass/lib/sass/script/interpolation.rb +70 -0
  58. data/vendor/sass/lib/sass/script/lexer.rb +337 -0
  59. data/vendor/sass/lib/sass/script/literal.rb +236 -0
  60. data/vendor/sass/lib/sass/script/node.rb +112 -0
  61. data/vendor/sass/lib/sass/script/number.rb +423 -0
  62. data/vendor/sass/lib/sass/script/operation.rb +90 -0
  63. data/vendor/sass/lib/sass/script/parser.rb +392 -0
  64. data/vendor/sass/lib/sass/script/string.rb +67 -0
  65. data/vendor/sass/lib/sass/script/string_interpolation.rb +93 -0
  66. data/vendor/sass/lib/sass/script/unary_operation.rb +57 -0
  67. data/vendor/sass/lib/sass/script/variable.rb +48 -0
  68. data/vendor/sass/lib/sass/scss.rb +17 -0
  69. data/vendor/sass/lib/sass/scss/css_parser.rb +51 -0
  70. data/vendor/sass/lib/sass/scss/parser.rb +838 -0
  71. data/vendor/sass/lib/sass/scss/rx.rb +126 -0
  72. data/vendor/sass/lib/sass/scss/sass_parser.rb +11 -0
  73. data/vendor/sass/lib/sass/scss/script_lexer.rb +15 -0
  74. data/vendor/sass/lib/sass/scss/script_parser.rb +25 -0
  75. data/vendor/sass/lib/sass/scss/static_parser.rb +40 -0
  76. data/vendor/sass/lib/sass/selector.rb +361 -0
  77. data/vendor/sass/lib/sass/selector/abstract_sequence.rb +62 -0
  78. data/vendor/sass/lib/sass/selector/comma_sequence.rb +82 -0
  79. data/vendor/sass/lib/sass/selector/sequence.rb +236 -0
  80. data/vendor/sass/lib/sass/selector/simple.rb +113 -0
  81. data/vendor/sass/lib/sass/selector/simple_sequence.rb +135 -0
  82. data/vendor/sass/lib/sass/shared.rb +78 -0
  83. data/vendor/sass/lib/sass/tree/comment_node.rb +128 -0
  84. data/vendor/sass/lib/sass/tree/debug_node.rb +36 -0
  85. data/vendor/sass/lib/sass/tree/directive_node.rb +75 -0
  86. data/vendor/sass/lib/sass/tree/extend_node.rb +65 -0
  87. data/vendor/sass/lib/sass/tree/for_node.rb +67 -0
  88. data/vendor/sass/lib/sass/tree/if_node.rb +81 -0
  89. data/vendor/sass/lib/sass/tree/import_node.rb +124 -0
  90. data/vendor/sass/lib/sass/tree/mixin_def_node.rb +60 -0
  91. data/vendor/sass/lib/sass/tree/mixin_node.rb +123 -0
  92. data/vendor/sass/lib/sass/tree/node.rb +490 -0
  93. data/vendor/sass/lib/sass/tree/prop_node.rb +220 -0
  94. data/vendor/sass/lib/sass/tree/root_node.rb +125 -0
  95. data/vendor/sass/lib/sass/tree/rule_node.rb +273 -0
  96. data/vendor/sass/lib/sass/tree/variable_node.rb +39 -0
  97. data/vendor/sass/lib/sass/tree/warn_node.rb +42 -0
  98. data/vendor/sass/lib/sass/tree/while_node.rb +48 -0
  99. data/vendor/sass/lib/sass/util.rb +700 -0
  100. data/vendor/sass/lib/sass/util/subset_map.rb +101 -0
  101. data/vendor/sass/lib/sass/version.rb +109 -0
  102. data/vendor/sass/rails/init.rb +1 -0
  103. data/vendor/sass/sass.gemspec +32 -0
  104. data/vendor/sass/test/sass/cache_test.rb +74 -0
  105. data/vendor/sass/test/sass/callbacks_test.rb +61 -0
  106. data/vendor/sass/test/sass/conversion_test.rb +1210 -0
  107. data/vendor/sass/test/sass/css2sass_test.rb +364 -0
  108. data/vendor/sass/test/sass/data/hsl-rgb.txt +319 -0
  109. data/vendor/sass/test/sass/engine_test.rb +2305 -0
  110. data/vendor/sass/test/sass/extend_test.rb +1348 -0
  111. data/vendor/sass/test/sass/functions_test.rb +565 -0
  112. data/vendor/sass/test/sass/importer_test.rb +104 -0
  113. data/vendor/sass/test/sass/less_conversion_test.rb +632 -0
  114. data/vendor/sass/test/sass/mock_importer.rb +49 -0
  115. data/vendor/sass/test/sass/more_results/more1.css +9 -0
  116. data/vendor/sass/test/sass/more_results/more1_with_line_comments.css +26 -0
  117. data/vendor/sass/test/sass/more_results/more_import.css +29 -0
  118. data/vendor/sass/test/sass/more_templates/_more_partial.sass +2 -0
  119. data/vendor/sass/test/sass/more_templates/more1.sass +23 -0
  120. data/vendor/sass/test/sass/more_templates/more_import.sass +11 -0
  121. data/vendor/sass/test/sass/plugin_test.rb +430 -0
  122. data/vendor/sass/test/sass/results/alt.css +4 -0
  123. data/vendor/sass/test/sass/results/basic.css +9 -0
  124. data/vendor/sass/test/sass/results/compact.css +5 -0
  125. data/vendor/sass/test/sass/results/complex.css +86 -0
  126. data/vendor/sass/test/sass/results/compressed.css +1 -0
  127. data/vendor/sass/test/sass/results/expanded.css +19 -0
  128. data/vendor/sass/test/sass/results/import.css +31 -0
  129. data/vendor/sass/test/sass/results/line_numbers.css +49 -0
  130. data/vendor/sass/test/sass/results/mixins.css +95 -0
  131. data/vendor/sass/test/sass/results/multiline.css +24 -0
  132. data/vendor/sass/test/sass/results/nested.css +22 -0
  133. data/vendor/sass/test/sass/results/options.css +1 -0
  134. data/vendor/sass/test/sass/results/parent_ref.css +13 -0
  135. data/vendor/sass/test/sass/results/script.css +16 -0
  136. data/vendor/sass/test/sass/results/scss_import.css +31 -0
  137. data/vendor/sass/test/sass/results/scss_importee.css +2 -0
  138. data/vendor/sass/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  139. data/vendor/sass/test/sass/results/subdir/subdir.css +3 -0
  140. data/vendor/sass/test/sass/results/units.css +11 -0
  141. data/vendor/sass/test/sass/results/warn.css +0 -0
  142. data/vendor/sass/test/sass/results/warn_imported.css +0 -0
  143. data/vendor/sass/test/sass/script_conversion_test.rb +254 -0
  144. data/vendor/sass/test/sass/script_test.rb +470 -0
  145. data/vendor/sass/test/sass/scss/css_test.rb +897 -0
  146. data/vendor/sass/test/sass/scss/rx_test.rb +156 -0
  147. data/vendor/sass/test/sass/scss/scss_test.rb +1088 -0
  148. data/vendor/sass/test/sass/scss/test_helper.rb +37 -0
  149. data/vendor/sass/test/sass/templates/_partial.sass +2 -0
  150. data/vendor/sass/test/sass/templates/alt.sass +16 -0
  151. data/vendor/sass/test/sass/templates/basic.sass +23 -0
  152. data/vendor/sass/test/sass/templates/bork1.sass +2 -0
  153. data/vendor/sass/test/sass/templates/bork2.sass +2 -0
  154. data/vendor/sass/test/sass/templates/bork3.sass +2 -0
  155. data/vendor/sass/test/sass/templates/bork4.sass +2 -0
  156. data/vendor/sass/test/sass/templates/compact.sass +17 -0
  157. data/vendor/sass/test/sass/templates/complex.sass +305 -0
  158. data/vendor/sass/test/sass/templates/compressed.sass +15 -0
  159. data/vendor/sass/test/sass/templates/expanded.sass +17 -0
  160. data/vendor/sass/test/sass/templates/import.sass +12 -0
  161. data/vendor/sass/test/sass/templates/importee.less +2 -0
  162. data/vendor/sass/test/sass/templates/importee.sass +19 -0
  163. data/vendor/sass/test/sass/templates/line_numbers.sass +13 -0
  164. data/vendor/sass/test/sass/templates/mixin_bork.sass +5 -0
  165. data/vendor/sass/test/sass/templates/mixins.sass +76 -0
  166. data/vendor/sass/test/sass/templates/multiline.sass +20 -0
  167. data/vendor/sass/test/sass/templates/nested.sass +25 -0
  168. data/vendor/sass/test/sass/templates/nested_bork1.sass +2 -0
  169. data/vendor/sass/test/sass/templates/nested_bork2.sass +2 -0
  170. data/vendor/sass/test/sass/templates/nested_bork3.sass +2 -0
  171. data/vendor/sass/test/sass/templates/nested_bork4.sass +2 -0
  172. data/vendor/sass/test/sass/templates/nested_mixin_bork.sass +6 -0
  173. data/vendor/sass/test/sass/templates/options.sass +2 -0
  174. data/vendor/sass/test/sass/templates/parent_ref.sass +25 -0
  175. data/vendor/sass/test/sass/templates/script.sass +101 -0
  176. data/vendor/sass/test/sass/templates/scss_import.scss +11 -0
  177. data/vendor/sass/test/sass/templates/scss_importee.scss +1 -0
  178. data/vendor/sass/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  179. data/vendor/sass/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  180. data/vendor/sass/test/sass/templates/subdir/subdir.sass +6 -0
  181. data/vendor/sass/test/sass/templates/units.sass +11 -0
  182. data/vendor/sass/test/sass/templates/warn.sass +3 -0
  183. data/vendor/sass/test/sass/templates/warn_imported.sass +4 -0
  184. data/vendor/sass/test/sass/test_helper.rb +8 -0
  185. data/vendor/sass/test/sass/util/subset_map_test.rb +91 -0
  186. data/vendor/sass/test/sass/util_test.rb +275 -0
  187. data/vendor/sass/test/test_helper.rb +64 -0
  188. data/vendor/sass/vendor/fssm/LICENSE +20 -0
  189. data/vendor/sass/vendor/fssm/README.markdown +55 -0
  190. data/vendor/sass/vendor/fssm/Rakefile +59 -0
  191. data/vendor/sass/vendor/fssm/VERSION.yml +5 -0
  192. data/vendor/sass/vendor/fssm/example.rb +9 -0
  193. data/vendor/sass/vendor/fssm/fssm.gemspec +77 -0
  194. data/vendor/sass/vendor/fssm/lib/fssm.rb +33 -0
  195. data/vendor/sass/vendor/fssm/lib/fssm/backends/fsevents.rb +36 -0
  196. data/vendor/sass/vendor/fssm/lib/fssm/backends/inotify.rb +26 -0
  197. data/vendor/sass/vendor/fssm/lib/fssm/backends/polling.rb +25 -0
  198. data/vendor/sass/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +131 -0
  199. data/vendor/sass/vendor/fssm/lib/fssm/monitor.rb +26 -0
  200. data/vendor/sass/vendor/fssm/lib/fssm/path.rb +91 -0
  201. data/vendor/sass/vendor/fssm/lib/fssm/pathname.rb +502 -0
  202. data/vendor/sass/vendor/fssm/lib/fssm/state/directory.rb +57 -0
  203. data/vendor/sass/vendor/fssm/lib/fssm/state/file.rb +24 -0
  204. data/vendor/sass/vendor/fssm/lib/fssm/support.rb +63 -0
  205. data/vendor/sass/vendor/fssm/lib/fssm/tree.rb +176 -0
  206. data/vendor/sass/vendor/fssm/profile/prof-cache.rb +40 -0
  207. data/vendor/sass/vendor/fssm/profile/prof-fssm-pathname.html +1231 -0
  208. data/vendor/sass/vendor/fssm/profile/prof-pathname.rb +68 -0
  209. data/vendor/sass/vendor/fssm/profile/prof-plain-pathname.html +988 -0
  210. data/vendor/sass/vendor/fssm/profile/prof.html +2379 -0
  211. data/vendor/sass/vendor/fssm/spec/path_spec.rb +75 -0
  212. data/vendor/sass/vendor/fssm/spec/root/duck/quack.txt +0 -0
  213. data/vendor/sass/vendor/fssm/spec/root/file.css +0 -0
  214. data/vendor/sass/vendor/fssm/spec/root/file.rb +0 -0
  215. data/vendor/sass/vendor/fssm/spec/root/file.yml +0 -0
  216. data/vendor/sass/vendor/fssm/spec/root/moo/cow.txt +0 -0
  217. data/vendor/sass/vendor/fssm/spec/spec_helper.rb +14 -0
  218. data/vendor/sass/yard/callbacks.rb +29 -0
  219. data/vendor/sass/yard/default/fulldoc/html/css/common.sass +26 -0
  220. data/vendor/sass/yard/default/layout/html/footer.erb +12 -0
  221. data/vendor/sass/yard/inherited_hash.rb +41 -0
  222. metadata +219 -2
@@ -0,0 +1,126 @@
1
+ require 'fileutils'
2
+
3
+ require 'sass'
4
+ require 'sass/plugin/compiler'
5
+
6
+ module Sass
7
+ # This module provides a single interface to the compilation of Sass/SCSS files
8
+ # for an application. It provides global options and checks whether CSS files
9
+ # need to be updated.
10
+ #
11
+ # This module is used as the primary interface with Sass
12
+ # when it's used as a plugin for various frameworks.
13
+ # All Rack-enabled frameworks are supported out of the box.
14
+ # The plugin is {file:SASS_REFERENCE.md#rails_merb_plugin automatically activated for Rails and Merb}.
15
+ # Other frameworks must enable it explicitly; see {Sass::Plugin::Rack}.
16
+ #
17
+ # This module has a large set of callbacks available
18
+ # to allow users to run code (such as logging) when certain things happen.
19
+ # All callback methods are of the form `on_#{name}`,
20
+ # and they all take a block that's called when the given action occurs.
21
+ #
22
+ # Note that this class proxies almost all methods to its {Sass::Plugin::Compiler} instance.
23
+ # See \{#compiler}.
24
+ #
25
+ # @example Using a callback
26
+ # Sass::Plugin.on_updating_stylesheet do |template, css|
27
+ # puts "Compiling #{template} to #{css}"
28
+ # end
29
+ # Sass::Plugin.update_stylesheets
30
+ # #=> Compiling app/sass/screen.scss to public/stylesheets/screen.css
31
+ # #=> Compiling app/sass/print.scss to public/stylesheets/print.css
32
+ # #=> Compiling app/sass/ie.scss to public/stylesheets/ie.css
33
+ # @see Sass::Plugin::Compiler
34
+ module Plugin
35
+ include Sass::Util
36
+ extend self
37
+
38
+ @checked_for_updates = false
39
+
40
+ # Whether or not Sass has **ever** checked if the stylesheets need to be updated
41
+ # (in this Ruby instance).
42
+ #
43
+ # @return [Boolean]
44
+ attr_reader :checked_for_updates
45
+
46
+ # Same as \{#update\_stylesheets}, but respects \{#checked\_for\_updates}
47
+ # and the {file:SASS_REFERENCE.md#always_update-option `:always_update`}
48
+ # and {file:SASS_REFERENCE.md#always_check-option `:always_check`} options.
49
+ #
50
+ # @see #update_stylesheets
51
+ def check_for_updates
52
+ return unless !Sass::Plugin.checked_for_updates ||
53
+ Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
54
+ update_stylesheets
55
+ end
56
+
57
+ # Returns the singleton compiler instance.
58
+ # This compiler has been pre-configured according
59
+ # to the plugin configuration.
60
+ #
61
+ # @return [Sass::Plugin::Compiler]
62
+ def compiler
63
+ @compiler ||= Compiler.new
64
+ end
65
+
66
+ # Updates out-of-date stylesheets.
67
+ #
68
+ # Checks each Sass/SCSS file in {file:SASS_REFERENCE.md#template_location-option `:template_location`}
69
+ # to see if it's been modified more recently than the corresponding CSS file
70
+ # in {file:SASS_REFERENCE.md#css_location-option `:css_location`}.
71
+ # If it has, it updates the CSS file.
72
+ #
73
+ # @param individual_files [Array<(String, String)>]
74
+ # A list of files to check for updates
75
+ # **in addition to those specified by the
76
+ # {file:SASS_REFERENCE.md#template_location-option `:template_location` option}.**
77
+ # The first string in each pair is the location of the Sass/SCSS file,
78
+ # the second is the location of the CSS file that it should be compiled to.
79
+ def update_stylesheets(individual_files = [])
80
+ return if options[:never_update]
81
+ compiler.update_stylesheets(individual_files)
82
+ end
83
+
84
+ # Updates all stylesheets, even those that aren't out-of-date.
85
+ # Ignores the cache.
86
+ #
87
+ # @param individual_files [Array<(String, String)>]
88
+ # A list of files to check for updates
89
+ # **in addition to those specified by the
90
+ # {file:SASS_REFERENCE.md#template_location-option `:template_location` option}.**
91
+ # The first string in each pair is the location of the Sass/SCSS file,
92
+ # the second is the location of the CSS file that it should be compiled to.
93
+ # @see #update_stylesheets
94
+ def force_update_stylesheets(individual_files = [])
95
+ old_options = options
96
+ self.options = options.dup
97
+ options[:never_update] = false
98
+ options[:always_update] = true
99
+ options[:cache] = false
100
+ update_stylesheets(individual_files)
101
+ ensure
102
+ self.options = old_options
103
+ end
104
+
105
+ # All other method invocations are proxied to the \{#compiler}.
106
+ #
107
+ # @see #compiler
108
+ # @see Sass::Plugin::Compiler
109
+ def method_missing(method, *args, &block)
110
+ if compiler.respond_to?(method)
111
+ compiler.send(method, *args, &block)
112
+ else
113
+ super
114
+ end
115
+ end
116
+
117
+ end
118
+ end
119
+
120
+ if defined?(ActionController)
121
+ require 'sass/plugin/rails'
122
+ elsif defined?(Merb::Plugins)
123
+ require 'sass/plugin/merb'
124
+ else
125
+ require 'sass/plugin/generic'
126
+ end
@@ -0,0 +1,346 @@
1
+ require 'fileutils'
2
+
3
+ require 'sass'
4
+ # XXX CE: is this still necessary now that we have the compiler class?
5
+ require 'sass/callbacks'
6
+ require 'sass/plugin/configuration'
7
+ require 'sass/plugin/staleness_checker'
8
+
9
+ module Sass::Plugin
10
+
11
+ # The Compiler class handles compilation of multiple files and/or directories,
12
+ # including checking which CSS files are out-of-date and need to be updated
13
+ # and calling Sass to perform the compilation on those files.
14
+ #
15
+ # {Sass::Plugin} uses this class to update stylesheets for a single application.
16
+ # Unlike {Sass::Plugin}, though, the Compiler class has no global state,
17
+ # and so multiple instances may be created and used independently.
18
+ #
19
+ # If you need to compile a Sass string into CSS,
20
+ # please see the {Sass::Engine} class.
21
+ #
22
+ # Unlike {Sass::Plugin}, this class doesn't keep track of
23
+ # whether or how many times a stylesheet should be updated.
24
+ # Therefore, the following `Sass::Plugin` options are ignored by the Compiler:
25
+ #
26
+ # * `:never_update`
27
+ # * `:always_check`
28
+ class Compiler
29
+ include Sass::Util
30
+ include Configuration
31
+ extend Sass::Callbacks
32
+
33
+ # Creates a new compiler.
34
+ #
35
+ # @param options [{Symbol => Object}]
36
+ # See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
37
+ def initialize(options = {})
38
+ self.options.merge!(options)
39
+ end
40
+
41
+ # Register a callback to be run before stylesheets are mass-updated.
42
+ # This is run whenever \{#update\_stylesheets} is called,
43
+ # unless the \{file:SASS_REFERENCE.md#never_update-option `:never_update` option}
44
+ # is enabled.
45
+ #
46
+ # @yield [individual_files]
47
+ # @yieldparam individual_files [<(String, String)>]
48
+ # Individual files to be updated, in addition to the directories
49
+ # specified in the options.
50
+ # The first element of each pair is the source file,
51
+ # the second is the target CSS file.
52
+ define_callback :updating_stylesheets
53
+
54
+ # Register a callback to be run before a single stylesheet is updated.
55
+ # The callback is only run if the stylesheet is guaranteed to be updated;
56
+ # if the CSS file is fresh, this won't be run.
57
+ #
58
+ # Even if the \{file:SASS_REFERENCE.md#full_exception-option `:full_exception` option}
59
+ # is enabled, this callback won't be run
60
+ # when an exception CSS file is being written.
61
+ # To run an action for those files, use \{#on\_compilation\_error}.
62
+ #
63
+ # @yield [template, css]
64
+ # @yieldparam template [String]
65
+ # The location of the Sass/SCSS file being updated.
66
+ # @yieldparam css [String]
67
+ # The location of the CSS file being generated.
68
+ define_callback :updating_stylesheet
69
+
70
+ # Register a callback to be run when Sass decides not to update a stylesheet.
71
+ # In particular, the callback is run when Sass finds that
72
+ # the template file and none of its dependencies
73
+ # have been modified since the last compilation.
74
+ #
75
+ # Note that this is **not** run when the
76
+ # \{file:SASS_REFERENCE.md#never-update_option `:never_update` option} is set,
77
+ # nor when Sass decides not to compile a partial.
78
+ #
79
+ # @yield [template, css]
80
+ # @yieldparam template [String]
81
+ # The location of the Sass/SCSS file not being updated.
82
+ # @yieldparam css [String]
83
+ # The location of the CSS file not being generated.
84
+ define_callback :not_updating_stylesheet
85
+
86
+ # Register a callback to be run when there's an error
87
+ # compiling a Sass file.
88
+ # This could include not only errors in the Sass document,
89
+ # but also errors accessing the file at all.
90
+ #
91
+ # @yield [error, template, css]
92
+ # @yieldparam error [Exception] The exception that was raised.
93
+ # @yieldparam template [String]
94
+ # The location of the Sass/SCSS file being updated.
95
+ # @yieldparam css [String]
96
+ # The location of the CSS file being generated.
97
+ define_callback :compilation_error
98
+
99
+ # Register a callback to be run when Sass creates a directory
100
+ # into which to put CSS files.
101
+ #
102
+ # Note that even if multiple levels of directories need to be created,
103
+ # the callback may only be run once.
104
+ # For example, if "foo/" exists and "foo/bar/baz/" needs to be created,
105
+ # this may only be run for "foo/bar/baz/".
106
+ # This is not a guarantee, however;
107
+ # it may also be run for "foo/bar/".
108
+ #
109
+ # @yield [dirname]
110
+ # @yieldparam dirname [String]
111
+ # The location of the directory that was created.
112
+ define_callback :creating_directory
113
+
114
+ # Register a callback to be run when Sass detects
115
+ # that a template has been modified.
116
+ # This is only run when using \{#watch}.
117
+ #
118
+ # @yield [template]
119
+ # @yieldparam template [String]
120
+ # The location of the template that was modified.
121
+ define_callback :template_modified
122
+
123
+ # Register a callback to be run when Sass detects
124
+ # that a new template has been created.
125
+ # This is only run when using \{#watch}.
126
+ #
127
+ # @yield [template]
128
+ # @yieldparam template [String]
129
+ # The location of the template that was created.
130
+ define_callback :template_created
131
+
132
+ # Register a callback to be run when Sass detects
133
+ # that a template has been deleted.
134
+ # This is only run when using \{#watch}.
135
+ #
136
+ # @yield [template]
137
+ # @yieldparam template [String]
138
+ # The location of the template that was deleted.
139
+ define_callback :template_deleted
140
+
141
+ # Register a callback to be run when Sass deletes a CSS file.
142
+ # This happens when the corresponding Sass/SCSS file has been deleted.
143
+ #
144
+ # @yield [filename]
145
+ # @yieldparam filename [String]
146
+ # The location of the CSS file that was deleted.
147
+ define_callback :deleting_css
148
+
149
+ # Updates out-of-date stylesheets.
150
+ #
151
+ # Checks each Sass/SCSS file in {file:SASS_REFERENCE.md#template_location-option `:template_location`}
152
+ # to see if it's been modified more recently than the corresponding CSS file
153
+ # in {file:SASS_REFERENCE.md#css_location-option `:css_location`}.
154
+ # If it has, it updates the CSS file.
155
+ #
156
+ # @param individual_files [Array<(String, String)>]
157
+ # A list of files to check for updates
158
+ # **in addition to those specified by the
159
+ # {file:SASS_REFERENCE.md#template_location-option `:template_location` option}.**
160
+ # The first string in each pair is the location of the Sass/SCSS file,
161
+ # the second is the location of the CSS file that it should be compiled to.
162
+ def update_stylesheets(individual_files = [])
163
+ run_updating_stylesheets individual_files
164
+
165
+ individual_files.each {|t, c| update_stylesheet(t, c)}
166
+
167
+ @checked_for_updates = true
168
+ staleness_checker = StalenessChecker.new(engine_options)
169
+
170
+ template_location_array.each do |template_location, css_location|
171
+
172
+ Dir.glob(File.join(template_location, "**", "[^_]*.s[ca]ss")).sort.each do |file|
173
+ # Get the relative path to the file
174
+ name = file.sub(template_location.sub(/\/*$/, '/'), "")
175
+ css = css_filename(name, css_location)
176
+
177
+ if options[:always_update] || staleness_checker.stylesheet_needs_update?(css, file)
178
+ update_stylesheet file, css
179
+ else
180
+ run_not_updating_stylesheet file, css
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ # Watches the template directory (or directories)
187
+ # and updates the CSS files whenever the related Sass/SCSS files change.
188
+ # `watch` never returns.
189
+ #
190
+ # Whenever a change is detected to a Sass/SCSS file in
191
+ # {file:SASS_REFERENCE.md#template_location-option `:template_location`},
192
+ # the corresponding CSS file in {file:SASS_REFERENCE.md#css_location-option `:css_location`}
193
+ # will be recompiled.
194
+ # The CSS files of any Sass/SCSS files that import the changed file will also be recompiled.
195
+ #
196
+ # Before the watching starts in earnest, `watch` calls \{#update\_stylesheets}.
197
+ #
198
+ # Note that `watch` uses the [FSSM](http://github.com/ttilley/fssm) library
199
+ # to monitor the filesystem for changes.
200
+ # FSSM isn't loaded until `watch` is run.
201
+ # The version of FSSM distributed with Sass is loaded by default,
202
+ # but if another version has already been loaded that will be used instead.
203
+ #
204
+ # @param individual_files [Array<(String, String)>]
205
+ # A list of files to watch for updates
206
+ # **in addition to those specified by the
207
+ # {file:SASS_REFERENCE.md#template_location-option `:template_location` option}.**
208
+ # The first string in each pair is the location of the Sass/SCSS file,
209
+ # the second is the location of the CSS file that it should be compiled to.
210
+ def watch(individual_files = [])
211
+ update_stylesheets(individual_files)
212
+
213
+ begin
214
+ require 'fssm'
215
+ rescue LoadError => e
216
+ e.message << "\n" <<
217
+ if File.exists?(scope(".git"))
218
+ 'Run "git submodule update --init" to get the recommended version.'
219
+ else
220
+ 'Run "gem install fssm" to get it.'
221
+ end
222
+ raise e
223
+ end
224
+
225
+ unless individual_files.empty? && FSSM::Backends::Default.name == "FSSM::Backends::FSEvents"
226
+ # As of FSSM 0.1.4, it doesn't support FSevents on individual files,
227
+ # but it also isn't smart enough to switch to polling itself.
228
+ require 'fssm/backends/polling'
229
+ Sass::Util.silence_warnings do
230
+ FSSM::Backends.const_set(:Default, FSSM::Backends::Polling)
231
+ end
232
+ end
233
+
234
+ # TODO: Keep better track of what depends on what
235
+ # so we don't have to run a global update every time anything changes.
236
+ FSSM.monitor do |mon|
237
+ template_location_array.each do |template_location, css_location|
238
+ mon.path template_location do |path|
239
+ path.glob '**/*.s[ac]ss'
240
+
241
+ path.update do |base, relative|
242
+ run_template_modified File.join(base, relative)
243
+ update_stylesheets(individual_files)
244
+ end
245
+
246
+ path.create do |base, relative|
247
+ run_template_created File.join(base, relative)
248
+ update_stylesheets(individual_files)
249
+ end
250
+
251
+ path.delete do |base, relative|
252
+ run_template_deleted File.join(base, relative)
253
+ css = File.join(css_location, relative.gsub(/\.s[ac]ss$/, '.css'))
254
+ try_delete_css css
255
+ update_stylesheets(individual_files)
256
+ end
257
+ end
258
+ end
259
+
260
+ individual_files.each do |template, css|
261
+ mon.file template do |path|
262
+ path.update do
263
+ run_template_modified template
264
+ update_stylesheets(individual_files)
265
+ end
266
+
267
+ path.create do
268
+ run_template_created template
269
+ update_stylesheets(individual_files)
270
+ end
271
+
272
+ path.delete do
273
+ run_template_deleted template
274
+ try_delete_css css
275
+ update_stylesheets(individual_files)
276
+ end
277
+ end
278
+ end
279
+ end
280
+ end
281
+
282
+ # Non-destructively modifies \{#options} so that default values are properly set,
283
+ # and returns the result.
284
+ #
285
+ # @param additional_options [{Symbol => Object}] An options hash with which to merge \{#options}
286
+ # @return [{Symbol => Object}] The modified options hash
287
+ def engine_options(additional_options = {})
288
+ opts = options.merge(additional_options)
289
+ opts[:load_paths] = load_paths(opts)
290
+ opts
291
+ end
292
+
293
+ # Compass expects this to exist
294
+ def stylesheet_needs_update?(css_file, template_file)
295
+ StalenessChecker.stylesheet_needs_update?(css_file, template_file)
296
+ end
297
+
298
+ private
299
+
300
+ def update_stylesheet(filename, css)
301
+ dir = File.dirname(css)
302
+ unless File.exists?(dir)
303
+ run_creating_directory dir
304
+ FileUtils.mkdir_p dir
305
+ end
306
+
307
+ begin
308
+ File.read(filename) unless File.readable?(filename) # triggers an error for handling
309
+ engine_opts = engine_options(:css_filename => css, :filename => filename)
310
+ result = Sass::Engine.for_file(filename, engine_opts).render
311
+ rescue Exception => e
312
+ run_compilation_error e, filename, css
313
+ result = Sass::SyntaxError.exception_to_css(e, options)
314
+ else
315
+ run_updating_stylesheet filename, css
316
+ end
317
+
318
+ # Finally, write the file
319
+ flag = 'w'
320
+ flag = 'wb' if Sass::Util.windows? && options[:unix_newlines]
321
+ File.open(css, flag) {|file| file.print(result)}
322
+ end
323
+
324
+ def try_delete_css(css)
325
+ return unless File.exists?(css)
326
+ run_deleting_css css
327
+ File.delete css
328
+ end
329
+
330
+ def load_paths(opts = options)
331
+ (opts[:load_paths] || []) + template_locations
332
+ end
333
+
334
+ def template_locations
335
+ template_location_array.to_a.map {|l| l.first}
336
+ end
337
+
338
+ def css_locations
339
+ template_location_array.to_a.map {|l| l.last}
340
+ end
341
+
342
+ def css_filename(name, path)
343
+ "#{path}/#{name}".gsub(/\.s[ac]ss$/, '.css')
344
+ end
345
+ end
346
+ end