| Module | Sass::Plugin |
| In: |
lib/sass/plugin.rb
lib/sass/plugin/rack.rb lib/sass/plugin/staleness_checker.rb |
This module handles the compilation of Sass/SCSS files. It provides global options and checks whether CSS files need to be updated.
This module is used as the primary interface with Sass when it‘s used as a plugin for various frameworks. All Rack-enabled frameworks are supported out of the box. The plugin is {file:SASS_REFERENCE.md#rails_merb_plugin automatically activated for Rails and Merb}. Other frameworks must enable it explicitly; see {Sass::Plugin::Rack}.
This module has a large set of callbacks available to allow users to run code (such as logging) when certain things happen. All callback methods are of the form `on_#{name}`, and they all take a block that‘s called when the given action occurs.
@example Using a callback Sass::Plugin.on_updating_stylesheet do |template, css|
puts "Compiling #{template} to #{css}"
end Sass::Plugin.update_stylesheets
#=> Compiling app/sass/screen.scss to public/stylesheets/screen.css #=> Compiling app/sass/print.scss to public/stylesheets/print.css #=> Compiling app/sass/ie.scss to public/stylesheets/ie.css
Same as \{update_stylesheets}, but respects \{checked_for_updates} and the {file:SASS_REFERENCE.md#always_update-option `:always_update`} and {file:SASS_REFERENCE.md#always_check-option `:always_check`} options.
@see update_stylesheets
# File lib/sass/plugin.rb, line 188
188: def check_for_updates
189: return unless !Sass::Plugin.checked_for_updates ||
190: Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
191: update_stylesheets
192: end
Non-destructively modifies \{options} so that default values are properly set.
@param additional_options [{Symbol => Object}] An options hash with which to merge \{options} @return [{Symbol => Object}] The modified options hash
# File lib/sass/plugin.rb, line 177
177: def engine_options(additional_options = {})
178: opts = options.dup.merge(additional_options)
179: opts[:load_paths] = load_paths(opts)
180: opts
181: end
Updates all stylesheets, even those that aren‘t out-of-date. Ignores the cache.
@param individual_files [Array<(String, String)>]
A list of files to check for updates
**in addition to those specified by the
{file:SASS_REFERENCE.md#template_location-option `:template_location` option}.**
The first string in each pair is the location of the Sass/SCSS file,
the second is the location of the CSS file that it should be compiled to.
@see update_stylesheets
# File lib/sass/plugin.rb, line 244
244: def force_update_stylesheets(individual_files = [])
245: old_options = options
246: self.options = options.dup
247: options[:never_update] = false
248: options[:always_update] = true
249: options[:cache] = false
250: update_stylesheets(individual_files)
251: ensure
252: self.options = old_options
253: end
Updates out-of-date stylesheets.
Checks each Sass/SCSS file in {file:SASS_REFERENCE.md#template_location-option `:template_location`} to see if it‘s been modified more recently than the corresponding CSS file in {file:SASS_REFERENCE.md#css_location-option `:css_location`}. If it has, it updates the CSS file.
@param individual_files [Array<(String, String)>]
A list of files to check for updates
**in addition to those specified by the
{file:SASS_REFERENCE.md#template_location-option `:template_location` option}.**
The first string in each pair is the location of the Sass/SCSS file,
the second is the location of the CSS file that it should be compiled to.
# File lib/sass/plugin.rb, line 207
207: def update_stylesheets(individual_files = [])
208: return if options[:never_update]
209:
210: run_updating_stylesheets individual_files
211:
212: individual_files.each {|t, c| update_stylesheet(t, c)}
213:
214: @checked_for_updates = true
215: staleness_checker = StalenessChecker.new
216:
217: template_locations.zip(css_locations).each do |template_location, css_location|
218:
219: Dir.glob(File.join(template_location, "**", "*.s[ca]ss")).each do |file|
220: # Get the relative path to the file
221: name = file.sub(template_location.sub(/\/*$/, '/'), "")
222: css = css_filename(name, css_location)
223:
224: next if forbid_update?(name)
225: if options[:always_update] || staleness_checker.stylesheet_needs_update?(css, file)
226: update_stylesheet file, css
227: else
228: run_not_updating_stylesheet file, css
229: end
230: end
231: end
232: end
Watches the template directory (or directories) and updates the CSS files whenever the related Sass/SCSS files change. `watch` never returns.
Whenever a change is detected to a Sass/SCSS file in {file:SASS_REFERENCE.md#template_location-option `:template_location`}, the corresponding CSS file in {file:SASS_REFERENCE.md#css_location-option `:css_location`} will be recompiled. The CSS files of any Sass/SCSS files that import the changed file will also be recompiled.
Before the watching starts in earnest, `watch` calls \{update_stylesheets}.
Note that `watch` uses the [FSSM](github.com/ttilley/fssm) library to monitor the filesystem for changes. FSSM isn‘t loaded until `watch` is run. The version of FSSM distributed with Sass is loaded by default, but if another version has already been loaded that will be used instead.
@param individual_files [Array<(String, String)>]
A list of files to watch for updates
**in addition to those specified by the
{file:SASS_REFERENCE.md#template_location-option `:template_location` option}.**
The first string in each pair is the location of the Sass/SCSS file,
the second is the location of the CSS file that it should be compiled to.
# File lib/sass/plugin.rb, line 279
279: def watch(individual_files = [])
280: update_stylesheets(individual_files)
281:
282: begin
283: require 'fssm'
284: rescue LoadError => e
285: e.message << "\n" <<
286: if File.exists?(scope(".git"))
287: 'Run "git submodule update --init" to get the recommended version.'
288: else
289: 'Run "gem install fssm" to get it.'
290: end
291: raise e
292: end
293:
294: unless individual_files.empty? && FSSM::Backends::Default.name == "FSSM::Backends::FSEvents"
295: # As of FSSM 0.1.4, it doesn't support FSevents on individual files,
296: # but it also isn't smart enough to switch to polling itself.
297: require 'fssm/backends/polling'
298: Haml::Util.silence_warnings do
299: FSSM::Backends.const_set(:Default, FSSM::Backends::Polling)
300: end
301: end
302:
303: # TODO: Keep better track of what depends on what
304: # so we don't have to run a global update every time anything changes.
305: FSSM.monitor do |mon|
306: template_locations.zip(css_locations).each do |template_location, css_location|
307: mon.path template_location do |path|
308: path.glob '**/*.s[ac]ss'
309:
310: path.update do |base, relative|
311: run_template_modified File.join(base, relative)
312: update_stylesheets(individual_files)
313: end
314:
315: path.create do |base, relative|
316: run_template_created File.join(base, relative)
317: update_stylesheets(individual_files)
318: end
319:
320: path.delete do |base, relative|
321: run_template_deleted File.join(base, relative)
322: css = File.join(css_location, relative.gsub(/\.s[ac]ss$/, '.css'))
323: try_delete_css css
324: update_stylesheets(individual_files)
325: end
326: end
327: end
328:
329: individual_files.each do |template, css|
330: mon.file template do |path|
331: path.update do
332: run_template_modified template
333: update_stylesheets(individual_files)
334: end
335:
336: path.create do
337: run_template_created template
338: update_stylesheets(individual_files)
339: end
340:
341: path.delete do
342: run_template_deleted template
343: try_delete_css css
344: update_stylesheets(individual_files)
345: end
346: end
347: end
348: end
349: end