secobarbital-jammit 0.5.0.1 → 0.6.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/jammit.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'secobarbital-jammit'
3
- s.version = '0.5.0.1' # Keep version in sync with jammit.rb
4
- s.date = '2010-4-15'
3
+ s.version = '0.6.0.1' # Keep version in sync with jammit.rb
4
+ s.date = '2011-3-4'
5
5
 
6
6
  s.homepage = "http://documentcloud.github.com/jammit/"
7
7
  s.summary = "Industrial Strength Asset Packaging for Rails"
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
14
14
  EOS
15
15
 
16
16
  s.authors = ['Jeremy Ashkenas', 'Seggy Umboh']
17
- s.email = ['jeremy@documentcloud.org', 'Seggy Umboh']
17
+ s.email = ['jeremy@documentcloud.org', 'seggy.umboh@gmail.com']
18
18
  s.rubyforge_project = 'jammit'
19
19
 
20
20
  s.require_paths = ['lib']
@@ -27,8 +27,7 @@ Gem::Specification.new do |s|
27
27
  '--main' << 'README' <<
28
28
  '--all'
29
29
 
30
- s.add_dependency 'rails', ['>= 2.0.0']
31
- s.add_dependency 'yui-compressor', ['>= 0.9.1']
30
+ s.add_dependency 'yui-compressor', ['>= 0.9.3']
32
31
 
33
- s.files = Dir['lib/**/*', 'bin/*', 'jammit.gemspec', 'LICENSE', 'README']
34
- end
32
+ s.files = Dir['lib/**/*', 'bin/*', 'rails/*', 'jammit.gemspec', 'LICENSE', 'README']
33
+ end
data/lib/jammit.rb CHANGED
@@ -4,13 +4,13 @@ $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.4.4"
7
+ VERSION = "0.6.0"
8
8
 
9
9
  ROOT = File.expand_path(File.dirname(__FILE__) + '/..')
10
10
 
11
- ASSET_ROOT = File.expand_path(defined?(Rails) ? Rails.root : ".") unless defined?(ASSET_ROOT)
11
+ ASSET_ROOT = File.expand_path((defined?(Rails) && Rails.root.to_s.length > 0) ? Rails.root : ".") unless defined?(ASSET_ROOT)
12
12
 
13
- PUBLIC_ROOT = defined?(Rails) ? Rails.public_path : File.join(ASSET_ROOT, 'public')
13
+ PUBLIC_ROOT = (defined?(Rails) && Rails.public_path.to_s.length > 0) ? Rails.public_path : File.join(ASSET_ROOT, 'public') unless defined?(PUBLIC_ROOT)
14
14
 
15
15
  DEFAULT_CONFIG_PATH = File.join(ASSET_ROOT, 'config', 'assets.yml')
16
16
 
@@ -27,8 +27,8 @@ module Jammit
27
27
  DEFAULT_COMPRESSOR = :yui
28
28
 
29
29
  # Extension matchers for JavaScript and JST, which need to be disambiguated.
30
- JS_EXT = /\.js\Z/
31
- JST_EXT = /\.jst\Z/
30
+ JS_EXTENSION = /\.js\Z/
31
+ DEFAULT_JST_EXTENSION = "jst"
32
32
 
33
33
  # Jammit raises a @PackageNotFound@ exception when a non-existent package is
34
34
  # requested by a browser -- rendering a 404.
@@ -48,8 +48,9 @@ module Jammit
48
48
  class << self
49
49
  attr_reader :configuration, :template_function, :template_namespace,
50
50
  :embed_assets, :package_assets, :compress_assets, :gzip_assets,
51
- :package_path, :mhtml_enabled, :include_jst_script,
52
- :javascript_compressor, :compressor_options, :css_compressor_options
51
+ :package_path, :mhtml_enabled, :include_jst_script, :config_path,
52
+ :javascript_compressor, :compressor_options, :css_compressor_options,
53
+ :template_extension, :template_extension_matcher, :allow_debugging
53
54
  end
54
55
 
55
56
  # The minimal required configuration.
@@ -57,23 +58,29 @@ module Jammit
57
58
  @package_path = DEFAULT_PACKAGE_PATH
58
59
 
59
60
  # Load the complete asset configuration from the specified @config_path@.
60
- def self.load_configuration(config_path)
61
+ # If we're loading softly, don't let missing configuration error out.
62
+ def self.load_configuration(config_path, soft=false)
61
63
  exists = config_path && File.exists?(config_path)
64
+ return false if soft && !exists
62
65
  raise ConfigurationNotFound, "could not find the \"#{config_path}\" configuration file" unless exists
