compass 0.11.beta.3 → 0.11.beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION.yml +1 -1
- data/features/extensions.feature +7 -0
- data/frameworks/compass/stylesheets/compass/css3/_transform.scss +4 -4
- data/lib/compass.rb +6 -3
- data/lib/compass/app_integration/rails/templates/compass-install-rails.rb +4 -4
- data/lib/compass/configuration.rb +2 -1
- data/lib/compass/configuration/defaults.rb +5 -0
- data/lib/compass/configuration/helpers.rb +14 -6
- data/lib/compass/sass_extensions.rb +1 -0
- data/lib/compass/sass_extensions/functions/sprites.rb +10 -229
- data/lib/compass/sass_extensions/sprites.rb +14 -0
- data/lib/compass/sass_extensions/sprites/base.rb +183 -0
- data/lib/compass/sass_extensions/sprites/engines.rb +1 -0
- data/lib/compass/sass_extensions/sprites/engines/chunky_png_engine.rb +33 -0
- data/lib/compass/sass_extensions/sprites/image.rb +89 -0
- data/lib/compass/{sprites.rb → sass_extensions/sprites/sprite_map.rb} +46 -52
- data/lib/compass/sass_extensions/sprites/sprites.rb +26 -0
- data/lib/compass/util.rb +11 -0
- data/test/fixtures/stylesheets/compass/css/transform.css +2 -2
- data/test/test_case_helper.rb +1 -1
- metadata +11 -8
- data/examples/compass/saved_stylesheets/PIE.htc +0 -77
- data/examples/compass/src/sprites/_emblem.scss +0 -90
- data/examples/compass/src/sprites/_flag.scss +0 -44
- data/lib/compass/core_ext.rb +0 -14
data/VERSION.yml
CHANGED
data/features/extensions.feature
CHANGED
@@ -20,3 +20,10 @@ Feature: Extensions
|
|
20
20
|
When I run: compass frameworks
|
21
21
|
Then the list of frameworks includes "testing"
|
22
22
|
|
23
|
+
@listframeworks
|
24
|
+
Scenario: Shared extensions directory
|
25
|
+
Given I am using the existing project in test/fixtures/stylesheets/compass
|
26
|
+
And the "~/.compass/extensions" directory exists
|
27
|
+
And and I have a fake extension at ~/.compass/extensions/testing
|
28
|
+
When I run: compass frameworks
|
29
|
+
Then the list of frameworks includes "testing"
|
@@ -198,10 +198,10 @@ $default-skew-y : 5deg !default;
|
|
198
198
|
//
|
199
199
|
// @include transform-style( [ style ] )
|
200
200
|
//
|
201
|
-
// where `style` can be either `flat` or `
|
202
|
-
// browsers default to `flat`, mixin defaults to `
|
203
|
-
@mixin transform-style($style:
|
204
|
-
@include experimental(
|
201
|
+
// where `style` can be either `flat` or `preserve-3d`
|
202
|
+
// browsers default to `flat`, mixin defaults to `preserve-3d`
|
203
|
+
@mixin transform-style($style: preserve-3d) {
|
204
|
+
@include experimental(transform-style, $style,
|
205
205
|
not -moz, -webkit, not -o, not -ms, not -khtml, official
|
206
206
|
);
|
207
207
|
}
|
data/lib/compass.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Compass
|
2
2
|
end
|
3
3
|
|
4
|
-
%w(dependencies util browser_support sass_extensions
|
4
|
+
%w(dependencies util browser_support sass_extensions version errors quick_cache).each do |lib|
|
5
5
|
require "compass/#{lib}"
|
6
6
|
end
|
7
7
|
|
@@ -14,10 +14,13 @@ module Compass
|
|
14
14
|
def lib_directory
|
15
15
|
File.expand_path(File.join(File.dirname(__FILE__)))
|
16
16
|
end
|
17
|
-
|
17
|
+
def shared_extension_paths
|
18
|
+
[File.expand_path("~/.compass/extensions")]
|
19
|
+
end
|
20
|
+
module_function :base_directory, :lib_directory, :shared_extension_paths
|
18
21
|
extend QuickCache
|
19
22
|
end
|
20
23
|
|
21
|
-
%w(configuration frameworks app_integration actions compiler
|
24
|
+
%w(configuration frameworks app_integration actions compiler).each do |lib|
|
22
25
|
require "compass/#{lib}"
|
23
26
|
end
|
@@ -47,18 +47,18 @@ css_framework = ask("What CSS Framework install do you want to use with Compass?
|
|
47
47
|
|
48
48
|
# sass storage prompt
|
49
49
|
sass_dir = ask("Where would you like to keep your sass files within your project? (default: 'app/stylesheets')")
|
50
|
-
sass_dir = "app/stylesheets" if
|
50
|
+
sass_dir = "app/stylesheets" if Compass::Util.blank?(sass_dir)
|
51
51
|
|
52
52
|
# compiled css storage prompt
|
53
53
|
css_dir = ask("Where would you like Compass to store your compiled css files? (default: 'public/stylesheets/compiled')")
|
54
|
-
css_dir = "public/stylesheets/compiled" if
|
54
|
+
css_dir = "public/stylesheets/compiled" if Compass::Util.blank?(css_dir)
|
55
55
|
|
56
56
|
# use sudo for gem commands?
|
57
57
|
use_sudo = nil
|
58
58
|
if sudo_is_an_option? # dont give them the option if they are on a system that can't use sudo (aka windows)
|
59
59
|
use_sudo = yes?("Use sudo for the gem commands? (the default for your system is #{sudo_is_an_option? ? 'yes' : 'no'})")
|
60
60
|
end
|
61
|
-
use_sudo = sudo_is_an_option? if
|
61
|
+
use_sudo = sudo_is_an_option? if Compass::Util.blank?(use_sudo)
|
62
62
|
|
63
63
|
# define dependencies
|
64
64
|
gem "haml", :version => ">=3.0.0"
|
@@ -71,7 +71,7 @@ rake "gems:unpack GEM=compass --trace"
|
|
71
71
|
|
72
72
|
# build out compass command
|
73
73
|
compass_command = "compass init rails . --css-dir=#{css_dir} --sass-dir=#{sass_dir} "
|
74
|
-
compass_command << "--using #{css_framework} " unless
|
74
|
+
compass_command << "--using #{css_framework} " unless Compass::Util.blank?(css_framework)
|
75
75
|
|
76
76
|
# integrate it!
|
77
77
|
run "haml --rails ."
|
@@ -65,11 +65,14 @@ module Compass
|
|
65
65
|
Sass::Plugin.add_template_location sass_dir, css_dir
|
66
66
|
end
|
67
67
|
end
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
68
|
+
unless defined?(CallbacksSetup)
|
69
|
+
Sass::Plugin.on_updating_stylesheet do |sass_file, css_file|
|
70
|
+
Compass.configuration.run_callback(:stylesheet_saved, css_file)
|
71
|
+
end
|
72
|
+
Sass::Plugin.on_compilation_error do |e, filename, css|
|
73
|
+
Compass.configuration.run_callback(:stylesheet_error, filename, e.message)
|
74
|
+
end
|
75
|
+
const_set('CallbacksSetup', true)
|
73
76
|
end
|
74
77
|
end
|
75
78
|
|
@@ -98,7 +101,12 @@ module Compass
|
|
98
101
|
end
|
99
102
|
|
100
103
|
def discover_extensions!
|
101
|
-
|
104
|
+
Compass.shared_extension_paths.each do |extensions_path|
|
105
|
+
if File.directory?(extensions_path)
|
106
|
+
Compass::Frameworks.discover(extensions_path)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
if File.directory?(configuration.extensions_path)
|
102
110
|
Compass::Frameworks.discover(configuration.extensions_path)
|
103
111
|
end
|
104
112
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'digest/md5'
|
2
|
-
|
3
1
|
module Compass::SassExtensions::Functions::Sprites
|
4
2
|
ZERO = Sass::Script::Number::new(0)
|
5
3
|
|
@@ -12,224 +10,7 @@ module Compass::SassExtensions::Functions::Sprites
|
|
12
10
|
end
|
13
11
|
end
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
# Changing this string will invalidate all previously generated sprite images.
|
18
|
-
# We should do so only when the packing algorithm changes
|
19
|
-
SPRITE_VERSION = "1"
|
20
|
-
|
21
|
-
attr_accessor :image_names, :path, :name, :options
|
22
|
-
attr_accessor :images, :width, :height
|
23
|
-
|
24
|
-
def self.from_uri(uri, context, kwargs)
|
25
|
-
path, name = Compass::Sprites.path_and_name(uri.value)
|
26
|
-
sprites = Compass::Sprites.discover_sprites(uri.value).map do |sprite|
|
27
|
-
sprite.gsub(Compass.configuration.images_path+"/", "")
|
28
|
-
end
|
29
|
-
new(sprites, path, name, context, kwargs)
|
30
|
-
end
|
31
|
-
|
32
|
-
def initialize(image_names, path, name, context, options)
|
33
|
-
@image_names, @path, @name, @options = image_names, path, name, options
|
34
|
-
@images = nil
|
35
|
-
@width = nil
|
36
|
-
@height = nil
|
37
|
-
@evaluation_context = context
|
38
|
-
validate!
|
39
|
-
compute_image_metadata!
|
40
|
-
end
|
41
|
-
|
42
|
-
def sprite_names
|
43
|
-
image_names.map{|f| Compass::Sprites.sprite_name(f) }
|
44
|
-
end
|
45
|
-
|
46
|
-
def validate!
|
47
|
-
for sprite_name in sprite_names
|
48
|
-
unless sprite_name =~ /\A#{Sass::SCSS::RX::IDENT}\Z/
|
49
|
-
raise Sass::SyntaxError, "#{sprite_name} must be a legal css identifier"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Calculates the overal image dimensions
|
55
|
-
# collects image sizes and input parameters for each sprite
|
56
|
-
def compute_image_metadata!
|
57
|
-
@images = []
|
58
|
-
@width = 0
|
59
|
-
image_names.each do |relative_file|
|
60
|
-
file = File.join(Compass.configuration.images_path, relative_file)
|
61
|
-
width, height = Compass::SassExtensions::Functions::ImageSize::ImageProperties.new(file).size
|
62
|
-
sprite_name = Compass::Sprites.sprite_name(relative_file)
|
63
|
-
position = position_for(sprite_name)
|
64
|
-
offset = (position.unitless? || position.unit_str == "px") ? position.value : 0
|
65
|
-
@images << {
|
66
|
-
:name => sprite_name,
|
67
|
-
:file => file,
|
68
|
-
:relative_file => relative_file,
|
69
|
-
:height => height,
|
70
|
-
:width => width,
|
71
|
-
:repeat => repeat_for(sprite_name),
|
72
|
-
:spacing => spacing_for(sprite_name),
|
73
|
-
:position => position,
|
74
|
-
:digest => Digest::MD5.file(file).hexdigest
|
75
|
-
}
|
76
|
-
@width = [@width, width + offset].max
|
77
|
-
end
|
78
|
-
@images.each_with_index do |image, index|
|
79
|
-
if index == 0
|
80
|
-
image[:top] = 0
|
81
|
-
else
|
82
|
-
last_image = @images[index-1]
|
83
|
-
image[:top] = last_image[:top] + last_image[:height] + [image[:spacing], last_image[:spacing]].max
|
84
|
-
end
|
85
|
-
if image[:position].unit_str == "%"
|
86
|
-
image[:left] = (@width - image[:width]) * (image[:position].value / 100)
|
87
|
-
else
|
88
|
-
image[:left] = image[:position].value
|
89
|
-
end
|
90
|
-
end
|
91
|
-
@height = @images.last[:top] + @images.last[:height]
|
92
|
-
end
|
93
|
-
|
94
|
-
def position_for(name)
|
95
|
-
options.get_var("#{name}-position") || options.get_var("position") || Sass::Script::Number.new(0, ["px"])
|
96
|
-
end
|
97
|
-
|
98
|
-
def repeat_for(name)
|
99
|
-
if (var = options.get_var("#{name}-repeat"))
|
100
|
-
var.value
|
101
|
-
elsif (var = options.get_var("repeat"))
|
102
|
-
var.value
|
103
|
-
else
|
104
|
-
"no-repeat"
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def spacing_for(name)
|
109
|
-
(options.get_var("#{name}-spacing") ||
|
110
|
-
options.get_var("spacing") ||
|
111
|
-
ZERO).value
|
112
|
-
end
|
113
|
-
|
114
|
-
def image_for(name)
|
115
|
-
@images.detect{|img| img[:name] == name}
|
116
|
-
end
|
117
|
-
|
118
|
-
# Calculate the size of the sprite
|
119
|
-
def size
|
120
|
-
[width, height]
|
121
|
-
end
|
122
|
-
|
123
|
-
# Generate a sprite image if necessary
|
124
|
-
def generate
|
125
|
-
if generation_required?
|
126
|
-
sprite_data = construct_sprite
|
127
|
-
save!(sprite_data)
|
128
|
-
Compass.configuration.run_callback(:sprite_generated, sprite_data)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def generation_required?
|
133
|
-
!File.exists?(filename) || outdated?
|
134
|
-
end
|
135
|
-
|
136
|
-
def require_png_library!
|
137
|
-
begin
|
138
|
-
require 'oily_png'
|
139
|
-
rescue LoadError
|
140
|
-
require 'chunky_png'
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
# Returns a PNG object
|
145
|
-
def construct_sprite
|
146
|
-
require_png_library!
|
147
|
-
output_png = ChunkyPNG::Image.new(width, height, ChunkyPNG::Color::TRANSPARENT)
|
148
|
-
images.each do |image|
|
149
|
-
input_png = ChunkyPNG::Image.from_file(image[:file])
|
150
|
-
if image[:repeat] == "no-repeat"
|
151
|
-
output_png.replace input_png, image[:left], image[:top]
|
152
|
-
else
|
153
|
-
x = image[:left] - (image[:left] / image[:width]).ceil * image[:width]
|
154
|
-
while x < width do
|
155
|
-
output_png.replace input_png, x, image[:top]
|
156
|
-
x += image[:width]
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
output_png
|
161
|
-
end
|
162
|
-
|
163
|
-
# The on-the-disk filename of the sprite
|
164
|
-
def filename
|
165
|
-
File.join(Compass.configuration.images_path, "#{path}-#{uniqueness_hash}.png")
|
166
|
-
end
|
167
|
-
|
168
|
-
def uniqueness_hash
|
169
|
-
@uniqueness_hash ||= begin
|
170
|
-
sum = Digest::MD5.new
|
171
|
-
sum << SPRITE_VERSION
|
172
|
-
sum << path
|
173
|
-
images.each do |image|
|
174
|
-
[:relative_file, :height, :width, :repeat, :spacing, :position, :digest].each do |attr|
|
175
|
-
sum << image[attr].to_s
|
176
|
-
end
|
177
|
-
end
|
178
|
-
sum.hexdigest[0...10]
|
179
|
-
end
|
180
|
-
@uniqueness_hash
|
181
|
-
end
|
182
|
-
|
183
|
-
# saves the sprite for later retrieval
|
184
|
-
def save!(output_png)
|
185
|
-
saved = output_png.save filename
|
186
|
-
Compass.configuration.run_callback(:sprite_saved, filename)
|
187
|
-
saved
|
188
|
-
end
|
189
|
-
|
190
|
-
# All the full-path filenames involved in this sprite
|
191
|
-
def image_filenames
|
192
|
-
image_names.map do |image_name|
|
193
|
-
File.join(Compass.configuration.images_path, image_name)
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
# Checks whether this sprite is outdated
|
198
|
-
def outdated?
|
199
|
-
last_update = self.mtime
|
200
|
-
image_filenames.each do |image|
|
201
|
-
return true if File.mtime(image) > last_update
|
202
|
-
end
|
203
|
-
false
|
204
|
-
end
|
205
|
-
|
206
|
-
def mtime
|
207
|
-
File.mtime(filename)
|
208
|
-
end
|
209
|
-
|
210
|
-
def inspect
|
211
|
-
to_s
|
212
|
-
end
|
213
|
-
|
214
|
-
def to_s(options = self.options)
|
215
|
-
sprite_url(self).value
|
216
|
-
end
|
217
|
-
|
218
|
-
def respond_to?(meth)
|
219
|
-
super || @evaluation_context.respond_to?(meth)
|
220
|
-
end
|
221
|
-
|
222
|
-
def method_missing(meth, *args, &block)
|
223
|
-
if @evaluation_context.respond_to?(meth)
|
224
|
-
@evaluation_context.send(meth, *args, &block)
|
225
|
-
else
|
226
|
-
super
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
end
|
231
|
-
|
232
|
-
# Creates a SpriteMap object. A sprite map, when used in a property is the same
|
13
|
+
# Creates a Compass::SassExtensions::Sprites::Base object. A sprite map, when used in a property is the same
|
233
14
|
# as calling sprite-url. So the following background properties are equivalent:
|
234
15
|
#
|
235
16
|
# $icons: sprite-map("icons/*.png");
|
@@ -240,7 +21,7 @@ module Compass::SassExtensions::Functions::Sprites
|
|
240
21
|
# the first time it is converted to a url. Simply constructing it has no side-effects.
|
241
22
|
def sprite_map(glob, kwargs = {})
|
242
23
|
kwargs.extend VariableReader
|
243
|
-
|
24
|
+
Compass::SassExtensions::Sprites::Base.from_uri(glob, self, kwargs)
|
244
25
|
end
|
245
26
|
Sass::Script::Functions.declare :sprite_map, [:glob], :var_kwargs => true
|
246
27
|
|
@@ -253,7 +34,7 @@ module Compass::SassExtensions::Functions::Sprites
|
|
253
34
|
#
|
254
35
|
# background: url('/images/icons.png?12345678') 0 -24px no-repeat;
|
255
36
|
def sprite(map, sprite, offset_x = ZERO, offset_y = ZERO)
|
256
|
-
unless map.is_a?(
|
37
|
+
unless map.is_a?(Compass::SassExtensions::Sprites::Base)
|
257
38
|
missing_sprite!("sprite")
|
258
39
|
end
|
259
40
|
unless sprite.is_a?(Sass::Script::String)
|
@@ -270,7 +51,7 @@ module Compass::SassExtensions::Functions::Sprites
|
|
270
51
|
# Returns the name of a sprite map
|
271
52
|
# The name is derived from the folder than contains the sprites.
|
272
53
|
def sprite_map_name(map)
|
273
|
-
unless map.is_a?(
|
54
|
+
unless map.is_a?(Compass::SassExtensions::Sprites::Base)
|
274
55
|
missing_sprite!("sprite-map-name")
|
275
56
|
end
|
276
57
|
Sass::Script::String.new(map.name)
|
@@ -279,11 +60,11 @@ module Compass::SassExtensions::Functions::Sprites
|
|
279
60
|
|
280
61
|
# Returns the path to the original image file for the sprite with the given name
|
281
62
|
def sprite_file(map, sprite)
|
282
|
-
unless map.is_a?(
|
63
|
+
unless map.is_a?(Compass::SassExtensions::Sprites::Base)
|
283
64
|
missing_sprite!("sprite-file")
|
284
65
|
end
|
285
66
|
if image = map.image_for(sprite.value)
|
286
|
-
Sass::Script::String.new(image
|
67
|
+
Sass::Script::String.new(image.relative_file)
|
287
68
|
else
|
288
69
|
missing_image!(map, sprite)
|
289
70
|
end
|
@@ -292,7 +73,7 @@ module Compass::SassExtensions::Functions::Sprites
|
|
292
73
|
|
293
74
|
# Returns a url to the sprite image.
|
294
75
|
def sprite_url(map)
|
295
|
-
unless map.is_a?(
|
76
|
+
unless map.is_a?(Compass::SassExtensions::Sprites::Base)
|
296
77
|
missing_sprite!("sprite-url")
|
297
78
|
end
|
298
79
|
map.generate
|
@@ -322,7 +103,7 @@ module Compass::SassExtensions::Functions::Sprites
|
|
322
103
|
#
|
323
104
|
# background-position: 3px -36px;
|
324
105
|
def sprite_position(map, sprite = nil, offset_x = ZERO, offset_y = ZERO)
|
325
|
-
unless map.is_a?(
|
106
|
+
unless map.is_a?(Compass::SassExtensions::Sprites::Base)
|
326
107
|
missing_sprite!("sprite-position")
|
327
108
|
end
|
328
109
|
unless sprite && sprite.is_a?(Sass::Script::String)
|
@@ -335,10 +116,10 @@ module Compass::SassExtensions::Functions::Sprites
|
|
335
116
|
if offset_x.unit_str == "%"
|
336
117
|
x = offset_x # CE: Shouldn't this be a percentage of the total width?
|
337
118
|
else
|
338
|
-
x = offset_x.value - image
|
119
|
+
x = offset_x.value - image.left
|
339
120
|
x = Sass::Script::Number.new(x, x == 0 ? [] : ["px"])
|
340
121
|
end
|
341
|
-
y = offset_y.value - image
|
122
|
+
y = offset_y.value - image.top
|
342
123
|
y = Sass::Script::Number.new(y, y == 0 ? [] : ["px"])
|
343
124
|
Sass::Script::List.new([x, y],:space)
|
344
125
|
end
|