jammit 0.4.4 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/jammit +1 -1
- data/jammit.gemspec +2 -3
- data/lib/jammit/compressor.rb +49 -21
- data/lib/jammit/controller.rb +11 -8
- data/lib/jammit/dependencies.rb +6 -6
- data/lib/jammit/helper.rb +12 -8
- data/lib/jammit/packager.rb +33 -19
- data/lib/jammit/railtie.rb +14 -0
- data/lib/jammit/routes.rb +9 -2
- data/lib/jammit.rb +42 -8
- metadata +29 -23
data/bin/jammit
CHANGED
data/jammit.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'jammit'
|
3
|
-
s.version = '0.
|
4
|
-
s.date = '2010-2-
|
3
|
+
s.version = '0.5.0' # Keep version in sync with jammit.rb
|
4
|
+
s.date = '2010-2-19'
|
5
5
|
|
6
6
|
s.homepage = "http://documentcloud.github.com/jammit/"
|
7
7
|
s.summary = "Industrial Strength Asset Packaging for Rails"
|
@@ -27,7 +27,6 @@ Gem::Specification.new do |s|
|
|
27
27
|
'--main' << 'README' <<
|
28
28
|
'--all'
|
29
29
|
|
30
|
-
s.add_dependency 'rails', ['>= 2.0.0']
|
31
30
|
s.add_dependency 'yui-compressor', ['>= 0.9.1']
|
32
31
|
s.add_dependency 'closure-compiler', ['>= 0.1.0']
|
33
32
|
|
data/lib/jammit/compressor.rb
CHANGED
@@ -23,18 +23,18 @@ module Jammit
|
|
23
23
|
EMBED_EXTS = EMBED_MIME_TYPES.keys
|
24
24
|
EMBED_FONTS = ['.ttf', '.otf']
|
25
25
|
|
26
|
-
# 32k maximum
|
27
|
-
MAX_IMAGE_SIZE =
|
26
|
+
# (32k - padding) maximum length for data-uri assets (an IE8 limitation).
|
27
|
+
MAX_IMAGE_SIZE = 32700
|
28
28
|
|
29
29
|
# CSS asset-embedding regexes for URL rewriting.
|
30
30
|
EMBED_DETECTOR = /url\(['"]?([^\s)]+\.[a-z]+)(\?\d+)?['"]?\)/
|
31
31
|
EMBEDDABLE = /[\A\/]embed\//
|
32
|
-
EMBED_REPLACER = /url\(__EMBED__(
|
32
|
+
EMBED_REPLACER = /url\(__EMBED__(.+?)(\?\d+)?\)/
|
33
33
|
|
34
34
|
# MHTML file constants.
|
35
|
-
MHTML_START = "/*\r\nContent-Type: multipart/related; boundary=\"
|
36
|
-
MHTML_SEPARATOR = "--
|
37
|
-
MHTML_END = "*/\r\n"
|
35
|
+
MHTML_START = "/*\r\nContent-Type: multipart/related; boundary=\"MHTML_MARK\"\r\n\r\n"
|
36
|
+
MHTML_SEPARATOR = "--MHTML_MARK\r\n"
|
37
|
+
MHTML_END = "\r\n--MHTML_MARK--\r\n*/\r\n"
|
38
38
|
|
39
39
|
# JST file constants.
|
40
40
|
JST_START = "(function(){"
|
@@ -61,9 +61,13 @@ module Jammit
|
|
61
61
|
end
|
62
62
|
|
63
63
|
# Concatenate together a list of JavaScript paths, and pass them through the
|
64
|
-
# YUI Compressor (with munging enabled).
|
64
|
+
# YUI Compressor (with munging enabled). JST can optionally be included.
|
65
65
|
def compress_js(paths)
|
66
|
-
|
66
|
+
if (jst_paths = paths.grep(Jammit.template_extension_matcher)).empty?
|
67
|
+
js = concatenate(paths)
|
68
|
+
else
|
69
|
+
js = concatenate(paths - jst_paths) + compile_jst(jst_paths)
|
70
|
+
end
|
67
71
|
Jammit.compress_assets ? @js_compressor.compress(js) : js
|
68
72
|
end
|
69
73
|
|
@@ -71,6 +75,7 @@ module Jammit
|
|
71
75
|
# :datauri or :mhtml variant, post-processes the result to embed
|
72
76
|
# referenced assets.
|
73
77
|
def compress_css(paths, variant=nil, asset_url=nil)
|
78
|
+
@asset_contents = {}
|
74
79
|
css = concatenate_and_tag_assets(paths, variant)
|
75
80
|
css = @css_compressor.compress(css) if Jammit.compress_assets
|
76
81
|
case variant
|
@@ -87,11 +92,13 @@ module Jammit
|
|
87
92
|
# specified your own preferred function, or turned it off.
|
88
93
|
# JST templates are named with the basename of their file.
|
89
94
|
def compile_jst(paths)
|
90
|
-
namespace
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
+
namespace = Jammit.template_namespace
|
96
|
+
paths = paths.grep(Jammit.template_extension_matcher).sort
|
97
|
+
base_path = find_base_path(paths)
|
98
|
+
compiled = paths.map do |path|
|
99
|
+
contents = File.read(path).gsub(/\n/, '').gsub("'", '\\\\\'')
|
100
|
+
name = template_name(path, base_path)
|
101
|
+
"#{namespace}['#{name}'] = #{Jammit.template_function}('#{contents}');"
|
95
102
|
end
|
96
103
|
compiler = Jammit.include_jst_script ? File.read(DEFAULT_JST_SCRIPT) : '';
|
97
104
|
setup_namespace = "#{namespace} = #{namespace} || {};"
|
@@ -101,6 +108,27 @@ module Jammit
|
|
101
108
|
|
102
109
|
private
|
103
110
|
|
111
|
+
# Given a set of paths, find a common prefix path.
|
112
|
+
def find_base_path(paths)
|
113
|
+
return nil if paths.length <= 1
|
114
|
+
paths.sort!
|
115
|
+
first = paths.first.split('/')
|
116
|
+
last = paths.last.split('/')
|
117
|
+
i = 0
|
118
|
+
while first[i] == last[i] && i <= first.length
|
119
|
+
i += 1
|
120
|
+
end
|
121
|
+
res = first.slice(0, i).join('/')
|
122
|
+
res.empty? ? nil : res
|
123
|
+
end
|
124
|
+
|
125
|
+
# Determine the name of a JS template. If there's a common base path, use
|
126
|
+
# the namespaced prefix. Otherwise, simply use the filename.
|
127
|
+
def template_name(path, base_path)
|
128
|
+
return File.basename(path, ".#{Jammit.template_extension}") unless base_path
|
129
|
+
path.gsub(/\A#{base_path}\/(.*)\.#{Jammit.template_extension}\Z/, '\1')
|
130
|
+
end
|
131
|
+
|
104
132
|
# In order to support embedded assets from relative paths, we need to
|
105
133
|
# expand the paths before contatenating the CSS together and losing the
|
106
134
|
# location of the original stylesheet path. Validate the assets while we're
|
@@ -168,7 +196,7 @@ module Jammit
|
|
168
196
|
# append the RAILS_ASSET_ID cache-buster to URLs, if it's defined.
|
169
197
|
def rewrite_asset_path(path, file_path)
|
170
198
|
asset_id = rails_asset_id(file_path)
|
171
|
-
asset_id
|
199
|
+
(!asset_id || asset_id == '') ? path : "#{path}?#{asset_id}"
|
172
200
|
end
|
173
201
|
|
174
202
|
# Similar to the AssetTagHelper's method of the same name, this will
|
@@ -180,23 +208,23 @@ module Jammit
|
|
180
208
|
end
|
181
209
|
|
182
210
|
# An asset is valid for embedding if it exists, is less than 32K, and is
|
183
|
-
# stored somewhere inside of a folder named "embed".
|
184
|
-
#
|
185
|
-
#
|
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.
|
186
215
|
def embeddable?(asset_path, variant)
|
187
216
|
font = EMBED_FONTS.include?(asset_path.extname)
|
188
217
|
return false unless variant
|
189
218
|
return false unless asset_path.to_s.match(EMBEDDABLE) && asset_path.exist?
|
190
219
|
return false unless EMBED_EXTS.include?(asset_path.extname)
|
191
|
-
return false unless font || asset_path.
|
220
|
+
return false unless font || encoded_contents(asset_path).length < MAX_IMAGE_SIZE
|
192
221
|
return false if font && variant == :mhtml
|
193
|
-
true
|
222
|
+
return true
|
194
223
|
end
|
195
224
|
|
196
225
|
# Return the Base64-encoded contents of an asset on a single line.
|
197
226
|
def encoded_contents(asset_path)
|
198
|
-
|
199
|
-
Base64.encode64(data).gsub(/\n/, '')
|
227
|
+
@asset_contents[asset_path] ||= Base64.encode64(File.read(asset_path)).gsub(/\n/, '')
|
200
228
|
end
|
201
229
|
|
202
230
|
# Grab the mime-type of an asset, by filename.
|
data/lib/jammit/controller.rb
CHANGED
@@ -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
|
8
|
+
VALID_FORMATS = [:css, :js]
|
9
9
|
|
10
10
|
SUFFIX_STRIPPER = /-(datauri|mhtml)\Z/
|
11
11
|
|
@@ -16,9 +16,12 @@ module Jammit
|
|
16
16
|
def package
|
17
17
|
parse_request
|
18
18
|
case @extension
|
19
|
-
when :js
|
20
|
-
|
21
|
-
when
|
19
|
+
when :js
|
20
|
+
render :js => (@contents = Jammit.packager.pack_javascripts(@package))
|
21
|
+
when Jammit.template_extension.to_sym
|
22
|
+
render :js => (@contents = Jammit.packager.pack_templates(@package))
|
23
|
+
when :css
|
24
|
+
render :text => generate_stylesheets, :content_type => 'text/css'
|
22
25
|
end
|
23
26
|
cache_package if perform_caching
|
24
27
|
rescue Jammit::PackageNotFound
|
@@ -57,12 +60,12 @@ module Jammit
|
|
57
60
|
css
|
58
61
|
end
|
59
62
|
|
60
|
-
# Extracts the package name, extension (:css, :js
|
61
|
-
#
|
63
|
+
# Extracts the package name, extension (:css, :js), and variant (:datauri,
|
64
|
+
# :mhtml) from the incoming URL.
|
62
65
|
def parse_request
|
63
66
|
pack = params[:package]
|
64
67
|
@extension = params[:extension].to_sym
|
65
|
-
raise PackageNotFound unless VALID_FORMATS.include?(@extension)
|
68
|
+
raise PackageNotFound unless (VALID_FORMATS + [Jammit.template_extension.to_sym]).include?(@extension)
|
66
69
|
if Jammit.embed_assets
|
67
70
|
suffix_match = pack.match(SUFFIX_STRIPPER)
|
68
71
|
@variant = Jammit.embed_assets && suffix_match && suffix_match[1].to_sym
|
@@ -84,7 +87,7 @@ end
|
|
84
87
|
# Make the Jammit::Controller available to Rails as a top-level controller.
|
85
88
|
::JammitController = Jammit::Controller
|
86
89
|
|
87
|
-
if Rails.env.development?
|
90
|
+
if defined?(Rails) && Rails.env.development?
|
88
91
|
ActionController::Base.class_eval do
|
89
92
|
append_before_filter { Jammit.reload! }
|
90
93
|
end
|
data/lib/jammit/dependencies.rb
CHANGED
@@ -2,17 +2,14 @@
|
|
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
12
|
require 'closure-compiler'
|
14
|
-
require 'active_support'
|
15
|
-
require 'active_support/core_ext/hash'
|
16
13
|
|
17
14
|
# Load initial configuration before the rest of Jammit.
|
18
15
|
Jammit.load_configuration(Jammit::DEFAULT_CONFIG_PATH) if defined?(Rails)
|
@@ -23,6 +20,9 @@ require 'jammit/packager'
|
|
23
20
|
|
24
21
|
# Jammit Rails Integration:
|
25
22
|
if defined?(Rails)
|
26
|
-
require 'jammit/controller'
|
23
|
+
require 'jammit/controller'
|
24
|
+
require 'jammit/helper'
|
25
|
+
require 'jammit/railtie'
|
27
26
|
require 'jammit/routes'
|
28
|
-
end
|
27
|
+
end
|
28
|
+
|
data/lib/jammit/helper.rb
CHANGED
@@ -6,10 +6,10 @@ 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
|
@@ -18,8 +18,8 @@ module Jammit
|
|
18
18
|
options = packages.extract_options!
|
19
19
|
return individual_stylesheets(packages, options) unless Jammit.package_assets
|
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,
|
@@ -28,18 +28,22 @@ module Jammit
|
|
28
28
|
tags = packages.map do |pack|
|
29
29
|
Jammit.package_assets ? 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
|
35
35
|
# have to pre-process it, even in development.
|
36
36
|
def include_templates(*packages)
|
37
|
-
|
37
|
+
raise DeprecationError, "Jammit 0.5+ no longer supports separate packages for templates.\nYou can include your JST alongside your JS, and use include_javascripts."
|
38
38
|
end
|
39
39
|
|
40
40
|
|
41
41
|
private
|
42
42
|
|
43
|
+
def html_safe(string)
|
44
|
+
string.respond_to?(:html_safe) ? string.html_safe : string
|
45
|
+
end
|
46
|
+
|
43
47
|
# HTML tags, in order, for all of the individual stylesheets.
|
44
48
|
def individual_stylesheets(packages, options)
|
45
49
|
tags_with_options(packages, options) {|p| Jammit.packager.individual_urls(p.to_sym, :css) }
|
data/lib/jammit/packager.rb
CHANGED
@@ -21,14 +21,12 @@ module Jammit
|
|
21
21
|
@compressor = Compressor.new
|
22
22
|
@force = false
|
23
23
|
@config = {
|
24
|
-
:css => (Jammit.configuration[:stylesheets] || {})
|
25
|
-
:js => (Jammit.configuration[:javascripts] || {})
|
26
|
-
:jst => (Jammit.configuration[:templates] || {}).symbolize_keys
|
24
|
+
:css => (Jammit.configuration[:stylesheets] || {}),
|
25
|
+
:js => (Jammit.configuration[:javascripts] || {})
|
27
26
|
}
|
28
27
|
@packages = {
|
29
28
|
:css => create_packages(@config[:css]),
|
30
|
-
:js => create_packages(@config[:js])
|
31
|
-
:jst => create_packages(@config[:jst])
|
29
|
+
:js => create_packages(@config[:js])
|
32
30
|
}
|
33
31
|
end
|
34
32
|
|
@@ -40,7 +38,6 @@ module Jammit
|
|
40
38
|
def precache_all(output_dir=nil, base_url=nil)
|
41
39
|
output_dir ||= File.join(PUBLIC_ROOT, Jammit.package_path)
|
42
40
|
cacheable(:js, output_dir).each {|p| cache(p, 'js', pack_javascripts(p), output_dir) }
|
43
|
-
cacheable(:jst, output_dir).each {|p| cache(p, 'jst', pack_templates(p), output_dir) }
|
44
41
|
cacheable(:css, output_dir).each do |p|
|
45
42
|
cache(p, 'css', pack_stylesheets(p), output_dir)
|
46
43
|
if Jammit.embed_assets
|
@@ -87,10 +84,9 @@ module Jammit
|
|
87
84
|
|
88
85
|
# Return the compiled contents of a JST package.
|
89
86
|
def pack_templates(package)
|
90
|
-
@compressor.compile_jst(package_for(package, :
|
87
|
+
@compressor.compile_jst(package_for(package, :js)[:paths])
|
91
88
|
end
|
92
89
|
|
93
|
-
|
94
90
|
private
|
95
91
|
|
96
92
|
# Look up a package asset list by name, raising an exception if the
|
@@ -110,30 +106,48 @@ module Jammit
|
|
110
106
|
end
|
111
107
|
|
112
108
|
# Return a list of all of the packages that should be cached. If "force" is
|
113
|
-
# true, this is all of them -- otherwise only the packages
|
114
|
-
# 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.
|
115
111
|
def cacheable(extension, output_dir)
|
116
112
|
names = @packages[extension].keys
|
117
113
|
return names if @force
|
114
|
+
config_mtime = File.mtime(Jammit.config_path)
|
118
115
|
return names.select do |name|
|
119
|
-
pack
|
120
|
-
cached
|
121
|
-
|
122
|
-
|
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
|
123
127
|
end
|
124
128
|
end
|
125
129
|
|
126
|
-
# Compiles the list of assets that goes into each package. Runs an
|
127
|
-
# 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.
|
128
137
|
def create_packages(config)
|
129
138
|
packages = {}
|
130
139
|
return packages if !config
|
131
140
|
config.each do |name, globs|
|
132
141
|
globs ||= []
|
133
142
|
packages[name] = {}
|
134
|
-
paths = globs.map {|glob| glob_files(glob) }.flatten.uniq
|
143
|
+
paths = globs.flatten.uniq.map {|glob| glob_files(glob) }.flatten.uniq
|
135
144
|
packages[name][:paths] = paths
|
136
|
-
|
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)]
|
148
|
+
else
|
149
|
+
packages[name][:urls] = paths.map {|path| path.sub(PATH_TO_URL, '') }
|
150
|
+
end
|
137
151
|
end
|
138
152
|
packages
|
139
153
|
end
|
@@ -145,4 +159,4 @@ module Jammit
|
|
145
159
|
|
146
160
|
end
|
147
161
|
|
148
|
-
end
|
162
|
+
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,5 +1,6 @@
|
|
1
1
|
module Jammit
|
2
2
|
|
3
|
+
# Rails 2.x routing module. Rails 3.x routes are in rails/routes.rb.
|
3
4
|
module Routes
|
4
5
|
|
5
6
|
# Jammit uses a single route in order to slow down Rails' routing speed
|
@@ -7,8 +8,14 @@ module Jammit
|
|
7
8
|
# Jammit::Routes.draw(map)
|
8
9
|
# Passing in the routing "map" object.
|
9
10
|
def self.draw(map)
|
10
|
-
map.jammit "/#{Jammit.package_path}/:package.:extension",
|
11
|
-
|
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
|
+
}
|
12
19
|
end
|
13
20
|
|
14
21
|
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.
|
7
|
+
VERSION = "0.5.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
|
|
@@ -26,6 +26,10 @@ module Jammit
|
|
26
26
|
|
27
27
|
DEFAULT_COMPRESSOR = :yui
|
28
28
|
|
29
|
+
# Extension matchers for JavaScript and JST, which need to be disambiguated.
|
30
|
+
JS_EXTENSION = /\.js\Z/
|
31
|
+
DEFAULT_JST_EXTENSION = "jst"
|
32
|
+
|
29
33
|
# Jammit raises a @PackageNotFound@ exception when a non-existent package is
|
30
34
|
# requested by a browser -- rendering a 404.
|
31
35
|
class PackageNotFound < NameError; end
|
@@ -38,11 +42,15 @@ module Jammit
|
|
38
42
|
# cached packages is locked.
|
39
43
|
class OutputNotWritable < StandardError; end
|
40
44
|
|
45
|
+
# Jammit raises a DeprecationError if you try to use an outdated feature.
|
46
|
+
class DeprecationError < StandardError; end
|
47
|
+
|
41
48
|
class << self
|
42
49
|
attr_reader :configuration, :template_function, :template_namespace,
|
43
50
|
:embed_assets, :package_assets, :compress_assets, :gzip_assets,
|
44
|
-
:package_path, :mhtml_enabled, :include_jst_script,
|
45
|
-
: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
|
46
54
|
end
|
47
55
|
|
48
56
|
# The minimal required configuration.
|
@@ -55,19 +63,23 @@ module Jammit
|
|
55
63
|
raise ConfigurationNotFound, "could not find the \"#{config_path}\" configuration file" unless exists
|
56
64
|
conf = YAML.load(ERB.new(File.read(config_path)).result)
|
57
65
|
@config_path = config_path
|
58
|
-
@configuration = conf
|
66
|
+
@configuration = symbolize_keys(conf)
|
59
67
|
@package_path = conf[:package_path] || DEFAULT_PACKAGE_PATH
|
60
68
|
@embed_assets = conf[:embed_assets] || conf[:embed_images]
|
61
69
|
@compress_assets = !(conf[:compress_assets] == false)
|
62
70
|
@gzip_assets = !(conf[:gzip_assets] == false)
|
63
71
|
@mhtml_enabled = @embed_assets && @embed_assets != "datauri"
|
64
|
-
@compressor_options = (conf[:compressor_options] || {})
|
65
|
-
@css_compressor_options = (conf[:css_compressor_options] || {})
|
72
|
+
@compressor_options = symbolize_keys(conf[:compressor_options] || {})
|
73
|
+
@css_compressor_options = symbolize_keys(conf[:css_compressor_options] || {})
|
66
74
|
set_javascript_compressor(conf[:javascript_compressor])
|
67
75
|
set_package_assets(conf[:package_assets])
|
68
76
|
set_template_function(conf[:template_function])
|
69
77
|
set_template_namespace(conf[:template_namespace])
|
78
|
+
set_template_extension(conf[:template_extension])
|
79
|
+
symbolize_keys(conf[:stylesheets]) if conf[:stylesheets]
|
80
|
+
symbolize_keys(conf[:javascripts]) if conf[:javascripts]
|
70
81
|
check_java_version
|
82
|
+
check_for_deprecations
|
71
83
|
self
|
72
84
|
end
|
73
85
|
|
@@ -124,14 +136,22 @@ module Jammit
|
|
124
136
|
@template_namespace = value == true || value.nil? ? DEFAULT_JST_NAMESPACE : value.to_s
|
125
137
|
end
|
126
138
|
|
139
|
+
# Set the extension for JS templates.
|
140
|
+
def self.set_template_extension(value)
|
141
|
+
@template_extension = (value == true || value.nil? ? DEFAULT_JST_EXTENSION : value.to_s).gsub(/\A\.?(.*)\Z/, '\1')
|
142
|
+
@template_extension_matcher = /\.#{Regexp.escape(@template_extension)}\Z/
|
143
|
+
end
|
144
|
+
|
127
145
|
# The YUI Compressor requires Java > 1.4, and Closure requires Java > 1.6.
|
128
146
|
def self.check_java_version
|
147
|
+
return true if @checked_java_version
|
129
148
|
java = @compressor_options[:java] || 'java'
|
130
149
|
@css_compressor_options[:java] ||= java if @compressor_options[:java]
|
131
150
|
version = (`#{java} -version 2>&1`)[/\d+\.\d+/]
|
132
151
|
disable_compression if !version ||
|
133
152
|
(@javascript_compressor == :closure && version < '1.6') ||
|
134
153
|
(@javascript_compressor == :yui && version < '1.4')
|
154
|
+
@checked_java_version = true
|
135
155
|
end
|
136
156
|
|
137
157
|
# If we don't have a working Java VM, then disable asset compression and
|
@@ -141,6 +161,11 @@ module Jammit
|
|
141
161
|
warn("Asset compression disabled -- Java unavailable.")
|
142
162
|
end
|
143
163
|
|
164
|
+
# Jammit 0.5+ no longer supports separate template packages.
|
165
|
+
def self.check_for_deprecations
|
166
|
+
raise DeprecationError, "Jammit 0.5+ no longer supports separate packages for templates.\nPlease fold your templates into the appropriate 'javascripts' package instead." if @configuration[:templates]
|
167
|
+
end
|
168
|
+
|
144
169
|
def self.warn(message)
|
145
170
|
message = "Jammit Warning: #{message}"
|
146
171
|
@logger ||= (defined?(Rails) && Rails.logger ? Rails.logger :
|
@@ -148,6 +173,15 @@ module Jammit
|
|
148
173
|
@logger ? @logger.warn(message) : STDERR.puts(message)
|
149
174
|
end
|
150
175
|
|
176
|
+
# Clone of active_support's symbolize_keys, so that we don't have to depend
|
177
|
+
# on active_support in any fashion. Converts a hash's keys to all symbols.
|
178
|
+
def self.symbolize_keys(hash)
|
179
|
+
hash.keys.each do |key|
|
180
|
+
hash[(key.to_sym rescue key) || key] = hash.delete(key)
|
181
|
+
end
|
182
|
+
hash
|
183
|
+
end
|
184
|
+
|
151
185
|
end
|
152
186
|
|
153
187
|
require 'jammit/dependencies'
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jammit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 5
|
8
|
+
- 0
|
9
|
+
version: 0.5.0
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Jeremy Ashkenas
|
@@ -9,39 +14,37 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-02-
|
17
|
+
date: 2010-02-19 00:00:00 -05:00
|
13
18
|
default_executable:
|
14
19
|
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
16
|
-
name: rails
|
17
|
-
type: :runtime
|
18
|
-
version_requirement:
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 2.0.0
|
24
|
-
version:
|
25
20
|
- !ruby/object:Gem::Dependency
|
26
21
|
name: yui-compressor
|
27
|
-
|
28
|
-
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
30
24
|
requirements:
|
31
25
|
- - ">="
|
32
26
|
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 9
|
30
|
+
- 1
|
33
31
|
version: 0.9.1
|
34
|
-
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
35
34
|
- !ruby/object:Gem::Dependency
|
36
35
|
name: closure-compiler
|
37
|
-
|
38
|
-
|
39
|
-
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
38
|
requirements:
|
41
39
|
- - ">="
|
42
40
|
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 1
|
44
|
+
- 0
|
43
45
|
version: 0.1.0
|
44
|
-
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
45
48
|
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"
|
46
49
|
email: jeremy@documentcloud.org
|
47
50
|
executables:
|
@@ -58,6 +61,7 @@ files:
|
|
58
61
|
- lib/jammit/helper.rb
|
59
62
|
- lib/jammit/jst.js
|
60
63
|
- lib/jammit/packager.rb
|
64
|
+
- lib/jammit/railtie.rb
|
61
65
|
- lib/jammit/routes.rb
|
62
66
|
- lib/jammit.rb
|
63
67
|
- bin/jammit
|
@@ -83,18 +87,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
83
87
|
requirements:
|
84
88
|
- - ">="
|
85
89
|
- !ruby/object:Gem::Version
|
90
|
+
segments:
|
91
|
+
- 0
|
86
92
|
version: "0"
|
87
|
-
version:
|
88
93
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
94
|
requirements:
|
90
95
|
- - ">="
|
91
96
|
- !ruby/object:Gem::Version
|
97
|
+
segments:
|
98
|
+
- 0
|
92
99
|
version: "0"
|
93
|
-
version:
|
94
100
|
requirements: []
|
95
101
|
|
96
102
|
rubyforge_project: jammit
|
97
|
-
rubygems_version: 1.3.
|
103
|
+
rubygems_version: 1.3.6
|
98
104
|
signing_key:
|
99
105
|
specification_version: 3
|
100
106
|
summary: Industrial Strength Asset Packaging for Rails
|