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

Methods

Included Modules

Haml::Util Sass::Callbacks

Classes and Modules

Class Sass::Plugin::Rack
Class Sass::Plugin::StalenessChecker

Attributes

checked_for_updates  [R]  Whether or not Sass has *ever* checked if the stylesheets need to be updated (in this Ruby instance).

@return [Boolean]

options  [R]  An options hash. See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.

@return [{Symbol => Object}]

Public Instance methods

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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

Sets the options hash. See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.

@param value [{Symbol => Object}] The options hash

[Source]

     # File lib/sass/plugin.rb, line 169
169:     def options=(value)
170:       @options.merge!(value)
171:     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.

[Source]

     # 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.

[Source]

     # 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

[Validate]