sass 3.1.0.alpha.212 → 3.1.0.alpha.214

Sign up to get free protection for your applications and to get access to all the features.
data/REVISION CHANGED
@@ -1 +1 @@
1
- ebf9e326dafba548aef36fe36945d97a9dd590d9
1
+ e18890b4746317cad3919e6461554eb0415b12fc
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.0.alpha.212
1
+ 3.1.0.alpha.214
@@ -12,4 +12,3 @@ end
12
12
  require 'sass/cache_stores/base'
13
13
  require 'sass/cache_stores/filesystem'
14
14
  require 'sass/cache_stores/memory'
15
- require 'sass/cache_stores/chain'
@@ -48,7 +48,7 @@ module Sass
48
48
  # @param sha [String] The checksum for the contents that are being stored.
49
49
  # @param obj [Object] The object to cache.
50
50
  def store(key, sha, root)
51
- _store(key, Sass::VERSION, sha, Marshal.dump(root))
51
+ _store(key, Sass::VERSION, sha, Sass::Util.dump(root))
52
52
  end
53
53
 
54
54
  # Retrieve a {Sass::Tree::RootNode}.
@@ -58,7 +58,7 @@ module Sass
58
58
  # @return [Object] The cached object.
59
59
  def retrieve(key, sha)
60
60
  contents = _retrieve(key, Sass::VERSION, sha)
61
- Marshal.load(contents) if contents
61
+ Sass::Util.load(contents) if contents
62
62
  rescue EOFError, TypeError, ArgumentError => e
63
63
  Sass::Util.sass_warn "Warning. Error encountered while reading cache #{path_to(key)}: #{e}"
64
64
  end
@@ -24,18 +24,22 @@ module Sass
24
24
  @contents = {}
25
25
  end
26
26
 
27
- # @see Base#retrieve
28
- def retrieve(key, sha)
27
+ # @see Base#_retrieve
28
+ def _retrieve(key, version, sha)
29
29
  if @contents.has_key?(key)
30
+ return unless @contents[key][:version] == version
30
31
  return unless @contents[key][:sha] == sha
31
- obj = @contents[key][:obj]
32
- obj.respond_to?(:deep_copy) ? obj.deep_copy : obj.dup
32
+ return @contents[key][:contents]
33
33
  end
34
34
  end
35
-
36
- # @see Base#store
37
- def store(key, sha, obj)
38
- @contents[key] = {:sha => sha, :obj => obj}
35
+
36
+ # @see Base#_store
37
+ def _store(key, version, sha, contents)
38
+ @contents[key] = {
39
+ :version => version,
40
+ :sha => sha,
41
+ :contents => contents
42
+ }
39
43
  end
40
44
 
41
45
  # Destructively clear the cache.
data/lib/sass/engine.rb CHANGED
@@ -164,8 +164,7 @@ module Sass
164
164
  # Tracks the original filename of the top-level Sass file
165
165
  options[:original_filename] = options[:original_filename] || options[:filename]
166
166
 
167
- options[:cache_store] ||= Sass::CacheStores::Chain.new(
168
- Sass::CacheStores::Memory.new, Sass::CacheStores::Filesystem.new(options[:cache_location]))
167
+ options[:cache_store] ||= Sass::CacheStores::Filesystem.new(options[:cache_location])
169
168
  # Support both, because the docs said one and the other actually worked
170
169
  # for quite a long time.
171
170
  options[:line_comments] ||= options[:line_numbers]
@@ -334,15 +333,7 @@ module Sass
334
333
  end
335
334
 
336
335
  root.options = @options
337
- if @options[:cache] && key && sha
338
- begin
339
- old_options = root.options
340
- root.options = {:importer => root.options[:importer]}
341
- @options[:cache_store].store(key, sha, root)
342
- ensure
343
- root.options = old_options
344
- end
345
- end
336
+ @options[:cache_store].store(key, sha, root) if @options[:cache] && key && sha
346
337
  root
347
338
  rescue SyntaxError => e
348
339
  e.modify_backtrace(:filename => @options[:filename], :line => @line)
@@ -93,12 +93,12 @@ module Sass::Script
93
93
  # \{#adjust adjust-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\]}
94
94
  # : Increase or decrease any of the components of a color.
95
95
  #
96
- # \{#scale_color scale-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\]}
97
- # : Fluidly scale one or more components of a color.
98
- #
99
96
  # \{#change_color change-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\]}
100
97
  # : Changes one or more properties of a color.
101
98
  #
99
+ # \{#scale_color scale-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\]}
100
+ # : Scales one or more properties of a color by a percentage value.
101
+ #
102
102
  # ## String Functions
103
103
  #
104
104
  # \{#unquote unquote($string)}
@@ -41,22 +41,23 @@ module Sass::Tree
41
41
  self.else.options = options if self.else
42
42
  end
43
43
 
