Callbacks for the following events:

* sprite_saved
* sprite_generated
* stylesheet_saved
* stylesheet_error

From the compass configuration file you can attach code to run when the
event occurs like so:

on_stylesheet_error do |filename, message|
  # do something
end
This commit is contained in:
Scott Davis 2011-02-17 02:30:11 -05:00 committed by Chris Eppstein
parent 9fd7ac6e52
commit 2142430735
9 changed files with 160 additions and 46 deletions

View File

@ -331,3 +331,36 @@ more than once. Example:
This code will be called if the file is added, updated, or removed. Be sure to check for existence
to avoid crashing the watcher in the case where the file has been removed.
## Callbacks
**`on_sprite_saved`** -- Pass this function a block of code that gets executed after a sprite is saved to disk. The block will be passed the filename. Can be invoked more then once. Example:
on_sprite_saved do |filename|
post_process(filename) if File.exists?(filename)
end
**`on_sprite_generated`** -- Pass this function a block of code that gets executed after a sprite is generated but before its saved to disk. The block will be passed an instance of `ChunkyPNG::Image`. Can be invoked more then once. Example:
on_sprite_generated do |sprite_data|
sprite_data.metadata['Caption'] = "This Image is © My Company 2011"
end
**`on_stylesheet_saved`** -- Pass this function a block of code that gets executed after a stylesheet is processed. The block will be passed the filename. Can be invoked more then once. Example:
on_stylesheet_saved do |filename|
Growl.notify {
self.message "#{filename} updated!"
self.icon = '/path/to/success.jpg'
}
end
**`on_stylesheet_error`** -- Pass this function a block of code that gets executed if a stylesheet has an error while processing. The block will be passed the filename and the error message. Can be invoked more then once. Example:
on_stylesheet_error do |filename, message|
Growl.notify {
self.message = "#{filename}: #{message}"
self.icon = '/path/to/fail.jpg'
sticky!
}
end

View File

@ -5,6 +5,8 @@ end
require "compass/#{lib}"
end
require 'sass/callbacks'
module Compass
def base_directory
File.expand_path(File.join(File.dirname(__FILE__), '..'))

View File

@ -119,6 +119,7 @@ module Compass
end
duration = additional_options[:time] ? "(#{(css_content.__duration * 1000).round / 1000.0}s)" : ""
write_file(css_filename, css_content, options.merge(:force => true, :extra => duration))
Compass.configuration.send(:run_stylesheet_saved, File.basename(css_filename)) #run callback
end
def should_compile?(sass_filename, css_filename)
@ -136,7 +137,10 @@ module Compass
# formatted to display in the browser (in development mode)
# if there's an error.
def handle_exception(sass_filename, css_filename, e)
logger.record :error, basename(sass_filename), "(Line #{e.sass_line}: #{e.message})"
formatted_error = "(Line #{e.sass_line}: #{e.message})"
file = basename(sass_filename)
logger.record :error, file, formatted_error
Compass.configuration.send(:run_styesheet_error, file, formatted_error) #run callback
write_file css_filename, error_contents(e, sass_filename), options.merge(:force => true)
end

View File

@ -43,6 +43,6 @@ module Compass
end
end
['adapters', 'comments', 'defaults', 'helpers', 'inheritance', 'serialization', 'paths', 'data'].each do |lib|
['adapters', 'callbacks', 'comments', 'defaults', 'helpers', 'inheritance', 'serialization', 'paths', 'data'].each do |lib|
require "compass/configuration/#{lib}"
end

View File

@ -0,0 +1,25 @@
module Compass
module Configuration
module CallbackMethods
extend ::Sass::Callbacks
# on_sprite_generated
# yields the filename
# usage: on_sprite_save {|filename| do_somethign(filename) }
define_callback :sprite_saved
# on_sprite_generated
# yields 'ChunkyPNG::Image'
# usage: on_sprite_generated {|sprite_data| do_something(sprite_data) }
define_callback :sprite_generated
define_callback :stylesheet_saved
define_callback :stylesheet_error
end
class Callbacks
extend CallbackMethods
end
end
end

View File

@ -141,9 +141,11 @@ module Compass
end
end
def method_missing(meth)
def method_missing(meth, *args, &block)
if inherited_data
inherited_data.send(meth)
inherited_data.send(meth, *args, &block)
elsif Callbacks.respond_to?(meth, true)
Callbacks.send(meth, *args, &block)
else
raise NoMethodError, meth.to_s
end

View File

@ -124,6 +124,7 @@ module Compass::SassExtensions::Functions::Sprites
def generate
if generation_required?
save!(construct_sprite)
Compass.configuration.send(:run_sprite_generated, construct_sprite)
end
end
@ -180,7 +181,9 @@ module Compass::SassExtensions::Functions::Sprites
# saves the sprite for later retrieval
def save!(output_png)
output_png.save filename
saved = output_png.save filename
Compass.configuration.send(:run_sprite_saved, filename)
saved
end
# All the full-path filenames involved in this sprite

View File

@ -41,8 +41,33 @@ describe Compass::Sprites do
" #{css.gsub('@charset "UTF-8";', '').gsub(/\n/, "\n ").strip}\n"
end
# DEFAULT USAGE:
#Callbacks
describe 'callbacks' do
it "should fire on_sprite_saved" do
saved = false
path = nil
Compass.configuration.on_sprite_saved {|filepath| path = filepath; saved = true }
render <<-SCSS
@import "squares/*.png";
@include all-squares-sprites;
SCSS
saved.should eq true
path.should be_kind_of String
end
it "should fire on_sprite_generated" do
saved = false
sprite_data = nil
Compass.configuration.on_sprite_generated {|data| sprite_data = data; saved = true }
render <<-SCSS
@import "squares/*.png";
@include all-squares-sprites;
SCSS
sprite_data.should be_kind_of ChunkyPNG::Image
saved.should eq true
end
end
# DEFAULT USAGE:
it "should generate sprite classes" do
css = render <<-SCSS
@import "squares/*.png";

View File

@ -20,6 +20,26 @@ class CompassTest < Test::Unit::TestCase
end
end
def test_on_stylesheet_saved_callback
saved = false
filepath = nil
Compass.configuration.on_stylesheet_saved {|filepath| path = filepath; saved = true }
within_project(:blueprint) { } #requires a block but we don't need to pass anything - sdavis
assert saved, "Stylesheet callback didn't get called"
assert filepath.is_a?(String), "Path is not a string"
end
# no project with errors exists to test aginst - leep of FAITH!
# *chriseppstein flogs himself*
# def test_on_stylesheet_error_callback
# error = false
# file = nil
# Compass.configuration.on_stylesheet_error {|filename, message| file = filename; error = true }
# within_project(:error) { } #requires a block but we don't need to pass anything - sdavis
# assert error, "Project did not throw a compile error"
# assert file.is_a?(String), "Filename was not a string"
# end
def test_empty_project
# With no sass files, we should have no css files.
within_project(:empty) do |proj|