Module | Sass::Plugin
In: | lib/sass/plugin/rack.rb lib/sass/plugin/configuration.rb lib/sass/plugin/staleness_checker.rb lib/sass/plugin.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

add_template_location check_for_updates engine_options force_update_stylesheets options= remove_template_location template_location_array update_stylesheets watch

### Included Modules

Sass::Callbacks Haml::Util

### Classes and Modules

Class Sass::Plugin::MerbBootLoader
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

add_template_location(template_location, css_location = options[:css_location])

Adds a new template-location/css-location mapping. This means that Sass/SCSS files in `template_location` will be compiled to CSS files in `css_location`.

This is preferred over manually manipulating the {file:SASS_REFERENCE.md#template_location-option `:template_location` option} since the option can be in multiple formats.

Note that this method will change `options[:template_location]` to be in the Array format. This means that even if `options[:template_location]` had previously been a Hash or a String, it will now be an Array.

@param template_location [String] The location where Sass/SCSS files will be. @param css_location [String] The location where compiled CSS files will go.

[Source]

         # File lib/sass/plugin/configuration.rb, line 166
    166:     def add_template_location(template_location, css_location = options[:css_location])
    167:       normalize_template_location!
    168:       template_location_array << [template_location, css_location]
    169:     end

check_for_updates()

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 48
    48:     def check_for_updates
    49:       return unless !Sass::Plugin.checked_for_updates ||
    50:           Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
    51:       update_stylesheets
    52:     end

engine_options(additional_options = {})

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/configuration.rb, line 145
    145:     def engine_options(additional_options = {})
    146:       opts = options.dup.merge(additional_options)
    147:       opts[:load_paths] = load_paths(opts)
    148:       opts
    149:     end

force_update_stylesheets(individual_files = [])

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 104
    104:     def force_update_stylesheets(individual_files = [])
    105:       old_options = options
    106:       self.options = options.dup
    107:       options[:never_update] = false
    108:       options[:always_update] = true
    109:       options[:cache] = false
    110:       update_stylesheets(individual_files)
    111:     ensure
    112:       self.options = old_options
    113:     end

options=(value)

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/configuration.rb, line 137
    137:     def options=(value)
    138:       @options.merge!(value)
    139:     end

remove_template_location(template_location, css_location = options[:css_location])

Removes a template-location/css-location mapping. This means that Sass/SCSS files in `template_location` will no longer be compiled to CSS files in `css_location`.

This is preferred over manually manipulating the {file:SASS_REFERENCE.md#template_location-option `:template_location` option} since the option can be in multiple formats.

Note that this method will change `options[:template_location]` to be in the Array format. This means that even if `options[:template_location]` had previously been a Hash or a String, it will now be an Array.

@param template_location [String]

      The location where Sass/SCSS files were,
      which is now going to be ignored.

@param css_location [String]

      The location where compiled CSS files went, but will no longer go.

@return [Boolean]

      Non-`nil` if the given mapping already existed and was removed,
      or `nil` if nothing was changed.

[Source]

         # File lib/sass/plugin/configuration.rb, line 192
    192:     def remove_template_location(template_location, css_location = options[:css_location])
    193:       normalize_template_location!
    194:       template_location_array.delete([template_location, css_location])
    195:     end

template_location_array()

Returns the template locations configured for Sass as an array of `[template_location, css_location]` pairs. See the {file:SASS_REFERENCE.md#template_location-option `:template_location` option} for details.

@return [Array<(String, String)>]

      An array of `[template_location, css_location]` pairs.

[Source]

         # File lib/sass/plugin/configuration.rb, line 204
    204:     def template_location_array
    205:       old_template_location = options[:template_location]
    206:       normalize_template_location!
    207:       options[:template_location]
    208:     ensure
    209:       options[:template_location] = old_template_location
    210:     end

update_stylesheets(individual_files = [])

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 67
    67:     def update_stylesheets(individual_files = [])
    68:       return if options[:never_update]
    69:
    70:       run_updating_stylesheets individual_files
    71:
    72:       individual_files.each {|t, c| update_stylesheet(t, c)}
    73:
    74:       @checked_for_updates = true
    75:       staleness_checker = StalenessChecker.new
    76:
    77:       template_location_array.each do |template_location, css_location|
    78:
    79:         Dir.glob(File.join(template_location, "**", "*.s[ca]ss")).each do |file|
    80:           # Get the relative path to the file
    81:           name = file.sub(template_location.sub(/\/*$/, '/'), "")
    82:           css = css_filename(name, css_location)
    83:
    84:           next if forbid_update?(name)
    85:           if options[:always_update] || staleness_checker.stylesheet_needs_update?(css, file)
    86:             update_stylesheet file, css
    87:           else
    88:             run_not_updating_stylesheet file, css
    89:           end
    90:         end
    91:       end
    92:     end

watch(individual_files = [])

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 139
    139:     def watch(individual_files = [])
    140:       update_stylesheets(individual_files)
    141:
    142:       begin
    143:         require 'fssm'
    144:       rescue LoadError => e
    145:         e.message << "\n" <<
    146:           if File.exists?(scope(".git"))
    147:             'Run "git submodule update --init" to get the recommended version.'
    148:           else
    149:             'Run "gem install fssm" to get it.'
    150:           end
    151:         raise e
    152:       end
    153:
    154:       unless individual_files.empty? && FSSM::Backends::Default.name == "FSSM::Backends::FSEvents"
    155:         # As of FSSM 0.1.4, it doesn't support FSevents on individual files,
    156:         # but it also isn't smart enough to switch to polling itself.
    157:         require 'fssm/backends/polling'
    158:         Haml::Util.silence_warnings do
    159:           FSSM::Backends.const_set(:Default, FSSM::Backends::Polling)
    160:         end
    161:       end
    162:
    163:       # TODO: Keep better track of what depends on what
    164:       # so we don't have to run a global update every time anything changes.
    165:       FSSM.monitor do |mon|
    166:         template_location_array.each do |template_location, css_location|
    167:           mon.path template_location do |path|
    168:             path.glob '**/*.s[ac]ss'
    169:
    170:             path.update do |base, relative|
    171:               run_template_modified File.join(base, relative)
    172:               update_stylesheets(individual_files)
    173:             end
    174:
    175:             path.create do |base, relative|
    176:               run_template_created File.join(base, relative)
    177:               update_stylesheets(individual_files)
    178:             end
    179:
    180:             path.delete do |base, relative|
    181:               run_template_deleted File.join(base, relative)
    182:               css = File.join(css_location, relative.gsub(/\.s[ac]ss$/, '.css'))
    183:               try_delete_css css
    184:               update_stylesheets(individual_files)
    185:             end
    186:           end
    187:         end
    188:
    189:         individual_files.each do |template, css|
    190:           mon.file template do |path|
    191:             path.update do
    192:               run_template_modified template
    193:               update_stylesheets(individual_files)
    194:             end
    195:
    196:             path.create do
    197:               run_template_created template
    198:               update_stylesheets(individual_files)
    199:             end
    200:
    201:             path.delete do
    202:               run_template_deleted template
    203:               try_delete_css css
    204:               update_stylesheets(individual_files)
    205:             end
    206:           end
    207:         end
    208:       end
    209:     end

[Validate]