jammit 0.1.0 → 0.1.1

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/Rakefile CHANGED
@@ -5,12 +5,14 @@ task :test do
5
5
  $LOAD_PATH.unshift(File.expand_path('test'))
6
6
  require 'redgreen' if Gem.available?('redgreen')
7
7
  require 'test/unit'
8
- Dir['test/**/test_*.rb'].each {|test| require test }
8
+ Dir.chdir('test')
9
+ Dir['./**/test_*.rb'].each {|test| require test }
9
10
  end
10
11
 
11
12
  desc 'Generate YARD Documentation'
12
13
  task :doc do
13
14
  sh "mv README TEMPME"
15
+ sh "rm -rf doc"
14
16
  sh "yardoc"
15
17
  sh "mv TEMPME README"
16
18
  end
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'jammit'
3
- s.version = '0.1.0' # Keep version in sync with jammit.rb
4
- s.date = '2009-11-06'
3
+ s.version = '0.1.1' # Keep version in sync with jammit.rb
4
+ s.date = '2009-11-16'
5
5
 
6
6
  s.homepage = "http://documentcloud.github.com/jammit/"
7
7
  s.summary = "Industrial Strength Asset Packaging for Rails"
@@ -4,7 +4,7 @@ $LOAD_PATH.push File.expand_path(File.dirname(__FILE__))
4
4
  # to all of the configuration options.
5
5
  module Jammit
6
6
 
7
- VERSION = "0.1.0"
7
+ VERSION = "0.1.1"
8
8
 
9
9
  ROOT = File.expand_path(File.dirname(__FILE__) + '/..')
10
10
 
@@ -96,6 +96,7 @@ end
96
96
  # Standard Library Dependencies:
97
97
  require 'zlib'
98
98
  require 'base64'
99
+ require 'pathname'
99
100
  require 'fileutils'
100
101
 
101
102
  # Gem Dependencies:
@@ -17,7 +17,8 @@ module Jammit
17
17
  }
18
18
 
19
19
  # Detect all image URLs that are inside of an "embed" folder.