44
- def _dump(f)
45
- Marshal.dump([self.expr, self.else])
46
- end
47
-
48
- def self._load(data)
49
- expr, else_ = Marshal.load(data)
50
- node = IfNode.new(expr)
51
- node.else = else_
52
- node
44
+ # @see Node#_around_dump
45
+ def _around_dump
46
+ old_else = @else
47
+ old_last_else = @last_else
48
+ @else = Sass::Util.dump(@else)
49
+ @last_else = (self == @last_else ? nil : Sass::Util.dump(@last_else))
50
+ super
51
+ ensure
52
+ @else = old_else
53
+ @last_else = old_last_else
53
54
  end
54
55
 
55
- # @see Node#deep_copy
56
- def deep_copy
57
- node = super
58
- node.else = self.else.deep_copy if self.else
59
- node
56
+ # @see Node#_after_load
57
+ def _after_load
58
+ super
59
+ @else = Sass::Util.load(@else)
60
+ @last_else = (@last_else ? Sass::Util.load(@last_else) : self)
60
61
  end
61
62
  end
62
63
  end
@@ -180,14 +180,29 @@ module Sass
180
180
  Sass::Tree::Visitors::Convert.visit(self, options, :scss)
181
181
  end
182
182
 
183
- # Return a deep clone of this node.
184
- # The child nodes are cloned, but options are not.
185
- #
186
- # @return [Node]
187
- def deep_copy
188
- node = dup
189
- node.children = children.map {|c| c.deep_copy}
190
- node
183
+ # Names of options that are saved when the node is serialized and cached.
184
+ SAVED_OPTIONS = [:importer]
185
+
186
+ # Ensures that only {SAVED_OPTIONS} get saved.
187
+ def _around_dump
188
+ old_options = @options
189
+ old_children = @children
190
+ @options = {}
191
+ SAVED_OPTIONS.each do |opt|
192
+ @options[opt] = old_options[opt]
193
+ end
194
+ @options = Sass::Util.dump(@options)
195
+ @children = Sass::Util.dump(@children)
196
+ yield
197
+ ensure
198
+ @options = old_options
199
+ @children = old_children
200
+ end
201
+
202
+ # Ensures that only {SAVED_OPTIONS} get saved.
203
+ def _after_load
204
+ @options = Sass::Util.load(@options)
205
+ @children = Sass::Util.load(@children)
191
206
  end
192
207
 
193
208
  protected
data/lib/sass/util.rb CHANGED
@@ -270,6 +270,47 @@ module Sass
270
270
  version_gt(v1, v2) || !version_gt(v2, v1)
271
271
  end
272
272
 
273
+ # A wrapper for `Marshal.dump` that calls `#_before_dump` on the object
274
+ # before dumping it, `#_after_dump` afterwards.
275
+ # It also calls `#_around_dump` and passes it a block in which the object is dumped.
276
+ #
277
+ # If any of these methods are undefined, they are not called.
278
+ #
279
+ # This will recursively call itself on members of arrays and hashes,
280
+ # but not of user-defined objects.
281
+ # This means that user-defined objects that need their members' `#_before_dump` etc. methods called
282
+ # must call `Haml::Util.dump` and `Haml::Util.load` manually on those members.
283
+ #
284
+ # @param obj [Object] The object to dump.
285
+ # @return [String] The dumped data.
286
+ def dump(obj)
287
+ obj._before_dump if obj.respond_to?(:_before_dump)
288
+ return convert_and_dump(obj) unless obj.respond_to?(:_around_dump)
289
+ res = nil
290
+ obj._around_dump {res = convert_and_dump(obj)}
291
+ res
292
+ ensure
293
+ obj._after_dump if obj.respond_to?(:_after_dump)
294
+ end
295
+
296
+ # A wrapper for `Marshal.load` that calls `#_after_load` on the object
297
+ # after loading it, if it's defined.
298
+ #
299
+ # @param data [String] The data to load.
300
+ # @return [Object] The loaded object.
301
+ def load(data)
302
+ obj = Marshal.load(data)
303
+
304
+ if obj.is_a?(Array)
305
+ obj = obj.map {|e| Sass::Util.load(e)}
306
+ elsif obj.is_a?(Hash)
307
+ obj = map_hash(obj) {|k, v| [Sass::Util.load(k), Sass::Util.load(v)]}
308
+ end
309
+
310
+ obj._after_load if obj.respond_to?(:_after_load)
311
+ obj
312
+ end
313
+
273
314
  # Throws a NotImplementedError for an abstract method.
274
315
  #
275
316
  # @param obj [Object] `self`
@@ -665,5 +706,14 @@ MSG
665
706
  return lcs_backtrace(c, x, y, i, j-1, &block) if c[i][j-1] > c[i-1][j]
666
707
  return lcs_backtrace(c, x, y, i-1, j, &block)
667
708
  end
709
+
710
+ def convert_and_dump(obj)
711
+ if obj.is_a?(Array)
712
+ obj = obj.map {|e| dump(e)}
713
+ elsif obj.is_a?(Hash)
714
+ obj = map_hash(obj) {|k, v| [dump(k), dump(v)]}
715
+ end
716
+ Marshal.dump(obj)
717
+ end
668
718
  end
