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:
parent
9fd7ac6e52
commit
2142430735
@ -217,13 +217,13 @@ later on.
|
||||
approach.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align:top;"><code>disable_warnings</code> </td>
|
||||
<td style="vertical-align:top;">Boolean </td>
|
||||
<tr>
|
||||
<td style="vertical-align:top;"><code>disable_warnings</code> </td>
|
||||
<td style="vertical-align:top;">Boolean </td>
|
||||
<td style="vertical-align:top;">
|
||||
Set this to true to silence deprecation warnings.
|
||||
</td>
|
||||
</tr>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align:top;"><code>sass_options</code> </td>
|
||||
<td style="vertical-align:top;">Hash </td>
|
||||
@ -330,4 +330,37 @@ more than once. Example:
|
||||
end
|
||||
|
||||
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.
|
||||
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
|
@ -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__), '..'))
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
25
lib/compass/configuration/callbacks.rb
Normal file
25
lib/compass/configuration/callbacks.rb
Normal 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
|
@ -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
|
||||
|
@ -2,7 +2,7 @@ require 'digest/md5'
|
||||
|
||||
module Compass::SassExtensions::Functions::Sprites
|
||||
ZERO = Sass::Script::Number::new(0)
|
||||
|
||||
|
||||
# Provides a consistent interface for getting a variable in ruby
|
||||
# from a keyword argument hash that accounts for underscores/dash equivalence
|
||||
# and allows the caller to pass a symbol instead of a string.
|
||||
@ -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
|
||||
|
||||
@ -155,7 +156,7 @@ module Compass::SassExtensions::Functions::Sprites
|
||||
end
|
||||
end
|
||||
end
|
||||
output_png
|
||||
output_png
|
||||
end
|
||||
|
||||
# The on-the-disk filename of the sprite
|
||||
@ -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
|
||||
@ -285,7 +288,7 @@ module Compass::SassExtensions::Functions::Sprites
|
||||
end
|
||||
end
|
||||
Sass::Script::Functions.declare :sprite_file, [:map, :sprite]
|
||||
|
||||
|
||||
# Returns a url to the sprite image.
|
||||
def sprite_url(map)
|
||||
unless map.is_a?(SpriteMap)
|
||||
|
@ -3,7 +3,7 @@ require "compass/sprites"
|
||||
require 'digest/md5'
|
||||
|
||||
describe Compass::Sprites do
|
||||
|
||||
|
||||
before :each do
|
||||
@images_src_path = File.join(File.dirname(__FILE__), 'test_project', 'public', 'images')
|
||||
@images_tmp_path = File.join(File.dirname(__FILE__), 'test_project', 'public', 'images-tmp')
|
||||
@ -29,7 +29,7 @@ describe Compass::Sprites do
|
||||
md5.update IO.read(map_location(file))
|
||||
md5.hexdigest
|
||||
end
|
||||
|
||||
|
||||
def render(scss)
|
||||
scss = %Q(@import "compass"; #{scss})
|
||||
options = Compass.sass_engine_options
|
||||
@ -40,9 +40,34 @@ describe Compass::Sprites do
|
||||
# reformat to fit result of heredoc:
|
||||
" #{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";
|
||||
@ -90,15 +115,15 @@ describe Compass::Sprites do
|
||||
CSS
|
||||
image_size('squares-*.png').should == [20, 30]
|
||||
end
|
||||
|
||||
|
||||
it "should provide sprite mixin" do
|
||||
css = render <<-SCSS
|
||||
@import "squares/*.png";
|
||||
|
||||
|
||||
.cubicle {
|
||||
@include squares-sprite("ten-by-ten");
|
||||
}
|
||||
|
||||
|
||||
.large-cube {
|
||||
@include squares-sprite("twenty-by-twenty", true);
|
||||
}
|
||||
@ -120,9 +145,9 @@ describe Compass::Sprites do
|
||||
CSS
|
||||
image_size('squares-*.png').should == [20, 30]
|
||||
end
|
||||
|
||||
|
||||
# CUSTOMIZATIONS:
|
||||
|
||||
|
||||
it "should be possible to change the base class" do
|
||||
css = render <<-SCSS
|
||||
$squares-sprite-base-class: ".circles";
|
||||
@ -135,7 +160,7 @@ describe Compass::Sprites do
|
||||
CSS
|
||||
image_size('squares-*.png').should == [20, 30]
|
||||
end
|
||||
|
||||
|
||||
it "should calculate the spacing between images but not before first image" do
|
||||
css = render <<-SCSS
|
||||
$squares-ten-by-ten-spacing: 33px;
|
||||
@ -157,7 +182,7 @@ describe Compass::Sprites do
|
||||
CSS
|
||||
image_size('squares-*.png').should == [20, 63]
|
||||
end
|
||||
|
||||
|
||||
it "should calculate the spacing between images" do
|
||||
css = render <<-SCSS
|
||||
$squares-twenty-by-twenty-spacing: 33px;
|
||||
@ -179,7 +204,7 @@ describe Compass::Sprites do
|
||||
CSS
|
||||
image_size('squares-*.png').should == [20, 63]
|
||||
end
|
||||
|
||||
|
||||
it "should calculate the maximum spacing between images" do
|
||||
css = render <<-SCSS
|
||||
$squares-ten-by-ten-spacing: 44px;
|
||||
@ -202,7 +227,7 @@ describe Compass::Sprites do
|
||||
CSS
|
||||
image_size('squares-*.png').should == [20, 74]
|
||||
end
|
||||
|
||||
|
||||
it "should calculate the maximum spacing between images in reversed order" do
|
||||
css = render <<-SCSS
|
||||
$squares-ten-by-ten-spacing: 33px;
|
||||
@ -225,7 +250,7 @@ describe Compass::Sprites do
|
||||
CSS
|
||||
image_size('squares-*.png').should == [20, 74]
|
||||
end
|
||||
|
||||
|
||||
it "should calculate the default spacing between images" do
|
||||
css = render <<-SCSS
|
||||
$squares-spacing: 22px;
|
||||
@ -247,22 +272,22 @@ describe Compass::Sprites do
|
||||
CSS
|
||||
image_size('squares-*.png').should == [20, 52]
|
||||
end
|
||||
|
||||
|
||||
it "should use position adjustments in functions" do
|
||||
css = render <<-SCSS
|
||||
$squares: sprite-map("squares/*.png", $position: 100%);
|
||||
.squares-sprite {
|
||||
background: $squares no-repeat;
|
||||
}
|
||||
|
||||
|
||||
.adjusted-percentage {
|
||||
background-position: sprite-position($squares, ten-by-ten, 100%);
|
||||
}
|
||||
|
||||
|
||||
.adjusted-px-1 {
|
||||
background-position: sprite-position($squares, ten-by-ten, 4px);
|
||||
}
|
||||
|
||||
|
||||
.adjusted-px-2 {
|
||||
background-position: sprite-position($squares, twenty-by-twenty, -3px, 2px);
|
||||
}
|
||||
@ -287,20 +312,20 @@ describe Compass::Sprites do
|
||||
image_size('squares-*.png').should == [20, 30]
|
||||
image_md5('squares-*.png').should == '652b67f5e9092520d6f26caae7e18012'
|
||||
end
|
||||
|
||||
|
||||
it "should use position adjustments in mixins" do
|
||||
css = render <<-SCSS
|
||||
$squares-position: 100%;
|
||||
@import "squares/*.png";
|
||||
|
||||
|
||||
.adjusted-percentage {
|
||||
@include squares-sprite("ten-by-ten", $offset-x: 100%);
|
||||
}
|
||||
|
||||
|
||||
.adjusted-px-1 {
|
||||
@include squares-sprite("ten-by-ten", $offset-x: 4px);
|
||||
}
|
||||
|
||||
|
||||
.adjusted-px-2 {
|
||||
@include squares-sprite("twenty-by-twenty", $offset-x: -3px, $offset-y: 2px);
|
||||
}
|
||||
@ -325,7 +350,7 @@ describe Compass::Sprites do
|
||||
image_size('squares-*.png').should == [20, 30]
|
||||
image_md5('squares-*.png').should == '652b67f5e9092520d6f26caae7e18012'
|
||||
end
|
||||
|
||||
|
||||
it "should repeat the image" do
|
||||
css = render <<-SCSS
|
||||
$squares-repeat: repeat;
|
||||
@ -372,7 +397,7 @@ describe Compass::Sprites do
|
||||
image_size('squares-*.png').should == [30, 30]
|
||||
image_md5('squares-*.png').should == '2fb19ef9c83018c93c6f147af3a56cb2'
|
||||
end
|
||||
|
||||
|
||||
it "should provide a nice errors for lemonade's old users" do
|
||||
proc do
|
||||
render <<-SCSS
|
||||
@ -393,7 +418,7 @@ describe Compass::Sprites do
|
||||
proc do
|
||||
render <<-SCSS
|
||||
@import "squares/*.png";
|
||||
|
||||
|
||||
.squares {
|
||||
background: sprite-position("squares/twenty-by-twenty.png") no-repeat;
|
||||
}
|
||||
@ -401,7 +426,7 @@ describe Compass::Sprites do
|
||||
end.should raise_error Sass::SyntaxError,
|
||||
%q(The first argument to sprite-position() must be a sprite map. See http://beta.compass-style.org/help/tutorials/spriting/ for more information.)
|
||||
end
|
||||
|
||||
|
||||
it "should work even if @import is missing" do
|
||||
actual_css = render <<-SCSS
|
||||
.squares {
|
||||
@ -414,5 +439,5 @@ describe Compass::Sprites do
|
||||
}
|
||||
CSS
|
||||
end
|
||||
|
||||
|
||||
end
|
@ -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|
|
||||
@ -114,10 +134,10 @@ private
|
||||
end
|
||||
yield Compass.configuration
|
||||
rescue
|
||||
save_output(project_name)
|
||||
save_output(project_name)
|
||||
raise
|
||||
end
|
||||
|
||||
|
||||
def each_css_file(dir, &block)
|
||||
Dir.glob("#{dir}/**/*.css").each(&block)
|
||||
end
|
||||
@ -145,15 +165,15 @@ private
|
||||
def tempfile_path(project_name)
|
||||
File.join(project_path(project_name), "tmp")
|
||||
end
|
||||
|
||||
|
||||
def template_path(project_name)
|
||||
File.join(project_path(project_name), "sass")
|
||||
end
|
||||
|
||||
|
||||
def result_path(project_name)
|
||||
File.join(project_path(project_name), "css")
|
||||
end
|
||||
|
||||
|
||||
def save_path(project_name)
|
||||
File.join(project_path(project_name), "saved")
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user