20
- IMAGE_DETECTOR = /url\(['"]?(\/[^\s)]*embed\/[^\s)]+\.(png|jpg|jpeg|gif|tif|tiff))['"]?\)/
20
+ IMAGE_DETECTOR = /url\(['"]?([^\s)]*embed\/[^\s)]+\.(png|jpg|jpeg|gif|tif|tiff))['"]?\)/
21
+ IMAGE_REPLACER = /url\(__EMBED__([^\s)]+)\)/
21
22
 
22
23
  # MHTML file constants.
23
24
  MHTML_START = "/*\r\nContent-Type: multipart/related; boundary=\"JAMMIT_MHTML_SEPARATOR\"\r\n\r\n"
@@ -45,12 +46,11 @@ module Jammit
45
46
  # :datauri or :mhtml variant, post-processes the result to embed
46
47
  # referenced images.
47
48
  def compress_css(paths, variant=nil, asset_url=nil)
48
- compressed_css = @yui_css.compress(concatenate(paths))
49
- case variant
50
- when nil then compressed_css
51
- when :datauri then with_data_uris(compressed_css)
52
- when :mhtml then with_mhtml(compressed_css, asset_url)
53
- end
49
+ return @yui_css.compress(concatenate(paths)) if variant.nil?
50
+ compressed_css = @yui_css.compress(concatenate_and_tag_images(paths))
51
+ return with_data_uris(compressed_css) if variant == :datauri
52
+ return with_mhtml(compressed_css, asset_url) if variant == :mhtml
53
+ raise PackageNotFound, "\"#{variant}\" is not a valid stylesheet variant"
54
54
  end
55
55
 
56
56
  # Compiles a single JST file by writing out a javascript that adds
@@ -71,12 +71,25 @@ module Jammit
71
71
 
72
72
  private
73
73
 
74
+ # In order to support embedded images from relative paths, we need to
75
+ # expand the paths before contatenating the CSS together and losing the
76
+ # location of the original stylesheet path. Validate the images while we're
77
+ # at it.
78
+ def concatenate_and_tag_images(paths)
79
+ stylesheets = [paths].flatten.map do |css_path|
80
+ File.read(css_path).gsub(IMAGE_DETECTOR) do |url|
81
+ image_path = public_path($1, css_path)
82
+ valid_image(image_path) ? "url(__EMBED__#{image_path})" : url
83
+ end
84
+ end
85
+ stylesheets.join("\n")
86
+ end
87
+
74
88
  # Re-write all enabled image URLs in a stylesheet with their corresponding
75
89
  # Data-URI Base-64 encoded image contents.
76
90
  def with_data_uris(css)
77
- css.gsub(IMAGE_DETECTOR) do |url|
78
- image_path = "public#{$1}"
79
- valid_image(image_path) ? "url(\"data:#{mime_type(image_path)};base64,#{encoded_contents(image_path)}\")" : url
91
+ css.gsub(IMAGE_REPLACER) do |url|
92
+ "url(\"data:#{mime_type($1)};base64,#{encoded_contents($1)}\")"
80
93
  end
81
94
  end
82
95
 
@@ -84,25 +97,30 @@ module Jammit
84
97
  # The newlines ("\r\n") in the following method are critical. Without them
85
98
  # your MHTML will look identical, but won't work.
86
99
  def with_mhtml(css, asset_url)
87
- paths = {}
88
- css = css.gsub(IMAGE_DETECTOR) do |url|
89
- image_path = "public#{$1}"
90
- valid = valid_image(image_path)
91
- paths[$1] ||= image_path if valid
92
- valid ? "url(mhtml:#{asset_url}!#{$1})" : url
100
+ paths, index = {}, 0
101
+ css = css.gsub(IMAGE_REPLACER) do |url|
102
+ i = paths[$1] ||= "#{index += 1}-#{File.basename($1)}"
103
+ "url(mhtml:#{asset_url}!#{i})"
93
104
  end
94
- mhtml = paths.map do |identifier, path|
105
+ mhtml = paths.map do |path, identifier|
95
106
  mime, contents = mime_type(path), encoded_contents(path)
96
107
  [MHTML_SEPARATOR, "Content-Location: #{identifier}\r\n", "Content-Type: #{mime}\r\n", "Content-Transfer-Encoding: base64\r\n\r\n", contents, "\r\n"]
97
108
  end
98
109
  [MHTML_START, mhtml, MHTML_END, css].flatten.join('')
99
110
  end
100
111
 
112
+ # Get the site-absolute public path for an image file path that may or may
113
+ # not be relative, given the path of the stylesheet that contains it.
114
+ def public_path(image_path, css_path)
115
+ image_path, css_path = Pathname.new(image_path), Pathname.new(css_path)
116
+ (image_path.absolute? ? Pathname.new("public#{image_path}") : css_path.dirname + image_path).cleanpath
117
+ end
118
+
101
119
  # An image is valid if it exists, and is less than 32K.
102
120
  # IE does not support Data-URIs larger than 32K, and you probably shouldn't
103
121
  # be embedding images that large in any case.
104
122
  def valid_image(image_path)
105
- File.exists?(image_path) && File.size(image_path) < 32.kilobytes
123
+ image_path.exist? && image_path.size < 32.kilobytes
106
124
  end
107
125
 
108
126
  # Return the Base64-encoded contents of an image on a single line.
@@ -1 +1 @@
1
- var template = function(str){var fn = new Function('obj', 'var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push(\''+str.replace(/[\r\t\n]/g, " ").split("<%").join("\t").replace(/((^|%>)[^\t]*)'/g, "$1\r").replace(/\t=(.*?)%>/g, "',$1,'").split("\t").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');"); return fn;};
1
+ var template = function(str){var fn = new Function('obj', 'var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push(\''+str.replace(/[\r\t\n]/g, " ").split("<%").join("\t").replace(/((^|%>)[^\t]*)'/g, "$1\r").replace(/\t=(.*?)%>/g, "',$1,'").split("\t").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');"); return fn;};
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jammit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Ashkenas
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-06 00:00:00 -05:00
12
+ date: 2009-11-16 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency