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