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