63
66
  conf = YAML.load(ERB.new(File.read(config_path)).result)
64
67
  @config_path = config_path
65
- @configuration = conf = conf.symbolize_keys
68
+ @configuration = symbolize_keys(conf)
66
69
  @package_path = conf[:package_path] || DEFAULT_PACKAGE_PATH
67
70
  @embed_assets = conf[:embed_assets] || conf[:embed_images]
68
71
  @compress_assets = !(conf[:compress_assets] == false)
69
72
  @gzip_assets = !(conf[:gzip_assets] == false)
73
+ @allow_debugging = !(conf[:allow_debugging] == false)
70
74
  @mhtml_enabled = @embed_assets && @embed_assets != "datauri"
71
- @compressor_options = (conf[:compressor_options] || {}).symbolize_keys
72
- @css_compressor_options = (conf[:css_compressor_options] || {}).symbolize_keys
75
+ @compressor_options = symbolize_keys(conf[:compressor_options] || {})
76
+ @css_compressor_options = symbolize_keys(conf[:css_compressor_options] || {})
73
77
  set_javascript_compressor(conf[:javascript_compressor])
74
78
  set_package_assets(conf[:package_assets])
75
79
  set_template_function(conf[:template_function])
76
80
  set_template_namespace(conf[:template_namespace])
81
+ set_template_extension(conf[:template_extension])
82
+ symbolize_keys(conf[:stylesheets]) if conf[:stylesheets]
83
+ symbolize_keys(conf[:javascripts]) if conf[:javascripts]
77
84
  check_java_version
78
85
  check_for_deprecations
79
86
  self
@@ -104,6 +111,18 @@ module Jammit
104
111
  "/#{package_path}/#{filename(package, extension, suffix)}#{timestamp}"
105
112
  end
106
113
 
114
+ # Convenience method for packaging up Jammit, using the default options.
115
+ def self.package!(options={})
116
+ options = {
117
+ :config_path => Jammit::DEFAULT_CONFIG_PATH,
118
+ :output_folder => nil,
119
+ :base_url => nil,
120
+ :force => false
121
+ }.merge(options)
122
+ load_configuration(options[:config_path])
123
+ packager.force = options[:force]
124
+ packager.precache_all(options[:output_folder], options[:base_url])
125
+ end
107
126
 
108
127
  private
109
128
 
@@ -115,7 +134,7 @@ module Jammit
115
134
 
116
135
  # Turn asset packaging on or off, depending on configuration and environment.
117
136
  def self.set_package_assets(value)
118
- package_env = !defined?(Rails) || !Rails.env.development?
137
+ package_env = !defined?(Rails) || (!Rails.env.development? && !Rails.env.test?)
119
138
  @package_assets = value == true || value.nil? ? package_env :
120
139
  value == 'always' ? true : false
121
140
  end
@@ -132,6 +151,12 @@ module Jammit
132
151
  @template_namespace = value == true || value.nil? ? DEFAULT_JST_NAMESPACE : value.to_s
133
152
  end
134
153
 
154
+ # Set the extension for JS templates.
155
+ def self.set_template_extension(value)
156
+ @template_extension = (value == true || value.nil? ? DEFAULT_JST_EXTENSION : value.to_s).gsub(/\A\.?(.*)\Z/, '\1')
157
+ @template_extension_matcher = /\.#{Regexp.escape(@template_extension)}\Z/
158
+ end
159
+
135
160
  # The YUI Compressor requires Java > 1.4, and Closure requires Java > 1.6.
136
161
  def self.check_java_version
137
162
  return true if @checked_java_version
@@ -157,9 +182,16 @@ module Jammit
157
182
 
158
183
  def self.warn(message)
159
184
  message = "Jammit Warning: #{message}"
160
- @logger ||= (defined?(Rails) && Rails.logger ? Rails.logger :
161
- defined?(RAILS_DEFAULT_LOGGER) ? RAILS_DEFAULT_LOGGER : nil)
162
- @logger ? @logger.warn(message) : STDERR.puts(message)
185
+ $stderr.puts message
186
+ end
187
+
188
+ # Clone of active_support's symbolize_keys, so that we don't have to depend
189
+ # on active_support in any fashion. Converts a hash's keys to all symbols.
190
+ def self.symbolize_keys(hash)
191
+ hash.keys.each do |key|
192
+ hash[(key.to_sym rescue key) || key] = hash.delete(key)
193
+ end
194
+ hash
163
195
  end
164
196
 
165
197
  end
@@ -26,9 +26,7 @@ Options:
26
26
  def initialize
27
27
  parse_options
28
28
  ensure_configuration_file