669
719
  end
@@ -5,6 +5,8 @@ require File.dirname(__FILE__) + '/test_helper'
5
5
  class ImporterTest < Test::Unit::TestCase
6
6
 
7
7
  class FruitImporter < Sass::Importers::Base
8
+ attr_reader :cached
9
+
8
10
  def find(name, context = nil)
9
11
  if name =~ %r{fruits/(\w+)(\.s[ac]ss)?}
10
12
  fruit = $1
@@ -29,6 +31,13 @@ class ImporterTest < Test::Unit::TestCase
29
31
  def key(name, context)
30
32
  [self.class.name, name]
31
33
  end
34
+
35
+ def _around_dump
36
+ @cached = true
37
+ yield
38
+ ensure
39
+ @cached = false
40
+ end
32
41
  end
33
42
 
34
43
  # This class proves that you can override the extension scheme for importers
@@ -79,4 +88,17 @@ CSS
79
88
  ensure
80
89
  FileUtils.rm_rf(absolutize("tmp"))
81
90
  end
91
+
92
+ def test_caching_importer
93
+ source = "p\n foo: bar"
94
+ importer = FruitImporter.new
95
+ filename = filename_for_test
96
+ engine = Sass::Engine.new(source, :filename => filename, :importer => importer)
97
+ engine.to_tree # Trigger caching
98
+
99
+ sha = Digest::SHA1.hexdigest(source)
100
+ cache = engine.options[:cache_store]
101
+ cached_tree = cache.retrieve(cache.key(*importer.key(filename, engine.options)), sha)
102
+ assert cached_tree.options[:importer].cached, "Importer's _around_dump method should have been called"
103
+ end
82
104
  end
@@ -5,6 +5,19 @@ require 'pathname'
5
5
  class UtilTest < Test::Unit::TestCase
6
6
  include Sass::Util
7
7
 
8
+ class Dumpable
9
+ attr_reader :arr
10
+ def initialize; @arr = []; end
11
+ def _before_dump; @arr << :before; end
12
+ def _after_dump; @arr << :after; end
13
+ def _around_dump
14
+ @arr << :around_before
15
+ yield
16
+ @arr << :around_after
17
+ end
18
+ def _after_load; @arr << :loaded; end
19
+ end
20
+
8
21
  def test_scope
9
22
  assert(File.exist?(scope("Rakefile")))
10
23
  end
@@ -240,6 +253,14 @@ class UtilTest < Test::Unit::TestCase
240
253
  assert(!version_gt(v2, v1), "Expected #{v2} = #{v1}")
241
254
  end
242
255
 
256
+ def test_dump_and_load
257
+ obj = Dumpable.new
258
+ data = dump(obj)
259
+ assert_equal([:before, :around_before, :around_after, :after], obj.arr)
260
+ obj2 = load(data)
261
+ assert_equal([:before, :around_before, :loaded], obj2.arr)
262
+ end
263
+
243
264
  class FooBar
244
265
  def foo
245
266
  Sass::Util.abstract(self)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sass
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0.alpha.212
4
+ version: 3.1.0.alpha.214
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Weizenbaum
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2011-01-13 00:00:00 -05:00
14
+ date: 2010-12-31 00:00:00 -05:00
15
15
  default_executable:
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
@@ -63,7 +63,6 @@ files:
63
63
  - lib/sass/cache_stores/filesystem.rb
64
64
  - lib/sass/cache_stores/memory.rb
65
65
  - lib/sass/cache_stores/null.rb
66
- - lib/sass/cache_stores/chain.rb
67
66
  - lib/sass/plugin/configuration.rb
68
67
  - lib/sass/plugin/merb.rb
69
68
  - lib/sass/plugin/generic.rb
@@ -1,33 +0,0 @@
1
- module Sass
2
- module CacheStores
3
- # A meta-cache that chains multiple caches together.
4
- # Specifically:
5
- #
6
- # * All `#store`s are passed to all caches.
7
- # * `#retrieve`s are passed to each cache until one has a hit.
8
- # * When one cache has a hit, the value is `#store`d in all earlier caches.
9
- class Chain < Base
10
- # Create a new cache chaining the given caches.
11
- #
12
- # @param caches [Array<Sass::CacheStores::Base>] The caches to chain.
13
- def initialize(*caches)
14
- @caches = caches
15
- end
16
-
17
- # @see Base#store
18
- def store(key, sha, obj)
19
- @caches.each {|c| c.store(key, sha, obj)}
20
- end
21
-
22
- # @see Base#retrieve
23
- def retrieve(key, sha)
24
- @caches.each_with_index do |c, i|
25
- next unless obj = c.retrieve(key, sha)
26
- @caches[0...i].each {|c| c.store(key, sha, obj)}
27
- return obj
28
- end
29
- nil
30
- end
31
- end
32
- end
33
- end