diff --git a/doc-src/content/CHANGELOG.markdown b/doc-src/content/CHANGELOG.markdown index 3b966e4b..218c8b5e 100644 --- a/doc-src/content/CHANGELOG.markdown +++ b/doc-src/content/CHANGELOG.markdown @@ -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) ------------------- diff --git a/doc-src/content/help/tutorials/spriting.markdown b/doc-src/content/help/tutorials/spriting.markdown index 77169578..bf3d1b08 100644 --- a/doc-src/content/help/tutorials/spriting.markdown +++ b/doc-src/content/help/tutorials/spriting.markdown @@ -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`. * `$-sprite-base-class` -- The base class for these sprites. Defaults to `.-sprite`. E.g. `$icon-sprite-base-class: ".action-icon"` +* `$-clean-up` -- Whether or not to removed the old sprite file when a new one is created. Defaults to true ### Options per Sprite diff --git a/frameworks/compass/stylesheets/compass/utilities/sprites/_base.scss b/frameworks/compass/stylesheets/compass/utilities/sprites/_base.scss index bc63081b..c346e181 100644 --- a/frameworks/compass/stylesheets/compass/utilities/sprites/_base.scss +++ b/frameworks/compass/stylesheets/compass/utilities/sprites/_base.scss @@ -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 { diff --git a/lib/compass/sass_extensions/functions/sprites.rb b/lib/compass/sass_extensions/functions/sprites.rb index 18ca2009..69b7599e 100644 --- a/lib/compass/sass_extensions/functions/sprites.rb +++ b/lib/compass/sass_extensions/functions/sprites.rb @@ -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) diff --git a/lib/compass/sass_extensions/sprites/base.rb b/lib/compass/sass_extensions/sprites/base.rb index 194a5601..4bdea36b 100644 --- a/lib/compass/sass_extensions/sprites/base.rb +++ b/lib/compass/sass_extensions/sprites/base.rb @@ -8,7 +8,6 @@ module Compass # the path is relative to the images_path 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 diff --git a/lib/compass/sass_extensions/sprites/sprite_map.rb b/lib/compass/sass_extensions/sprites/sprite_map.rb index f2106739..121c4e12 100644 --- a/lib/compass/sass_extensions/sprites/sprite_map.rb +++ b/lib/compass/sass_extensions/sprites/sprite_map.rb @@ -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, diff --git a/lib/compass/sass_extensions/sprites/sprites.rb b/lib/compass/sass_extensions/sprites/sprites.rb index c0c5dc21..7431983f 100644 --- a/lib/compass/sass_extensions/sprites/sprites.rb +++ b/lib/compass/sass_extensions/sprites/sprites.rb @@ -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 diff --git a/test/fixtures/sprites/public/images/colors/blue.png b/test/fixtures/sprites/public/images/colors/blue.png new file mode 100644 index 00000000..c0ae53cc Binary files /dev/null and b/test/fixtures/sprites/public/images/colors/blue.png differ diff --git a/test/fixtures/sprites/public/images/colors/yellow.png b/test/fixtures/sprites/public/images/colors/yellow.png new file mode 100644 index 00000000..c0ae53cc Binary files /dev/null and b/test/fixtures/sprites/public/images/colors/yellow.png differ diff --git a/test/compass_test.rb b/test/integrations/compass_test.rb similarity index 100% rename from test/compass_test.rb rename to test/integrations/compass_test.rb diff --git a/test/rails_integration_test.rb b/test/integrations/rails_integration_test.rb similarity index 100% rename from test/rails_integration_test.rb rename to test/integrations/rails_integration_test.rb diff --git a/test/sprites_test.rb b/test/integrations/sprites_test.rb similarity index 88% rename from test/sprites_test.rb rename to test/integrations/sprites_test.rb index 8e6f4173..23a45996 100644 --- a/test/sprites_test.rb +++ b/test/integrations/sprites_test.rb @@ -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 \ No newline at end of file diff --git a/test/test_rails_helper.rb b/test/integrations/test_rails_helper.rb similarity index 100% rename from test/test_rails_helper.rb rename to test/integrations/test_rails_helper.rb diff --git a/test/command_line_test.rb b/test/units/command_line_test.rb similarity index 100% rename from test/command_line_test.rb rename to test/units/command_line_test.rb diff --git a/test/compass_png_test.rb b/test/units/compass_png_test.rb similarity index 97% rename from test/compass_png_test.rb rename to test/units/compass_png_test.rb index b8fd70c8..2a71e198 100644 --- a/test/compass_png_test.rb +++ b/test/units/compass_png_test.rb @@ -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 diff --git a/test/configuration_test.rb b/test/units/configuration_test.rb similarity index 100% rename from test/configuration_test.rb rename to test/units/configuration_test.rb diff --git a/test/sass_extensions_test.rb b/test/units/sass_extensions_test.rb similarity index 100% rename from test/sass_extensions_test.rb rename to test/units/sass_extensions_test.rb diff --git a/test/sprites/base_test.rb b/test/units/sprites/base_test.rb similarity index 72% rename from test/sprites/base_test.rb rename to test/units/sprites/base_test.rb index a5c0adef..e79a11c3 100644 --- a/test/sprites/base_test.rb +++ b/test/units/sprites/base_test.rb @@ -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 \ No newline at end of file diff --git a/test/sprites/image_test.rb b/test/units/sprites/image_test.rb similarity index 98% rename from test/sprites/image_test.rb rename to test/units/sprites/image_test.rb index 93435ad8..01609932 100644 --- a/test/sprites/image_test.rb +++ b/test/units/sprites/image_test.rb @@ -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'