| require 'fileutils' |
| |
| require 'sass' |
| require 'sass/plugin/compiler' |
| |
| module Sass |
| # This module provides a single interface to the compilation of Sass/SCSS files |
| # for an application. 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#Rack_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. |
| # |
| # Note that this class proxies almost all methods to its {Sass::Plugin::Compiler} instance. |
| # See \{#compiler}. |
| # |
| # @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 |
| # @see Sass::Plugin::Compiler |
| module Plugin |
| extend self |
| |
| @checked_for_updates = false |
| |
| # Whether or not Sass has **ever** checked if the stylesheets need to be updated |
| # (in this Ruby instance). |
| # |
| # @return [Boolean] |
| attr_accessor :checked_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 |
| def check_for_updates |
| return unless !Sass::Plugin.checked_for_updates || |
| Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check] |
| update_stylesheets |
| end |
| |
| # Returns the singleton compiler instance. |
| # This compiler has been pre-configured according |
| # to the plugin configuration. |
| # |
| # @return [Sass::Plugin::Compiler] |
| def compiler |
| @compiler ||= Compiler.new |
| 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. |
| def update_stylesheets(individual_files = []) |
| return if options[:never_update] |
| compiler.update_stylesheets(individual_files) |
| 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 |
| def force_update_stylesheets(individual_files = []) |
| Compiler.new( |
| options.dup.merge( |
| :never_update => false, |
| :always_update => true, |
| :cache => false)).update_stylesheets(individual_files) |
| end |
| |
| # All other method invocations are proxied to the \{#compiler}. |
| # |
| # @see #compiler |
| # @see Sass::Plugin::Compiler |
| def method_missing(method, *args, &block) |
| if compiler.respond_to?(method) |
| compiler.send(method, *args, &block) |
| else |
| super |
| end |
| end |
| |
| # For parity with method_missing |
| def respond_to?(method) |
| super || compiler.respond_to?(method) |
| end |
| |
| # There's a small speedup by not using method missing for frequently delegated methods. |
| def options |
| compiler.options |
| end |
| end |
| end |
| |
| if defined?(ActionController) |
| # On Rails 3+ the rails plugin is loaded at the right time in railtie.rb |
| require 'sass/plugin/rails' unless Sass::Util.ap_geq_3? |
| elsif defined?(Merb::Plugins) |
| require 'sass/plugin/merb' |
| else |
| require 'sass/plugin/generic' |
| end |