29
- Jammit.load_configuration(@options[:config_path])
30
- Jammit.packager.force = @options[:force]
31
- Jammit.packager.precache_all(@options[:output_folder], @options[:base_url])
29
+ Jammit.package!(@options)
32
30
  end
33
31
 
34
32
 
@@ -16,25 +16,26 @@ module Jammit
16
16
  '.tif' => 'image/tiff',
17
17
  '.tiff' => 'image/tiff',
18
18
  '.ttf' => 'font/truetype',
19
- '.otf' => 'font/opentype'
19
+ '.otf' => 'font/opentype',
20
+ '.woff' => 'font/woff'
20
21
  }
21
22
 
22
23
  # Font extensions for which we allow embedding:
23
24
  EMBED_EXTS = EMBED_MIME_TYPES.keys
24
- EMBED_FONTS = ['.ttf', '.otf']
25
+ EMBED_FONTS = ['.ttf', '.otf', '.woff']
25
26
 
26
- # 32k maximum size for embeddable images (an IE8 limitation).
27
- MAX_IMAGE_SIZE = 32768
27
+ # (32k - padding) maximum length for data-uri assets (an IE8 limitation).
28
+ MAX_IMAGE_SIZE = 32700
28
29
 
29
30
  # CSS asset-embedding regexes for URL rewriting.
