css_sprite 1.3.4 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -4,15 +4,30 @@ automatically css sprite.
4
4
 
5
5
  *************************************************************************
6
6
 
7
- h2. Notice
7
+ h2. What css_sprite does?
8
8
 
9
- I have rewritten the plugin. Please check out the gem version >= 1.3.0
9
+ css sprite generates css_sprite image and css files automatically for you follow the conventions as follows.
10
+
11
+ | images under css_sprite directory | class name in css_sprite css |
12
+ | twitter_icon.png | .twitter_icon |
13
+ | facebook_icon.png | .facebook_icon |
14
+ | hotmail-logo.png | .hotmail-logo |
15
+ | gmail-logo.png | .gmail-logo |
16
+ | icons/twitter_icon.png | .icons .twitter_icon |
17
+ | widget/icons/twitter_icon.png | .widget .icons .twitter_icon |
18
+ | twitter_icon_hover.png | .twitter_icon:hover |
19
+ | twitter-icon-hover.png | .twitter-icon:hover |
20
+
21
+ css_sprite directory is the directory whose name is "css_sprite" or "css_sprite" suffixed under public/images directory.
22
+ css_sprite image is the image file automatically generated under public/images directory.
23
+ css_sprite css is the css file automatically generated under public/stylesheets directory.
10
24
 
11
25
  **************************************************************************
12
26
 
13
27
  h2. Install
14
28
 
15
29
  css_sprite depends on the <code>rmagick</code> gem, please make sure RMagick is successfully installed on your system.
30
+ css_sprite also depends on the <code>optipng</code> tool as default image optimization, but you can use any other image optimization tool, check the Configuration section. If you use the default optipng tool, please make sure it is successfully installed on your system.
16
31
 
17
32
  install css_sprite as a gem:
18
33
  <pre><code>sudo gem install css_sprite</code></pre>
@@ -50,9 +65,19 @@ Or you can just do the css sprite manually by <code>rake css_sprite:build</code>
50
65
 
51
66
  h2. Configuration
52
67
 
53
- There is no need to create any configuration by default. If you want to use sass or you want to define common styles for some related classes, you need to define <code>config/css_sprite.yml</code> file.
68
+ There is no need to create any configuration by default. If you want some customizations as follows, you need to define <code>config/css_sprite.yml</code> file.
69
+
70
+ h3. Sass
71
+
72
+ <pre><code>engine:sass</code></pre>
73
+
74
+ h3. Image Optimization
75
+
76
+ css_sprite use *optipng* with optimization level 2 to optimize the auto generated css_sprite image. You can change it to any image optimization command.
77
+
78
+ <pre><code>optimization: optipng -o 7</code></pre>
54
79
 
55
- h3. Examples
80
+ h3. Customization styles
56
81
 
57
82
  * For css
58
83
  <pre><code>
@@ -96,7 +121,9 @@ if your image filename is icon suffixed (e.g. twitter_icon.png), the correspondi
96
121
 
97
122
  h2. Best Practices
98
123
 
99
- I have written a post "css sprite best practices":http://www.huangzhimin.com/entries/190-css-sprite-best-practices to introduce the idea that the css_sprite gem follows.
124
+ I have written posts "css sprite best practices" to introduce the idea that the css_sprite gem follows.
125
+ "english version":http://www.huangzhimin.com/entries/190-css-sprite-best-practices
126
+ "chinese version":http://www.huangzhimin.com/entries/189-css-sprite-best-practices
100
127
 
101
128
  **************************************************************************
102
129
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.4
1
+ 1.4.0
data/css_sprite.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{css_sprite}
8
- s.version = "1.3.4"
8
+ s.version = "1.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Richard Huang"]
12
- s.date = %q{2010-04-07}
12
+ s.date = %q{2010-04-08}
13
13
  s.description = %q{css_sprite is a rails plugin/gem to generate css sprite image automatically.}
14
14
  s.email = %q{flyerhzm@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
30
30
  "spec/public/images/css_sprite/gmail_logo.png",
31
31
  "spec/public/images/css_sprite/hotmail_logo.png",
32
32
  "spec/public/images/css_sprite/icons/facebook_icon.png",
33
+ "spec/public/images/css_sprite/icons/facebook_icon_hover.png",
33
34
  "spec/public/images/css_sprite/icons/twitter_icon.png",
34
35
  "spec/public/images/css_sprite/not_image.txt",
35
36
  "spec/spec.opts",
@@ -8,7 +8,6 @@ class Sprite
8
8
  def initialize(options={})
9
9
  @image_path = File.expand_path(File.join(Rails.root, 'public/images'))
10
10
  @stylesheet_path = File.expand_path(File.join(Rails.root, 'public/stylesheets'))
11
- @todo = {}
12
11
 
13
12
  if File.exist?(File.join(Rails.root, 'config/css_sprite.yml'))
14
13
  @config = YAML::load_file(File.join(Rails.root, 'config/css_sprite.yml'))
@@ -19,18 +18,20 @@ class Sprite
19
18
 
20
19
  def build
21
20
  directories = css_sprite_directories
22
- directories.each { |directory| output_image(directory) }
23
- output_stylesheet
21
+ directories.each { |directory| execute(directory) }
24
22
  end
25
23
 
26
24
  def check
27
25
  directories = css_sprite_directories
28
- directories.each do |directory|
29
- if expire?(directory)
30
- output_image(directory)
31
- end
26
+ directories.each { |directory| execute(directory) if expire?(directory) }
27
+ end
28
+
29
+ def execute(directory)
30
+ results = output_image(directory)
31
+ unless results.empty?
32
+ optimize_image(directory)
33
+ output_stylesheet(directory, results)
32
34
  end
33
- output_stylesheet
34
35
  end
35
36
 
36
37
  def expire?(directory)
@@ -42,11 +43,11 @@ class Sprite
42
43
  !File.exist?(stylesheet_path) or File.new(directory).mtime > File.new(stylesheet_path).mtime
43
44
  end
44
45
 
45
- def output_stylesheet
46
+ def output_stylesheet(directory, results)
46
47
  if sass?
47
- output_sass
48
+ output_sass(directory, results)
48
49
  else
49
- output_css
50
+ output_css(directory, results)
50
51
  end
51
52
  end
52
53
 
@@ -76,74 +77,74 @@ class Sprite
76
77
  results << image_properties(source_image, directory).merge(:x => x, :y => y)
77
78
  dest_image = composite_images(dest_image, source_image, x, y)
78
79
  end
79
- dest_image.image_type = Magick::PaletteMatteType
80
80
  dest_image.write(dest_image_path)
81
81
  end
82
- @todo[directory] = results
82
+ results
83
+ end
84
+
85
+ def optimize_image(directory)
86
+ dest_image_path = dest_image_path(directory)
87
+ @config['optimization'] ? system("#{@config['optimization']} #{dest_image_path}") : system("optipng -quiet #{dest_image_path}")
83
88
  end
84
89
 
85
- def output_css
86
- @todo.each do |directory, results|
87
- unless results.empty?
88
- dest_image_name = dest_image_name(directory)
89
- dest_css_path = dest_css_path(directory)
90
- dest_image_time = File.new(dest_image_path(directory)).mtime
91
- File.open(dest_css_path, 'w') do |f|
92
- if @config['suffix']
93
- @config['suffix'].each do |key, value|
94
- cns = class_names(results, :suffix => key)
95
- unless cns.empty?
96
- f.print cns.join(",\n")
97
- f.print " \{\n"
98
- f.print value.split("\n").collect { |text| " " + text }.join("\n")
99
- f.print "\}\n"
100
- end
90
+ def output_css(directory, results)
91
+ unless results.empty?
92
+ dest_image_name = dest_image_name(directory)
93
+ dest_css_path = dest_css_path(directory)
94
+ dest_image_time = File.new(dest_image_path(directory)).mtime
95
+ File.open(dest_css_path, 'w') do |f|
96
+ if @config['suffix']
97
+ @config['suffix'].each do |key, value|
98
+ cns = class_names(results, :suffix => key)
99
+ unless cns.empty?
100
+ f.print cns.join(",\n")
101
+ f.print " \{\n"
102
+ f.print value.split("\n").collect { |text| " " + text }.join("\n")
103
+ f.print "\}\n"
101
104
  end
102
105
  end
103
-
104
- f.print class_names(results).join(",\n")
105
- f.print " \{\n background: url('/images/#{dest_image_name}?#{dest_image_time.to_i}') no-repeat;\n\}\n"
106
+ end
106
107
 
107
- results.each do |result|
108
- f.print "#{class_name(result[:name])} \{"
109
- f.print " background-position: #{-result[:x]}px #{-result[:y]}px;"
110
- f.print " width: #{result[:width]}px;"
111
- f.print " height: #{result[:height]}px;"
112
- f.print " \}\n"
113
- end
108
+ f.print class_names(results).join(",\n")
109
+ f.print " \{\n background: url('/images/#{dest_image_name}?#{dest_image_time.to_i}') no-repeat;\n\}\n"
110
+
111
+ results.each do |result|
112
+ f.print "#{class_name(result[:name])} \{"
113
+ f.print " background-position: #{-result[:x]}px #{-result[:y]}px;"
114
+ f.print " width: #{result[:width]}px;"
115
+ f.print " height: #{result[:height]}px;"
116
+ f.print " \}\n"
114
117
  end
115
118
  end
116
119
  end
117
120
  end
118
121
 
119
- def output_sass
120
- @todo.each do |directory, results|
121
- unless results.empty?
122
- dest_image_name = dest_image_name(directory)
123
- dest_sass_path = dest_sass_path(directory)
124
- dest_image_time = File.new(dest_image_path(directory)).mtime
125
- File.open(dest_sass_path, 'w') do |f|
126
- if @config['suffix']
127
- @config['suffix'].each do |key, value|
128
- cns = class_names(results, :suffix => key)
129
- unless cns.empty?
130
- f.print cns.join(",\n")
131
- f.print "\n"
132
- f.print value.split("\n").collect { |text| " " + text }.join("\n")
133
- f.print "\n"
134
- end
122
+ def output_sass(directory, results)
123
+ unless results.empty?
124
+ dest_image_name = dest_image_name(directory)
125
+ dest_sass_path = dest_sass_path(directory)
126
+ dest_image_time = File.new(dest_image_path(directory)).mtime
127
+ File.open(dest_sass_path, 'w') do |f|
128
+ if @config['suffix']
129
+ @config['suffix'].each do |key, value|
130
+ cns = class_names(results, :suffix => key)
131
+ unless cns.empty?
132
+ f.print cns.join(",\n")
133
+ f.print "\n"
134
+ f.print value.split("\n").collect { |text| " " + text }.join("\n")
135
+ f.print "\n"
135
136
  end
136
137
  end
137
-
138
- f.print class_names(results).join(",\n")
139
- f.print " \n background: url('/images/#{dest_image_name}?#{dest_image_time.to_i}') no-repeat\n"
138
+ end
140
139
 
141
- results.each do |result|
142
- f.print "#{class_name(result[:name])}\n"
143
- f.print " background-position: #{-result[:x]}px #{-result[:y]}px\n"
144
- f.print " width: #{result[:width]}px\n"
145
- f.print " height: #{result[:height]}px\n"
146
- end
140
+ f.print class_names(results).join(",\n")
141
+ f.print " \n background: url('/images/#{dest_image_name}?#{dest_image_time.to_i}') no-repeat\n"
142
+
143
+ results.each do |result|
144
+ f.print "#{class_name(result[:name])}\n"
145
+ f.print " background-position: #{-result[:x]}px #{-result[:y]}px\n"
146
+ f.print " width: #{result[:width]}px\n"
147
+ f.print " height: #{result[:height]}px\n"
147
148
  end
148
149
  end
149
150
  end
@@ -160,7 +161,7 @@ class Sprite
160
161
  end
161
162
 
162
163
  def class_name(name)
163
- ".#{name.gsub('/', ' .')}"
164
+ ".#{name.gsub('/', ' .').sub(/[_-]hover$/, ':hover')}"
164
165
  end
165
166
 
166
167
  def all_images(directory)
@@ -12,7 +12,11 @@ describe Sprite do
12
12
  end
13
13
 
14
14
  it "should build css_sprite image and sass" do
15
- Sprite.new(:engine => :sass).build
15
+ Sprite.new('engine' => 'sass').build
16
+ end
17
+
18
+ it "should build another image optimization" do
19
+ Sprite.new('optimization' => "optipng -o 1").build
16
20
  end
17
21
  end
18
22
 
@@ -34,6 +38,7 @@ describe Sprite do
34
38
  it "should read all images from a directory" do
35
39
  expected_images = [File.join(IMAGE_PATH, 'css_sprite/icons/twitter_icon.png'),
36
40
  File.join(IMAGE_PATH, 'css_sprite/icons/facebook_icon.png'),
41
+ File.join(IMAGE_PATH, 'css_sprite/icons/facebook_icon_hover.png'),
37
42
  File.join(IMAGE_PATH, 'css_sprite/hotmail_logo.png'),
38
43
  File.join(IMAGE_PATH, 'css_sprite/gmail_logo.png')]
39
44
  actual_images = @sprite.all_images(File.join(IMAGE_PATH, 'css_sprite'))
@@ -63,6 +68,23 @@ describe Sprite do
63
68
  end
64
69
  end
65
70
 
71
+ describe "class_name" do
72
+ it "should get class_name with simple name" do
73
+ @sprite.class_name("twitter_icon").should == ".twitter_icon"
74
+ end
75
+
76
+ it "should get class_name with parent class" do
77
+ @sprite.class_name("icons/twitter_icon").should == ".icons .twitter_icon"
78
+ end
79
+
80
+ it "should get class_name with hover class" do
81
+ @sprite.class_name("icons/twitter_icon_hover").should == ".icons .twitter_icon:hover"
82
+ @sprite.class_name("icons/twitter-icon-hover").should == ".icons .twitter-icon:hover"
83
+ @sprite.class_name("twitter_hover_icon").should == ".twitter_hover_icon"
84
+ @sprite.class_name("twitter_hover_icon_hover").should == ".twitter_hover_icon:hover"
85
+ end
86
+ end
87
+
66
88
  describe "dest_image_path" do
67
89
  it "should get css_sprite image path for a directory" do
68
90
  @sprite.dest_image_path(File.join(IMAGE_PATH, 'css_sprite')).should == File.join(IMAGE_PATH, 'css_sprite.png')
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 1
7
- - 3
8
7
  - 4
9
- version: 1.3.4
8
+ - 0
9
+ version: 1.4.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Richard Huang
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-07 00:00:00 +08:00
17
+ date: 2010-04-08 00:00:00 +08:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -52,6 +52,7 @@ files:
52
52
  - spec/public/images/css_sprite/gmail_logo.png
53
53
  - spec/public/images/css_sprite/hotmail_logo.png
54
54
  - spec/public/images/css_sprite/icons/facebook_icon.png
55
+ - spec/public/images/css_sprite/icons/facebook_icon_hover.png
55
56
  - spec/public/images/css_sprite/icons/twitter_icon.png
56
57
  - spec/public/images/css_sprite/not_image.txt
57
58
  - spec/spec.opts