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.
@@ -2,4 +2,4 @@
2
2
  :major: 0
3
3
  :minor: 11
4
4
  :state: beta
5
- :build: 3
5
+ :build: 4
@@ -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 `preserves-3d`
202
- // browsers default to `flat`, mixin defaults to `preserves-3d`
203
- @mixin transform-style($style: preserves-3d) {
204
- @include experimental(perspective-origin, $style,
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
  }
@@ -1,7 +1,7 @@
1
1
  module Compass
2
2
  end
3
3
 
4
- %w(dependencies util browser_support sass_extensions core_ext version errors quick_cache).each do |lib|
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
- module_function :base_directory, :lib_directory
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 sprites).each do |lib|
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 sass_dir.blank?
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 css_dir.blank?
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 use_sudo.blank?
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 css_framework.blank?
74
+ compass_command << "--using #{css_framework} " unless Compass::Util.blank?(css_framework)
75
75
 
76
76
  # integrate it!
77
77
  run "haml --rails ."
@@ -37,7 +37,8 @@ module Compass
37
37
  :line_comments,
38
38
  :color_output,
39
39
  :preferred_syntax,
40
- :disable_warnings
40
+ :disable_warnings,
41
+ :sprite_engine
41
42
  ].flatten
42
43
 
43
44
  end
@@ -128,6 +128,11 @@ module Compass
128
128
  def default_preferred_syntax
129
129
  :scss
130
130
  end
131
+
132
+ def default_sprite_engine
133
+ :chunky_png
134
+ end
135
+
131
136
  # helper functions
132
137
 
133
138
  def http_join(*segments)
@@ -65,11 +65,14 @@ module Compass
65
65
  Sass::Plugin.add_template_location sass_dir, css_dir
66
66
  end
67
67
  end
68
- Sass::Plugin.on_updating_stylesheet do |sass_file, css_file|
69
- Compass.configuration.run_callback(:stylesheet_saved, css_file)
70
- end
71
- Sass::Plugin.on_compilation_error do |e, filename, css|
72
- Compass.configuration.run_callback(:stylesheet_error, filename, e.message)
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
- if File.exists?(configuration.extensions_path)
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
@@ -3,3 +3,4 @@ end
3
3
 
4
4
  require 'compass/sass_extensions/functions'
5
5
  require 'compass/sass_extensions/monkey_patches'
6
+ require 'compass/sass_extensions/sprites'
@@ -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
- class SpriteMap < Sass::Script::Literal
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
- SpriteMap.from_uri(glob, self, kwargs)
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?(SpriteMap)
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?(SpriteMap)
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?(SpriteMap)
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[:relative_file])
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?(SpriteMap)
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?(SpriteMap)
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[:left]
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[:top]
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