30
31
  EMBED_DETECTOR = /url\(['"]?([^\s)]+\.[a-z]+)(\?\d+)?['"]?\)/
31
32
  EMBEDDABLE = /[\A\/]embed\//
32
- EMBED_REPLACER = /url\(__EMBED__([^\s)]+)(\?\d+)?\)/
33
+ EMBED_REPLACER = /url\(__EMBED__(.+?)(\?\d+)?\)/
33
34
 
34
35
  # MHTML file constants.
35
- MHTML_START = "/*\r\nContent-Type: multipart/related; boundary=\"JAMMIT_MHTML_SEPARATOR\"\r\n\r\n"
36
- MHTML_SEPARATOR = "--JAMMIT_MHTML_SEPARATOR\r\n"
37
- MHTML_END = "*/\r\n"
36
+ MHTML_START = "/*\r\nContent-Type: multipart/related; boundary=\"MHTML_MARK\"\r\n\r\n"
37
+ MHTML_SEPARATOR = "--MHTML_MARK\r\n"
38
+ MHTML_END = "\r\n--MHTML_MARK--\r\n*/\r\n"
38
39
 
39
40
  # JST file constants.
40
41
  JST_START = "(function(){"
@@ -60,7 +61,7 @@ module Jammit
60
61
  # Concatenate together a list of JavaScript paths, and pass them through the
61
62
  # YUI Compressor (with munging enabled). JST can optionally be included.
62
63
  def compress_js(paths)
63
- if (jst_paths = paths.grep(JST_EXT)).empty?
64
+ if (jst_paths = paths.grep(Jammit.template_extension_matcher)).empty?
64
65
  js = concatenate(paths)
65
66
  else
66
67
  js = concatenate(paths - jst_paths) + compile_jst(jst_paths)
@@ -72,6 +73,7 @@ module Jammit
72
73
  # :datauri or :mhtml variant, post-processes the result to embed
73
74
  # referenced assets.
74
75
  def compress_css(paths, variant=nil, asset_url=nil)
76
+ @asset_contents = {}
75
77
  css = concatenate_and_tag_assets(paths, variant)
76
78
  css = @css_compressor.compress(css) if Jammit.compress_assets
77
79
  case variant
@@ -88,13 +90,16 @@ module Jammit
88
90
  # specified your own preferred function, or turned it off.
89
91
  # JST templates are named with the basename of their file.
90
92
  def compile_jst(paths)
91
- namespace = Jammit.template_namespace
92
- compiled = paths.grep(JST_EXT).map do |path|
93
- template_name = File.basename(path, File.extname(path))
94
- contents = File.read(path).gsub(/\n/, '').gsub("'", '\\\\\'')
95
- "#{namespace}.#{template_name} = #{Jammit.template_function}('#{contents}');"
93
+ namespace = Jammit.template_namespace
94
+ paths = paths.grep(Jammit.template_extension_matcher).sort
95
+ base_path = find_base_path(paths)
96
+ compiled = paths.map do |path|
97
+ contents = read_binary_file(path)
98
+ contents = contents.gsub(/\n/, '').gsub("'", '\\\\\'')
99
+ name = template_name(path, base_path)
100
+ "#{namespace}['#{name}'] = #{Jammit.template_function}('#{contents}');"
96
101
  end
97
- compiler = Jammit.include_jst_script ? File.read(DEFAULT_JST_SCRIPT) : '';
102
+ compiler = Jammit.include_jst_script ? read_binary_file(DEFAULT_JST_SCRIPT) : '';
98
103
  setup_namespace = "#{namespace} = #{namespace} || {};"
99
104
  [JST_START, setup_namespace, compiler, compiled, JST_END].flatten.join("\n")
100
105
  end
@@ -102,13 +107,35 @@ module Jammit
102
107
 
103
108
  private
104
109
 
110
+ # Given a set of paths, find a common prefix path.
111
+ def find_base_path(paths)
112
+ return nil if paths.length <= 1
113
+ paths.sort!
114
+ first = paths.first.split('/')
115
+ last = paths.last.split('/')
116
+ i = 0
117
+ while first[i] == last[i] && i <= first.length
118
+ i += 1
119
+ end
120
+ res = first.slice(0, i).join('/')
121
+ res.empty? ? nil : res
122
+ end
123
+
124
+ # Determine the name of a JS template. If there's a common base path, use
125
+ # the namespaced prefix. Otherwise, simply use the filename.
126
+ def template_name(path, base_path)
127
+ return File.basename(path, ".#{Jammit.template_extension}") unless base_path
128
+ path.gsub(/\A#{Regexp.escape(base_path)}\/(.*)\.#{Jammit.template_extension}\Z/, '\1')
129
+ end
130
+
105
131
  # In order to support embedded assets from relative paths, we need to
106
132
  # expand the paths before contatenating the CSS together and losing the
107
133
  # location of the original stylesheet path. Validate the assets while we're
108
134
  # at it.
109
135
  def concatenate_and_tag_assets(paths, variant=nil)
110
136
  stylesheets = [paths].flatten.map do |css_path|
111
- File.read(css_path).gsub(EMBED_DETECTOR) do |url|
137
+ contents = read_binary_file(css_path)
138
+ contents.gsub(EMBED_DETECTOR) do |url|
112
139
  ipath, cpath = Pathname.new($1), Pathname.new(File.expand_path(css_path))
113
140
  is_url = URI.parse($1).absolute?
114
141
  is_url ? url : "url(#{construct_asset_path(ipath, cpath, variant)})"
@@ -169,7 +196,7 @@ module Jammit
169
196
  # append the RAILS_ASSET_ID cache-buster to URLs, if it's defined.
170
197
  def rewrite_asset_path(path, file_path)
171
198
  asset_id = rails_asset_id(file_path)
172
- asset_id.blank? ? path : "#{path}?#{asset_id}"
199
+ (!asset_id || asset_id == '') ? path : "#{path}?#{asset_id}"
173
200
  end
174
201
 
175
202
  # Similar to the AssetTagHelper's method of the same name, this will
@@ -181,23 +208,25 @@ module Jammit
181
208
  end
182
209
 
183
210
  # An asset is valid for embedding if it exists, is less than 32K, and is
184
- # stored somewhere inside of a folder named "embed".
185
- # IE does not support Data-URIs larger than 32K, and you probably shouldn't
186
- # be embedding assets that large in any case.
211
+ # stored somewhere inside of a folder named "embed". IE does not support
212
+ # Data-URIs larger than 32K, and you probably shouldn't be embedding assets
213
+ # that large in any case. Because we need to check the base64 length here,
214
+ # save it so that we don't have to compute it again later.
187
215
  def embeddable?(asset_path, variant)
188
216
  font = EMBED_FONTS.include?(asset_path.extname)
189
217
  return false unless variant
190
218
  return false unless asset_path.to_s.match(EMBEDDABLE) && asset_path.exist?
191
219
  return false unless EMBED_EXTS.include?(asset_path.extname)
192
- return false unless font || asset_path.size < MAX_IMAGE_SIZE
220
+ return false unless font || encoded_contents(asset_path).length < MAX_IMAGE_SIZE
193
221
  return false if font && variant == :mhtml
194
- true
222
+ return true
195
223
  end
196
224
 
197
225
  # Return the Base64-encoded contents of an asset on a single line.
198
226
  def encoded_contents(asset_path)
199
- data = File.open(asset_path, 'rb'){|f| f.read }
200
- Base64.encode64(data).gsub(/\n/, '')
227
+ return @asset_contents[asset_path] if @asset_contents[asset_path]
228
+ data = read_binary_file(asset_path)
229
+ @asset_contents[asset_path] = Base64.encode64(data).gsub(/\n/, '')
201
230
  end
202
231
 
203
232
  # Grab the mime-type of an asset, by filename.
@@ -207,9 +236,13 @@ module Jammit
207
236
 
208
237
  # Concatenate together a list of asset files.
209
238
  def concatenate(paths)
210
- [paths].flatten.map {|p| File.read(p) }.join("\n")
239
+ [paths].flatten.map {|p| read_binary_file(p) }.join("\n")
211
240
  end
212
241
 
242
+ # `File.read`, but in "binary" mode.
243
+ def read_binary_file(path)
244
+ File.open(path, 'rb') {|f| f.read }
245
+ end
213
246
  end
214
247
 
215
248
  end
@@ -5,7 +5,7 @@ module Jammit
5
5
  # missing or uncached asset packages.
6
6
  class Controller < ActionController::Base
7
7
 
8
- VALID_FORMATS = [:css, :js, :jst]
8
+ VALID_FORMATS = [:css, :js]
9
9
 
10
10
  SUFFIX_STRIPPER = /-(datauri|mhtml)\Z/
11
11
 
@@ -15,12 +15,16 @@ module Jammit
15
15
  # yet been cached. The package will be built, cached, and gzipped.
16
16
  def package
17
17
  parse_request
18
+ template_ext = Jammit.template_extension.to_sym
18
19
  case @extension
19
- when :js then render :js => (@contents = Jammit.packager.pack_javascripts(@package))
20
- when :css then render :text => generate_stylesheets, :content_type => 'text/css'
21
- when :jst then render :js => (@contents = Jammit.packager.pack_templates(@package))
20
+ when :js
21
+ render :js => (@contents = Jammit.packager.pack_javascripts(@package))
22
+ when template_ext
23
+ render :js => (@contents = Jammit.packager.pack_templates(@package))
24
+ when :css
25
+ render :text => generate_stylesheets, :content_type => 'text/css'
22
26
  end
23
- cache_package if perform_caching
27
+ cache_package if perform_caching && (@extension != template_ext)
24
28
  rescue Jammit::PackageNotFound
25
29
  package_not_found
26
30
  end
@@ -50,19 +54,19 @@ module Jammit
50
54
  def generate_stylesheets
51
55
  return @contents = Jammit.packager.pack_stylesheets(@package, @variant) unless @variant == :mhtml
52
56
  @mtime = Time.now
53
- request_url = prefix_url(request.request_uri)
57
+ request_url = prefix_url(request.fullpath)
54
58
  cached_url = prefix_url(Jammit.asset_url(@package, @extension, @variant, @mtime))
55
59
  css = Jammit.packager.pack_stylesheets(@package, @variant, request_url)
56
60
  @contents = css.gsub(request_url, cached_url) if perform_caching
57
61
  css
58
62
  end
59
63
 
60
- # Extracts the package name, extension (:css, :js, :jst), and variant
61
- # (:datauri, :mhtml) from the incoming URL.
64
+ # Extracts the package name, extension (:css, :js), and variant (:datauri,
65
+ # :mhtml) from the incoming URL.
62
66
  def parse_request
63
67
  pack = params[:package]
64
68
  @extension = params[:extension].to_sym
65
- raise PackageNotFound unless VALID_FORMATS.include?(@extension)
69
+ raise PackageNotFound unless (VALID_FORMATS + [Jammit.template_extension.to_sym]).include?(@extension)
66
70
  if Jammit.embed_assets
67
71
  suffix_match = pack.match(SUFFIX_STRIPPER)
68
72
  @variant = Jammit.embed_assets && suffix_match && suffix_match[1].to_sym
@@ -84,7 +88,7 @@ end
84
88
  # Make the Jammit::Controller available to Rails as a top-level controller.
85
89
  ::JammitController = Jammit::Controller
86
90
 
87
- if Rails.env.development?
91
+ if defined?(Rails) && Rails.env.development?
88
92
  ActionController::Base.class_eval do
89
93
  append_before_filter { Jammit.reload! }
90
94
  end
@@ -2,19 +2,16 @@
2
2
  require 'uri'
3
3
  require 'erb'
4
4
  require 'zlib'
5
+ require 'yaml'
5
6
  require 'base64'
6
7
  require 'pathname'
7
8
  require 'fileutils'
8
9
 
9
10
  # Gem Dependencies:
10
- require 'rubygems'
11
- gem 'rails', '~> 2.0'
12
11
  require 'yui/compressor'
13
- require 'active_support'
14
- require 'active_support/core_ext/hash'
15
12
 
16
13
  # Load initial configuration before the rest of Jammit.
17
- Jammit.load_configuration(Jammit::DEFAULT_CONFIG_PATH) if defined?(Rails)
14
+ Jammit.load_configuration(Jammit::DEFAULT_CONFIG_PATH, true) if defined?(Rails)
18
15
 
19
16
  # Jammit Core:
20
17
  require 'jammit/compressor'
@@ -22,6 +19,9 @@ require 'jammit/packager'
22
19
 
23
20
  # Jammit Rails Integration:
24
21
  if defined?(Rails)
25
- require 'jammit/controller' # Rails will auto-load 'jammit/helper' for us.
22
+ require 'jammit/controller'
23
+ require 'jammit/helper'
24
+ require 'jammit/railtie'
26
25
  require 'jammit/routes'
27
- end
26
+ end
27
+
data/lib/jammit/helper.rb CHANGED
@@ -6,29 +6,29 @@ module Jammit
6
6
  # to the cached packages.
7
7
  module Helper
8
8
 
9
- DATA_URI_START = "<!--[if (!IE)|(gte IE 8)]><!-->"
10
- DATA_URI_END = "<!--<![endif]-->"
11
- MHTML_START = "<!--[if lte IE 7]>"
12
- MHTML_END = "<![endif]-->"
9
+ DATA_URI_START = "<!--[if (!IE)|(gte IE 8)]><!-->" unless defined?(DATA_URI_START)
10
+ DATA_URI_END = "<!--<![endif]-->" unless defined?(DATA_URI_END)
11
+ MHTML_START = "<!--[if lte IE 7]>" unless defined?(MHTML_START)
12
+ MHTML_END = "<![endif]-->" unless defined?(MHTML_END)
13
13
 
14
14
  # If embed_assets is turned on, writes out links to the Data-URI and MHTML
15
15
  # versions of the stylesheet package, otherwise the package is regular
16
16
  # compressed CSS, and in development the stylesheet URLs are passed verbatim.
17
17
  def include_stylesheets(*packages)
18
18
  options = packages.extract_options!
19
- return individual_stylesheets(packages, options) unless Jammit.package_assets
19
+ return individual_stylesheets(packages, options) unless should_package?
20
20
  disabled = (options.delete(:embed_assets) == false) || (options.delete(:embed_images) == false)
21
- return packaged_stylesheets(packages, options) if disabled || !Jammit.embed_assets
22
- return embedded_image_stylesheets(packages, options)
21
+ return html_safe(packaged_stylesheets(packages, options)) if disabled || !Jammit.embed_assets
22
+ return html_safe(embedded_image_stylesheets(packages, options))
23
23
  end
24
24
 
25
25
  # Writes out the URL to the bundled and compressed javascript package,
26
26
  # except in development, where it references the individual scripts.
27
27
  def include_javascripts(*packages)
28
28
  tags = packages.map do |pack|
29
- Jammit.package_assets ? Jammit.asset_url(pack, :js) : Jammit.packager.individual_urls(pack.to_sym, :js)
29
+ should_package? ? Jammit.asset_url(pack, :js) : Jammit.packager.individual_urls(pack.to_sym, :js)
30
30
  end
31
- javascript_include_tag(tags.flatten)
31
+ html_safe(javascript_include_tag(tags.flatten))
32
32
  end
33
33
 
34
34
  # Writes out the URL to the concatenated and compiled JST file -- we always
@@ -40,6 +40,14 @@ module Jammit
40
40
 
41
41
  private
42
42
 
43
+ def should_package?
44
+ Jammit.package_assets && !(Jammit.allow_debugging && params[:debug_assets])
45
+ end
46
+
47
+ def html_safe(string)
48
+ string.respond_to?(:html_safe) ? string.html_safe : string
49
+ end
50
+
43
51
  # HTML tags, in order, for all of the individual stylesheets.
44
52
  def individual_stylesheets(packages, options)
45
53
  tags_with_options(packages, options) {|p| Jammit.packager.individual_urls(p.to_sym, :css) }
@@ -21,8 +21,8 @@ module Jammit
21
21
  @compressor = Compressor.new
22
22
  @force = false
23
23
  @config = {
24
- :css => (Jammit.configuration[:stylesheets] || {}).symbolize_keys,
25
- :js => (Jammit.configuration[:javascripts] || {}).symbolize_keys
24
+ :css => (Jammit.configuration[:stylesheets] || {}),
25
+ :js => (Jammit.configuration[:javascripts] || {})
26
26
  }
27
27
  @packages = {
28
28
  :css => create_packages(@config[:css]),
@@ -84,17 +84,15 @@ module Jammit
84
84
 
85
85
  # Return the compiled contents of a JST package.
86
86
  def pack_templates(package)
87
- @compressor.compile_jst(package_for(package, :jst)[:paths])
87
+ @compressor.compile_jst(package_for(package, :js)[:paths])
88
88
  end
89
89
 
90
-
91
90
  private
92
91
 
93
92
  # Look up a package asset list by name, raising an exception if the
94
93
  # package has gone missing.
95
94
  def package_for(package, extension)
96
95
  pack = @packages[extension] && @packages[extension][package]
97
- pack ||= @packages[:js] && @packages[:js][package] if extension == :jst
98
96
  pack || not_found(package, extension)
99
97
  end
100
98
 
@@ -108,21 +106,34 @@ module Jammit
108
106
  end
109
107
 
110
108
  # Return a list of all of the packages that should be cached. If "force" is
111
- # true, this is all of them -- otherwise only the packages whose source
112
- # files have changed since the last package build.
109
+ # true, this is all of them -- otherwise only the packages that are missing
110
+ # or whose source files have changed since the last package build.
113
111
  def cacheable(extension, output_dir)
114
112
  names = @packages[extension].keys
115
113
  return names if @force
114
+ config_mtime = File.mtime(Jammit.config_path)
116
115
  return names.select do |name|
117
- pack = package_for(name, extension)
118
- cached = File.join(output_dir, Jammit.filename(name, extension))
119
- since = File.exists?(cached) && File.mtime(cached)
120
- !since || pack[:paths].any? {|src| File.mtime(src) > since }
116
+ pack = package_for(name, extension)
117
+ cached = [Jammit.filename(name, extension)]
118
+ cached.push Jammit.filename(name, extension, :datauri) if Jammit.embed_assets
119
+ cached.push Jammit.filename(name, extension, :mhtml) if Jammit.mhtml_enabled
120
+ cached.map! {|file| File.join(output_dir, file) }
121
+ if cached.any? {|file| !File.exists?(file) }
122
+ true
123
+ else
124
+ since = cached.map {|file| File.mtime(file) }.min
125
+ config_mtime > since || pack[:paths].any? {|src| File.mtime(src) > since }
126
+ end
121
127
  end
122
128
  end
123
129
 
124
- # Compiles the list of assets that goes into each package. Runs an ordered
125
- # list of Dir.globs, taking the merged unique result.
130
+ # Compiles the list of assets that goes into each package. Runs an
131
+ # ordered list of Dir.globs, taking the merged unique result.
132
+ # If there are JST files in this package we need to add an extra
133
+ # path for when package_assets is off (e.g. in a dev environment).
134
+ # This package (e.g. /assets/package-name.jst) will never exist as
135
+ # an actual file but will be dynamically generated by Jammit on
136
+ # every request.
126
137
  def create_packages(config)
127
138
  packages = {}
128
139
  return packages if !config
@@ -131,9 +142,9 @@ module Jammit
131
142
  packages[name] = {}
132
143
  paths = globs.flatten.uniq.map {|glob| glob_files(glob) }.flatten.uniq
133
144
  packages[name][:paths] = paths
134
- if !paths.grep(JS_EXT).empty? && !paths.grep(JST_EXT).empty?
135
- packages[name][:urls] = paths.grep(JS_EXT).map {|path| path.sub(PATH_TO_URL, '') }
136
- packages[name][:urls] += [Jammit.asset_url(name, :jst)]
145
+ if !paths.grep(Jammit.template_extension_matcher).empty?
146
+ packages[name][:urls] = paths.grep(JS_EXTENSION).map {|path| path.sub(PATH_TO_URL, '') }
147
+ packages[name][:urls] += [Jammit.asset_url(name, Jammit.template_extension)]
137
148
  else
138
149
  packages[name][:urls] = paths.map {|path| path.sub(PATH_TO_URL, '') }
139
150
  end
@@ -0,0 +1,14 @@
1
+ # Rails 3 configuration via Railtie
2
+
3
+ if defined?(Rails::Railtie)
4
+ module Jammit
5
+ class Railtie < Rails::Railtie
6
+
7
+ initializer :jammit_routes do |app|
8
+ # Add a Jammit route for the reloader.
9
+ app.routes_reloader.paths << File.join(File.dirname(__FILE__), "..", "..", "rails", "routes.rb")
10
+ end
11
+
12
+ end
13
+ end
14
+ end
data/lib/jammit/routes.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Jammit
2
2
 
3
- # Rails 2.x routing module.
3
+ # Rails 2.x routing module. Rails 3.x routes are in rails/routes.rb.
4
4
  module Routes
5
5
 
6
6
  # Jammit uses a single route in order to slow down Rails' routing speed
@@ -8,18 +8,16 @@ module Jammit
8
8
  # Jammit::Routes.draw(map)
9
9
  # Passing in the routing "map" object.
10
10
  def self.draw(map)
11
- map.jammit "/#{Jammit.package_path}/:package.:extension",
12
- :controller => 'jammit', :action => 'package'
11
+ map.jammit "/#{Jammit.package_path}/:package.:extension", {
12
+ :controller => 'jammit',
13
+ :action => 'package',
14
+ :requirements => {
15
+ # A hack to allow extension to include "."
16
+ :extension => /.+/
17
+ }
18
+ }
13
19
  end
14
20
 
15
21
  end
16
22
 
17
- end
18
-
19
- # Rails 3.x routes.
20
- if defined?(Jammit::Railtie)
21
- Jammit::Railtie.routes do
22
- match "/#{Jammit.package_path}/:package.:extension",
23
- :to => 'jammit#package', :as => 'jammit'
24
- end
25
23
  end
data/rails/routes.rb ADDED
@@ -0,0 +1,10 @@
1
+ if defined?(Rails::Application)
2
+ # Rails3 routes
3
+ Rails.application.routes.draw do
4
+ match "/#{Jammit.package_path}/:package.:extension",
5
+ :to => 'jammit#package', :as => :jammit, :constraints => {
6
+ # A hack to allow extension to include "."
7
+ :extension => /.+/
8
+ }
9
+ end
10
+ end
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: secobarbital-jammit
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 125
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
- - 5
8
+ - 6
8
9
  - 0
9
10
  - 1
10
- version: 0.5.0.1
11
+ version: 0.6.0.1
11
12
  platform: ruby
12
13
  authors:
13
14
  - Jeremy Ashkenas
@@ -16,41 +17,29 @@ autorequire:
16
17
  bindir: bin
17
18
  cert_chain: []
18
19
 
19
- date: 2010-04-15 00:00:00 -07:00
20
+ date: 2011-03-04 00:00:00 -08:00
20
21
  default_executable:
21
22
  dependencies:
22
- - !ruby/object:Gem::Dependency
23
- name: rails
24
- prerelease: false
25
- requirement: &id001 !ruby/object:Gem::Requirement
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- segments:
30
- - 2
31
- - 0
32
- - 0
33
- version: 2.0.0
34
- type: :runtime
35
- version_requirements: *id001
36
23
  - !ruby/object:Gem::Dependency
37
24
  name: yui-compressor
38
25
  prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
26
+ requirement: &id001 !ruby/object:Gem::Requirement
27
+ none: false
40
28
  requirements:
41
29
  - - ">="
42
30
  - !ruby/object:Gem::Version
31
+ hash: 61
43
32
  segments:
44
33
  - 0
45
34
  - 9
46
- - 1
47
- version: 0.9.1
35
+ - 3
36
+ version: 0.9.3
48
37
  type: :runtime
49
- version_requirements: *id002
38
+ version_requirements: *id001
50
39
  description: " Jammit is an industrial strength asset packaging library for Rails,\n providing both the CSS and JavaScript concatenation and compression that\n you'd expect, as well as YUI Compressor and Closure Compiler compatibility,\n ahead-of-time gzipping, built-in JavaScript template support, and optional\n Data-URI / MHTML image embedding.\n"
51
40
  email:
52
41
  - jeremy@documentcloud.org
53
- - Seggy Umboh
42
+ - seggy.umboh@gmail.com
54
43
  executables:
55
44
  - jammit
56
45
  extensions: []
@@ -65,9 +54,11 @@ files:
65
54
  - lib/jammit/helper.rb
66
55
  - lib/jammit/jst.js
67
56
  - lib/jammit/packager.rb
57
+ - lib/jammit/railtie.rb
68
58
  - lib/jammit/routes.rb
69
59
  - lib/jammit.rb
70
60
  - bin/jammit
61
+ - rails/routes.rb
71
62
  - jammit.gemspec
72
63
  - LICENSE
73
64
  - README
@@ -87,23 +78,27 @@ rdoc_options:
87
78
  require_paths:
88
79
  - lib
89
80
  required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
90
82
  requirements:
91
83
  - - ">="
92
84
  - !ruby/object:Gem::Version
85
+ hash: 3
93
86
  segments:
94
87
  - 0
95
88
  version: "0"
96
89
  required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
97
91
  requirements:
98
92
  - - ">="
99
93
  - !ruby/object:Gem::Version
94
+ hash: 3
100
95
  segments:
101
96
  - 0
102
97
  version: "0"
103
98
  requirements: []
104
99
 
105
100
  rubyforge_project: jammit
106
- rubygems_version: 1.3.6
101
+ rubygems_version: 1.3.7
107
102
  signing_key:
108
103
  specification_version: 3
109
104
  summary: Industrial Strength Asset Packaging for Rails