Merge branch 'master' of github.com:chriseppstein/compass into stable
This commit is contained in:
commit
9992a18a72
@ -14,6 +14,13 @@ The Documentation for the [latest stable release](http://compass-style.org/docs/
|
||||
|
||||
The Documentation for the [latest preview release](http://beta.compass-style.org/)
|
||||
|
||||
0.11.3 (PENDING)
|
||||
-------------------
|
||||
* Sprites will now by default remove any old versions of the sprite a new variable has been created to override this.
|
||||
* Nested sprites are now supported using globs `@import 'nested/**/*.png';`.
|
||||
* Fixed a bug that was causing sprite variable options to not get passed to the image classes.
|
||||
* Sass Colors will no longer cause an error if you use them as sprite names.
|
||||
|
||||
0.11.2 (05/01/2011)
|
||||
-------------------
|
||||
|
||||
|
@ -182,6 +182,7 @@ the sprites were contained within a folder called `icon`.
|
||||
included in each sprite's CSS output. Can be `true` or `false`. Defaults to `false`.
|
||||
* `$<map>-sprite-base-class` -- The base class for these sprites. Defaults to `.<map>-sprite`.
|
||||
E.g. `$icon-sprite-base-class: ".action-icon"`
|
||||
* `$<map>-clean-up` -- Whether or not to removed the old sprite file when a new one is created. Defaults to true
|
||||
|
||||
### Options per Sprite
|
||||
|
||||
|
@ -15,14 +15,15 @@ $sprite-selectors: hover, target, active !default;
|
||||
background-position: sprite-position($map, $sprite, $offset-x, $offset-y);
|
||||
}
|
||||
|
||||
|
||||
// Determines if you want to include magic selectors in your sprites
|
||||
$disable-magic-sprite-selectors:false !default;
|
||||
|
||||
// Include the position and (optionally) dimensions of this `$sprite`
|
||||
// in the given sprite `$map`. The sprite url should come from either a base
|
||||
// class or you can specify the `sprite-url` explicitly like this:
|
||||
//
|
||||
// background: $map no-repeat;
|
||||
|
||||
$disable-magic-sprite-selectors:false !default;
|
||||
|
||||
@mixin sprite($map, $sprite, $dimensions: false, $offset-x: 0, $offset-y: 0) {
|
||||
@include sprite-background-position($map, $sprite, $offset-x, $offset-y);
|
||||
@if $dimensions {
|
||||
|
@ -22,7 +22,7 @@ module Compass::SassExtensions::Functions::Sprites
|
||||
def sprite_map(glob, kwargs = {})
|
||||
kwargs.extend VariableReader
|
||||
Compass::SassExtensions::Sprites::Base.from_uri(glob, self, kwargs)
|
||||
end
|
||||
end
|
||||
Sass::Script::Functions.declare :sprite_map, [:glob], :var_kwargs => true
|
||||
|
||||
# Returns the image and background position for use in a single shorthand property:
|
||||
@ -34,6 +34,7 @@ module Compass::SassExtensions::Functions::Sprites
|
||||
#
|
||||
# background: url('/images/icons.png?12345678') 0 -24px no-repeat;
|
||||
def sprite(map, sprite, offset_x = ZERO, offset_y = ZERO)
|
||||
sprite = convert_sprite_name(sprite)
|
||||
verify_map(map)
|
||||
unless sprite.is_a?(Sass::Script::String)
|
||||
raise Sass::SyntaxError, %Q(The second argument to sprite() must be a sprite name. See http://beta.compass-style.org/help/tutorials/spriting/ for more information.)
|
||||
@ -56,6 +57,7 @@ module Compass::SassExtensions::Functions::Sprites
|
||||
|
||||
# Returns the path to the original image file for the sprite with the given name
|
||||
def sprite_file(map, sprite)
|
||||
sprite = convert_sprite_name(sprite)
|
||||
verify_map(map, "sprite")
|
||||
verify_sprite(sprite)
|
||||
if image = map.image_for(sprite.value)
|
||||
@ -68,6 +70,7 @@ module Compass::SassExtensions::Functions::Sprites
|
||||
|
||||
# Returns voolean if sprite has a parent
|
||||
def sprite_does_not_have_parent(map, sprite)
|
||||
sprite = convert_sprite_name(sprite)
|
||||
verify_map map
|
||||
verify_sprite sprite
|
||||
Sass::Script::Bool.new map.image_for(sprite.value).parent.nil?
|
||||
@ -77,6 +80,7 @@ module Compass::SassExtensions::Functions::Sprites
|
||||
|
||||
# Returns boolean if sprite has the selector
|
||||
def sprite_has_selector(map, sprite, selector)
|
||||
sprite = convert_sprite_name(sprite)
|
||||
verify_map map
|
||||
verify_sprite sprite
|
||||
unless VALID_SELECTORS.include?(selector.value)
|
||||
@ -118,6 +122,7 @@ module Compass::SassExtensions::Functions::Sprites
|
||||
#
|
||||
# background-position: 3px -36px;
|
||||
def sprite_position(map, sprite = nil, offset_x = ZERO, offset_y = ZERO)
|
||||
sprite = convert_sprite_name(sprite)
|
||||
verify_map(map, "sprite-position")
|
||||
unless sprite && sprite.is_a?(Sass::Script::String)
|
||||
raise Sass::SyntaxError, %Q(The second argument to sprite-position must be a sprite name. See http://beta.compass-style.org/help/tutorials/spriting/ for more information.)
|
||||
@ -147,6 +152,13 @@ module Compass::SassExtensions::Functions::Sprites
|
||||
|
||||
protected
|
||||
|
||||
def convert_sprite_name(sprite)
|
||||
if sprite.is_a?(Sass::Script::Color)
|
||||
return Sass::Script::String.new(Sass::Script::Color::HTML4_COLORS_REVERSE[sprite.rgb])
|
||||
end
|
||||
sprite
|
||||
end
|
||||
|
||||
def verify_map(map, error = "sprite")
|
||||
unless map.is_a?(Compass::SassExtensions::Sprites::Base)
|
||||
missing_sprite!(error)
|
||||
|
@ -8,7 +8,6 @@ module Compass
|
||||
# the path is relative to the <tt>images_path</tt> confguration option
|
||||
def self.from_uri(uri, context, kwargs)
|
||||
sprite_map = ::Compass::SpriteMap.new(uri.value, {})
|
||||
|
||||
sprites = sprite_map.files.map do |sprite|
|
||||
sprite.gsub(Compass.configuration.images_path+"/", "")
|
||||
end
|
||||
@ -24,18 +23,22 @@ module Compass
|
||||
# We should do so only when the packing algorithm changes
|
||||
SPRITE_VERSION = "1"
|
||||
|
||||
attr_accessor :image_names, :path, :name, :options, :map
|
||||
attr_accessor :image_names, :path, :name, :map, :kwargs
|
||||
attr_accessor :images, :width, :height
|
||||
|
||||
|
||||
def initialize(image_names, map, context, options)
|
||||
def initialize(sprites, sprite_map, context, kwargs)
|
||||
require_engine!
|
||||
@image_names, @path, @name, @options = image_names, map.path, map.name, options
|
||||
@image_names = sprites
|
||||
@path = sprite_map.path
|
||||
@name = sprite_map.name
|
||||
@kwargs = kwargs
|
||||
@kwargs['cleanup'] ||= Sass::Script::Bool.new(true)
|
||||
@images = nil
|
||||
@width = nil
|
||||
@height = nil
|
||||
@evaluation_context = context
|
||||
@map = map
|
||||
@map = sprite_map
|
||||
validate!
|
||||
compute_image_metadata!
|
||||
end
|
||||
@ -58,7 +61,7 @@ module Compass
|
||||
# Creates the Sprite::Image objects for each image and calculates the width
|
||||
def init_images
|
||||
@images = image_names.collect do |relative_file|
|
||||
image = Compass::SassExtensions::Sprites::Image.new(self, relative_file, options)
|
||||
image = Compass::SassExtensions::Sprites::Image.new(self, relative_file, kwargs)
|
||||
@width = [ @width, image.width + image.offset ].max
|
||||
image
|
||||
end
|
||||
@ -118,12 +121,21 @@ module Compass
|
||||
# Generate a sprite image if necessary
|
||||
def generate
|
||||
if generation_required?
|
||||
if kwargs.get_var('cleanup').value
|
||||
cleanup_old_sprites
|
||||
end
|
||||
sprite_data = construct_sprite
|
||||
save!(sprite_data)
|
||||
Compass.configuration.run_callback(:sprite_generated, sprite_data)
|
||||
end
|
||||
end
|
||||
|
||||
def cleanup_old_sprites
|
||||
Dir[File.join(Compass.configuration.images_path, "#{path}-*.png")].each do |file|
|
||||
FileUtils.rm file
|
||||
end
|
||||
end
|
||||
|
||||
# Does this sprite need to be generated
|
||||
def generation_required?
|
||||
!File.exists?(filename) || outdated?
|
||||
@ -174,7 +186,7 @@ module Compass
|
||||
to_s
|
||||
end
|
||||
|
||||
def to_s(options = self.options)
|
||||
def to_s(kwargs = self.kwargs)
|
||||
sprite_url(self).value
|
||||
end
|
||||
|
||||
|
@ -50,7 +50,18 @@ module Compass
|
||||
end
|
||||
|
||||
def ensure_path_and_name!
|
||||
@path, @name = Compass::Sprites.path_and_name(uri)
|
||||
@path ||= get_path
|
||||
@name ||= get_name
|
||||
end
|
||||
|
||||
def get_name
|
||||
_, name = Compass::Sprites.path_and_name(uri)
|
||||
name
|
||||
end
|
||||
|
||||
def get_path
|
||||
path, _ = Compass::Sprites.path_and_name(uri)
|
||||
path
|
||||
end
|
||||
|
||||
def key(uri, options)
|
||||
@ -74,8 +85,9 @@ $#{name}-position: 0% !default;
|
||||
$#{name}-spacing: 0 !default;
|
||||
$#{name}-repeat: no-repeat !default;
|
||||
$#{name}-prefix: '' !default;
|
||||
$#{name}-clean-up: true !default;
|
||||
|
||||
#{skip_overrides ? "$#{name}-sprites: sprite-map(\"#{uri}\");" : generate_overrides }
|
||||
#{skip_overrides ? "$#{name}-sprites: sprite-map(\"#{uri}\", $cleanup: $#{name}-clean-up);" : generate_overrides }
|
||||
|
||||
// All sprites should extend this class
|
||||
// The #{name}-sprite mixin will do so for you.
|
||||
@ -129,7 +141,7 @@ $#{name}-#{sprite_name}-repeat: $#{name}-repeat !default;
|
||||
SCSS
|
||||
end.join
|
||||
|
||||
content += "\n$#{name}-sprites: sprite-map(\"#{uri}\",\n"
|
||||
content += "\n$#{name}-sprites: sprite-map(\"#{uri}\", \n$cleanup: $#{name}-clean-up,\n"
|
||||
content += sprite_names.map do |sprite_name|
|
||||
%Q{ $#{sprite_name}-position: $#{name}-#{sprite_name}-position,
|
||||
$#{sprite_name}-spacing: $#{name}-#{sprite_name}-spacing,
|
||||
|
@ -3,11 +3,11 @@ module Compass
|
||||
attr_accessor :name, :path
|
||||
|
||||
def self.path_and_name(uri)
|
||||
if uri =~ %r{((.+/)?(.+))/(.+?)\.png}
|
||||
[$1, $3, $4]
|
||||
if uri =~ %r{((.+/)?([^\*.]+))/(.+?)\.png}
|
||||
[$1, $3]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def self.discover_sprites(uri)
|
||||
self.load_map(uri, {}).files
|
||||
end
|
||||
|
BIN
test/fixtures/sprites/public/images/colors/blue.png
vendored
Normal file
BIN
test/fixtures/sprites/public/images/colors/blue.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
test/fixtures/sprites/public/images/colors/yellow.png
vendored
Normal file
BIN
test/fixtures/sprites/public/images/colors/yellow.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
@ -9,8 +9,8 @@ class SpritesTest < Test::Unit::TestCase
|
||||
|
||||
def setup
|
||||
Compass.reset_configuration!
|
||||
@images_src_path = File.join(File.dirname(__FILE__), 'fixtures', 'sprites', 'public', 'images')
|
||||
@images_tmp_path = File.join(File.dirname(__FILE__), 'fixtures', 'sprites', 'public', 'images-tmp')
|
||||
@images_src_path = File.join(File.dirname(__FILE__), '..', 'fixtures', 'sprites', 'public', 'images')
|
||||
@images_tmp_path = File.join(File.dirname(__FILE__), '..', 'fixtures', 'sprites', 'public', 'images-tmp')
|
||||
::FileUtils.cp_r @images_src_path, @images_tmp_path
|
||||
file = StringIO.new("images_path = #{@images_tmp_path.inspect}\n")
|
||||
Compass.add_configuration(file, "sprite_config")
|
||||
@ -24,7 +24,11 @@ class SpritesTest < Test::Unit::TestCase
|
||||
|
||||
|
||||
def map_location(file)
|
||||
Dir.glob(File.join(@images_tmp_path, file)).first
|
||||
map_files(file).first
|
||||
end
|
||||
|
||||
def map_files(glob)
|
||||
Dir.glob(File.join(@images_tmp_path, glob))
|
||||
end
|
||||
|
||||
def image_size(file)
|
||||
@ -546,5 +550,58 @@ class SpritesTest < Test::Unit::TestCase
|
||||
}
|
||||
CSS
|
||||
end
|
||||
|
||||
it "should generate a sprite and remove the old file" do
|
||||
FileUtils.touch File.join(@images_tmp_path, "selectors-cc8834Fdd.png")
|
||||
assert_equal 1, map_files('selectors-*.png').size
|
||||
css = render <<-SCSS
|
||||
@import "selectors/*.png";
|
||||
a {
|
||||
$disable-magic-sprite-selectors:true;
|
||||
@include selectors-sprite(ten-by-ten)
|
||||
}
|
||||
SCSS
|
||||
assert_equal 1, map_files('selectors-*.png').size, "File was not removed"
|
||||
end
|
||||
|
||||
it "should generate a sprite and NOT remove the old file" do
|
||||
FileUtils.touch File.join(@images_tmp_path, "selectors-cc8834Ftest.png")
|
||||
assert_equal 1, map_files('selectors-*.png').size
|
||||
css = render <<-SCSS
|
||||
$selectors-clean-up: false;
|
||||
@import "selectors/*.png";
|
||||
a {
|
||||
$disable-magic-sprite-selectors:true;
|
||||
@include selectors-sprite(ten-by-ten)
|
||||
}
|
||||
SCSS
|
||||
assert_equal 2, map_files('selectors-*.png').size, "File was removed"
|
||||
end
|
||||
|
||||
it "should generate a sprite if the sprite is a colorname" do
|
||||
css = render <<-SCSS
|
||||
@import "colors/*.png";
|
||||
a {
|
||||
@include colors-sprite(blue);
|
||||
}
|
||||
SCSS
|
||||
assert !css.empty?
|
||||
end
|
||||
|
||||
it "should generate a sprite from nested folders" do
|
||||
css = render <<-SCSS
|
||||
@import "nested/**/*.png";
|
||||
@include all-nested-sprites;
|
||||
SCSS
|
||||
assert_correct css, <<-CSS
|
||||
.nested-sprite, .nested-ten-by-ten {
|
||||
background: url('/nested-55a8935544.png') no-repeat;
|
||||
}
|
||||
|
||||
.nested-ten-by-ten {
|
||||
background-position: 0 0;
|
||||
}
|
||||
CSS
|
||||
end
|
||||
|
||||
end
|
@ -1,7 +1,7 @@
|
||||
require 'test_helper'
|
||||
require 'fileutils'
|
||||
|
||||
class CommandLineTest < Test::Unit::TestCase
|
||||
class CompassPngTest < Test::Unit::TestCase
|
||||
|
||||
def test_class_crc_table
|
||||
assert_equal 256, Compass::PNG::CRC_TABLE.length
|
@ -3,15 +3,20 @@ require 'test_helper'
|
||||
class SpritesBaseTest < Test::Unit::TestCase
|
||||
|
||||
def setup
|
||||
@images_src_path = File.join(File.dirname(__FILE__), '..', 'fixtures', 'sprites', 'public', 'images')
|
||||
@images_tmp_path = File.join(File.dirname(__FILE__), '..', 'fixtures', 'sprites', 'public', 'images-tmp')
|
||||
Hash.send(:include, Compass::SassExtensions::Functions::Sprites::VariableReader)
|
||||
@images_src_path = File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'sprites', 'public', 'images')
|
||||
@images_tmp_path = File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'sprites', 'public', 'images-tmp')
|
||||
FileUtils.cp_r @images_src_path, @images_tmp_path
|
||||
config = Compass::Configuration::Data.new('config')
|
||||
config.images_path = @images_tmp_path
|
||||
Compass.add_configuration(config)
|
||||
Compass.configure_sass_plugin!
|
||||
options = Compass.sass_engine_options.extend Compass::SassExtensions::Functions::Sprites::VariableReader
|
||||
@map = Compass::SpriteMap.new("selectors/*.png", options)
|
||||
@options = {'cleanup' => Sass::Script::Bool.new(true)}
|
||||
setup_map
|
||||
end
|
||||
|
||||
def setup_map
|
||||
@map = Compass::SpriteMap.new("selectors/*.png", @options)
|
||||
@base = Compass::SassExtensions::Sprites::Base.new(@map.sprite_names.map{|n| "selectors/#{n}.png"}, @map, @map.sass_engine, @map.options)
|
||||
end
|
||||
|
||||
@ -70,4 +75,16 @@ class SpritesBaseTest < Test::Unit::TestCase
|
||||
assert !@base.outdated?
|
||||
end
|
||||
|
||||
it "should remove old sprite when generating new" do
|
||||
@base.generate
|
||||
file = @base.filename
|
||||
assert File.exists?(file), "Original file does not exist"
|
||||
file_to_remove = File.join(@images_tmp_path, 'selectors', 'ten-by-ten.png')
|
||||
FileUtils.rm file_to_remove
|
||||
assert !File.exists?(file_to_remove), "Failed to remove sprite file"
|
||||
setup_map
|
||||
@base.generate
|
||||
assert !File.exists?(file), "Sprite file did not get removed"
|
||||
end
|
||||
|
||||
end
|
@ -5,7 +5,7 @@ class SpritesImageTest < Test::Unit::TestCase
|
||||
|
||||
|
||||
def setup
|
||||
@images_src_path = File.join(File.dirname(__FILE__), '..', 'fixtures', 'sprites', 'public', 'images')
|
||||
@images_src_path = File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'sprites', 'public', 'images')
|
||||
file = StringIO.new("images_path = #{@images_src_path.inspect}\n")
|
||||
Compass.add_configuration(file, "sprite_config")
|
||||
@repeat = 'no-repeat'
|
Loading…
Reference in New Issue
Block a user