Permalink
Browse files

[Sass] Factor out a compiler class from the Plugin module.

  • Loading branch information...
1 parent 1feeafb commit 82671fc7419f511f3fcb54eb34b2881be91840f2 @chriseppstein chriseppstein committed May 19, 2010
@@ -119,13 +119,13 @@ can be either a String, a Hash, or an Array.
This makes it difficult to modify or use with confidence.
Thus, three new methods have been added for handling it:
-* {Sass::Plugin#template_location_array} --
+* {Sass::Plugin::Configuration#template_location_array Sass::Plugin#template_location_array} --
Returns the template locations and CSS locations formatted as an array.
-* {Sass::Plugin#add_template_location} --
+* {Sass::Plugin::Configuration#add_template_location Sass::Plugin#add_template_location} --
Converts the template location option to an array and adds a new location.
-* {Sass::Plugin#remove_template_location} --
+* {Sass::Plugin::Configuration#remove_template_location Sass::Plugin#remove_template_location} --
Converts the template location option to an array and removes an existing location.
## 3.0.0
@@ -619,7 +619,7 @@ and all of them will be watched:
sass --watch app/stylesheets:public/stylesheets public/stylesheets/test.sass
File and directory watching is accessible from Ruby,
-using the {Sass::Plugin#watch} function.
+using the {Sass::Plugin::Compiler#watch Sass::Plugin#watch} function.
#### Bulk Updating
@@ -142,7 +142,7 @@ set the [`:cache`](#cache-option) option to `false`.
### Options
-Options can be set by setting the {Sass::Plugin#options Sass::Plugin.options} hash
+Options can be set by setting the {Sass::Plugin::Configuration#options Sass::Plugin#options} hash
in `environment.rb` in Rails or `config.ru` in Rack...
Sass::Plugin.options[:style] = :compact
@@ -237,9 +237,9 @@ Available options are:
between them.
**Note that due to the many possible formats it can take,
this option should only be set directly, not accessed or modified.
- Use the {Sass::Plugin#template_location_array},
- {Sass::Plugin#add_template_location},
- and {Sass::Plugin#remove_template_location} methods instead**.
+ Use the {Sass::Plugin::Configuration#template_location_array Sass::Plugin#template_location_array},
+ {Sass::Plugin::Configuration#add_template_location Sass::Plugin#add_template_location},
+ and {Sass::Plugin::Configuration#remove_template_location Sass::Plugin#remove_template_location} methods instead**.
{#css_location-option} `:css_location`
: The path where CSS output should be written to.
View
@@ -23,8 +23,18 @@ module Sass
# m.on_string_munged {|str, res| puts "#{str} was munged into #{res}!"}
# m.munge "bar" #=> bar was munged into bbaarr!
module Callbacks
+ def self.extended(base)
+ base.send(:include, InstanceMethods)
+ end
protected
+ module InstanceMethods
+ # Removes all callbacks registered against this object.
+ def clear_callbacks!
+ @_sass_callbacks = {}
+ end
+ end
+
# Define a callback with the given name.
# This will define an `on_#{name}` method
# that registers a block,
View
@@ -6,8 +6,8 @@
require 'sass/plugin/staleness_checker'
module Sass
- # This module handles the compilation of Sass/SCSS files.
- # It provides global options and checks whether CSS files
+ # 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
@@ -30,7 +30,7 @@ module Sass
# #=> Compiling app/sass/print.scss to public/stylesheets/print.css
# #=> Compiling app/sass/ie.scss to public/stylesheets/ie.css
module Plugin
- include Haml::Util
+ extend self
@checked_for_updates = false
@@ -51,6 +51,13 @@ def check_for_updates
update_stylesheets
end
+ # Returns the singleton compiler instance
+ # This compiler has been pre-configured according
+ # to the plugin configuration.
+ 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`}
@@ -66,29 +73,7 @@ def check_for_updates
# 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]
-
- run_updating_stylesheets individual_files
-
- individual_files.each {|t, c| update_stylesheet(t, c)}
-
- @checked_for_updates = true
- staleness_checker = StalenessChecker.new
-
- template_location_array.each do |template_location, css_location|
-
- Dir.glob(File.join(template_location, "**", "*.s[ca]ss")).each do |file|
- # Get the relative path to the file
- name = file.sub(template_location.sub(/\/*$/, '/'), "")
- css = css_filename(name, css_location)
-
- next if forbid_update?(name)
- if options[:always_update] || staleness_checker.stylesheet_needs_update?(css, file)
- update_stylesheet file, css
- else
- run_not_updating_stylesheet file, css
- end
- end
- end
+ compiler.update_stylesheets(individual_files)
end
# Updates all stylesheets, even those that aren't out-of-date.
@@ -112,158 +97,21 @@ def force_update_stylesheets(individual_files = [])
self.options = old_options
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.
+ # All other method invocations are proxied to the compiler instance
#
- # Before the watching starts in earnest, `watch` calls \{#update\_stylesheets}.
- #
- # Note that `watch` uses the [FSSM](http://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.
- def watch(individual_files = [])
- update_stylesheets(individual_files)
-
- begin
- require 'fssm'
- rescue LoadError => e
- e.message << "\n" <<
- if File.exists?(scope(".git"))
- 'Run "git submodule update --init" to get the recommended version.'
- else
- 'Run "gem install fssm" to get it.'
- end
- raise e
- end
-
- unless individual_files.empty? && FSSM::Backends::Default.name == "FSSM::Backends::FSEvents"
- # As of FSSM 0.1.4, it doesn't support FSevents on individual files,
- # but it also isn't smart enough to switch to polling itself.
- require 'fssm/backends/polling'
- Haml::Util.silence_warnings do
- FSSM::Backends.const_set(:Default, FSSM::Backends::Polling)
- end
- end
-
- # TODO: Keep better track of what depends on what
- # so we don't have to run a global update every time anything changes.
- FSSM.monitor do |mon|
- template_location_array.each do |template_location, css_location|
- mon.path template_location do |path|
- path.glob '**/*.s[ac]ss'
-
- path.update do |base, relative|
- run_template_modified File.join(base, relative)
- update_stylesheets(individual_files)
- end
-
- path.create do |base, relative|
- run_template_created File.join(base, relative)
- update_stylesheets(individual_files)
- end
-
- path.delete do |base, relative|
- run_template_deleted File.join(base, relative)
- css = File.join(css_location, relative.gsub(/\.s[ac]ss$/, '.css'))
- try_delete_css css
- update_stylesheets(individual_files)
- end
- end
- end
-
- individual_files.each do |template, css|
- mon.file template do |path|
- path.update do
- run_template_modified template
- update_stylesheets(individual_files)
- end
-
- path.create do
- run_template_created template
- update_stylesheets(individual_files)
- end
-
- path.delete do
- run_template_deleted template
- try_delete_css css
- update_stylesheets(individual_files)
- end
- end
- end
- end
- end
-
- private
-
- def update_stylesheet(filename, css)
- dir = File.dirname(css)
- unless File.exists?(dir)
- run_creating_directory dir
- FileUtils.mkdir_p dir
- end
-
- begin
- result = Sass::Files.tree_for(filename, engine_options(:css_filename => css, :filename => filename)).render
- rescue Exception => e
- run_compilation_error e, filename, css
- result = Sass::SyntaxError.exception_to_css(e, options)
+ # @see #compiler
+ # @see Sass::Plugin::Compiler
+ def method_missing(method, *args, &block)
+ if compiler.respond_to?(method)
+ compiler.send(method, *args, &block)
else
- run_updating_stylesheet filename, css
+ super
end
-
- # Finally, write the file
- flag = 'w'
- flag = 'wb' if RbConfig::CONFIG['host_os'] =~ /mswin|windows/i && options[:unix_newlines]
- File.open(css, flag) {|file| file.print(result)}
- end
-
- def try_delete_css(css)
- return unless File.exists?(css)
- run_deleting_css css
- File.delete css
- end
-
- def load_paths(opts = options)
- (opts[:load_paths] || []) + template_locations
- end
-
- def template_locations
- template_location_array.to_a.map {|l| l.first}
- end
-
- def css_locations
- template_location_array.to_a.map {|l| l.last}
- end
-
- def css_filename(name, path)
- "#{path}/#{name}".gsub(/\.s[ac]ss$/, '.css')
end
- def forbid_update?(name)
- name.sub(/^.*\//, '')[0] == ?_
- end
-
- # Compass expects this to exist
- def stylesheet_needs_update?(css_file, template_file)
- StalenessChecker.stylesheet_needs_update?(css_file, template_file)
- end
end
end
+require 'sass/plugin/compiler'
require 'sass/plugin/rails' if defined?(ActionController)
require 'sass/plugin/merb' if defined?(Merb::Plugins)
Oops, something went wrong.

0 comments on commit 82671fc

Please sign in to comment.